0

I am working with JSON API. As c# doesn't accept characters like - (minus) or . (point), I had to replace each character by _ (underscore). The replacement happens when the JSON response is received as a string so that every attribute name containing a - or a . will have it replaced by a _ , then every attribute name will be the same as the attributes names in the class it will be deserialized into.

To make it clearer, here are some examples:

I recieve the following JSON : { "id": 1, "result": [ { "data": [ { "adm-pass": ""}]} In the class I want to deserialize into I have this attribute : public String adm_pass {get; set;}

So I replace the minus with an underscore so that the NewtonSoft parser can deserialize it accordingly.

My problem is that I sometimes I get some negative integers in my JSON. So if I do the string replacement in: {"beta" : -1}, I get a parsing exception since the -1 (integer here) becomes _1 and cannot be deserialized properly and raises an exception.

Is there a way to replace the string smartly so I can avoid this error? For example if - is followed by an int it's not replaced. If this way does not exist, is there a solution for this kind of problems?

4 Answers4

4

Newtonsoft allows you to specify the exact name of the JSON property, which it will use to serialize/deserialize. So you should be able to do this

[JsonProperty("adm-pass")]
public String adm_pass { get; set; }

This way you are not restricted to name your properties exactly as the JSON property names. And in your case, you won't need to do a string replace.

Hope this helps.

Ferdin
  • 362
  • 3
  • 12
  • That is pretty cool. I wonder if Microsoft's DataContractJsonSerializer has something similar. I looked and it has a way to change the name with [DataMember(Name = "user_id")], but I couldn't find if a dot (.) or a dash (-) are supported in it. – Rhyous Mar 30 '16 at 15:22
  • 1
    @Rhyous Even with Microsoft's DataContractJsonSerializer, you could do something like [DataMember(Name = "user-id")] or [DataMember(Name = "user.id")]. These are supported – Ferdin Mar 30 '16 at 15:31
  • Thanks. That saves me from testing to find out. :-) – Rhyous Mar 30 '16 at 15:33
  • Just out of curiosity, if I don't put a `[JsonProperty("propertyName")]` for a property, I dont get an error if its name is not containing prohibited characters? – Yacine Ben Slimene Mar 30 '16 at 16:00
  • The JsonProperty attribute can be used selectively for the properties that you want to name differently from the JSON (like those having invalid characters). For those that don't have this attribute, the parser will use the c# property name directly – Ferdin Mar 30 '16 at 16:53
2

You'll have to check that you are replacing the key and not the value, maybe by using a regex like http://regexr.com/3d471

wlalele
  • 333
  • 5
  • 16
1

Regex could work as wlalele suggests.

But I would create a new object like this:

  1. Create a new object:

    var sharpObj = {};
    
  2. loop through the objects as properties as described here: Iterate through object properties

    for (var property in object) {
        if (object.hasOwnProperty(property)) {
            // do stuff
        }
    }
    
  3. In the // do stuff section, create a property on sharpObj with the desired string replacements and set the property to the same value.

    var cleanProperty = cleanPropertyName(property);
    sharpObj[cleanProperty] = orginalObject[property];
    

Note: I assume you can figure out the cleanPropertyName() method or similar.

  1. Stringify the object

    var string = JSON.stringify(sharpObj);
    
Community
  • 1
  • 1
Rhyous
  • 6,510
  • 2
  • 44
  • 50
  • Thanks, but first: this approach will make the server do a lot more processing, secondly: I already have a JSON string, I don't want to create another string then stringify it, Third: It will take more coding as my JSON has more properties and I don't want that. – Yacine Ben Slimene Mar 30 '16 at 15:26
0

You can substring to check whether the next character is an integer, this can adapt into your code easily as you already find a character, as such you could do

int a;

if(int.TryParse(adm_pass.Substring(adm_pass.IndexOf("-") + 1,1),out a))
{
    //Code if next character is an int
}
else
{
    adm_pass = adm_pass.Replace("-","_");
}

This kind of code can be looped until there are no remaining hyphens/minuses

Alfie Goodacre
  • 2,753
  • 1
  • 13
  • 26