Problem with JsonProperty

2,617 views
Skip to first unread message

Ole Jørgensen

unread,
Mar 4, 2013, 11:59:44 AM3/4/13
to rest...@googlegroups.com
I have some problems deserializing a json "class" in red below (yes, unfortunately it is literally named "attribute"):
 
{
 
    "spatialReference": {
        "wkid": 1234
    },
    "geometryType": "Point",
    "features": [
        {
            "attribute": {
                "husnr": "1",
                "vej": {
                    "kode": "1111",
                    "navn": "road name here",
                    "href": "/?servicename=keys&method=vej&vejkode=1111"
                },
                "postdistrikt": {
                    "kode": "2222",
                    "navn": "city name here",
                    "href": "/?servicename=keys&method=postdistrikt&postnr=2222"
                },
                "kommune": {
                    "kode": "3333",
                    "navn": "municipality name here",
                    "href": "?servicename=keys&method=kommune&komkode=3333"
                }
            },
            "geometry": {
                "x": 715914.18,
                "y": 6180299.52
            }
        }
    ]
}
The json is valid and I can see that when I call the method from a browser I get valid json back. But when I try deserialize it, then all the values are there except the "attribute" value - the value is null (and not a "attribute" object).
 
This is my deserializer:
 
public class KeysDeserializer : IDeserializer {
    #region IDeserializer Members
    public T Deserialize<T>( IRestResponse response ) {
        var text = response.Content; if ( String.IsNullOrEmpty(text) ) text = {};
        var json = new Newtonsoft.Json.JsonSerializer( );
        json.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
        json.ObjectCreationHandling = Newtonsoft.Json.ObjectCreationHandling.Replace;
        json.MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore;
        json.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize;
        var sr = new StringReader( text );
        var reader = new JsonTextReader( sr );
        var result = json.Deserialize( reader, typeof( T ) );
        reader.Close( );
        return (T)result;
    }
    public string DateFormat { get; set; }
    public string Namespace { get; set; }
    public string RootElement { get; set; }
    #endregion
}
 
How do I make the deserializer accept that the JsonProperty literally is called "attribute"?
 
I can't call te json C# class Attribute, because then my code won't compile, ie. I can't do this:
 
    public class Feature  {
        [JsonProperty( "attribute" )]
        public Attribute Attribute { get; set; }
// <--- compile error: 'PostAddress.Feature' does not contain a definition for 'Attribute'
// and no extension method 'Attribute' accepting a first argument of type 'PostAddress.Feature'
// could be found (are you missing a using directive or an assembly reference?) 

        [JsonProperty( "geometry" )]
        public PointGeometry Geometry { get; set; }
    }
 
but i can do this:
 
    public class Feature  {
        [JsonProperty( "attribute" )]
        public Attribute Attributes { get; set; } // compiles fine
        [JsonProperty( "geometry" )]
        public PointGeometry Geometry { get; set; }
    }

    public class PostAdresse {
        [JsonProperty( "spatialReference" )]
        public SpatialReference SpatialReference { get; set; }
        [JsonProperty( "geometryType" )]
        public string GeometryType { get; set; }
        [JsonProperty( "features" )]
        public IList<Feature> Features { get; set; }
    }
    public class Attribute {
        [JsonProperty( "husnr" )]
        public string Husnr { get; set; }
        [JsonProperty( "vej" )]
        public Vej Vej { get; set; }
        [JsonProperty( "postdistrikt" )]
        public Postdistrikt Postdistrikt { get; set; }
        [JsonProperty( "kommune" )]
        public Kommune Kommune { get; set; }
    }
 
Has anyone seen this before, and how did they work around it?

Cristovão Morgado

unread,
Mar 4, 2013, 12:49:46 PM3/4/13
to RestSharp
I've seen that! I ussally use dataanotation to get by ...

 [DataContract]
    public class Propertie
    {
        [DataMember(Name = "Property")]
        public string Label{ get; set; }


--
You received this message because you are subscribed to the Google Groups "RestSharp" group.
To unsubscribe from this group and stop receiving emails from it, send an email to restsharp+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Cristovao Morgado
@TheSaintr

Cristovão Morgado

unread,
Mar 4, 2013, 12:50:02 PM3/4/13
to RestSharp
Ahh I use json.net
--
Cristovao Morgado
@TheSaintr

Ole Jørgensen

unread,
Mar 4, 2013, 2:32:20 PM3/4/13
to rest...@googlegroups.com
Hi Cristovão
 
but I do use json.net : ) I can't remember why I don't use DataContract and DataMember attributes. Maybe I should try to use them again.
 
This might be a bug somewhere.. now I have removed all Nuget packages and merged the current json.net and Restsharp windows phone projects into my solution, and now I get this error instead:
 
Error 1 Delegate 'System.Action<RestSharp.IRestResponse<PostAdresse>,RestSharp.RestRequestAsyncHandle>' does not take 1 arguments C:\Dev\keys\keysPhoneApp\PostAdressePage.xaml.cs 245 78 keysPhoneApp
This I where the error is:
 
private void DownloadPostAddress() {
    var client = CreateClient( PostAdresse.Namespace  );
    var template = String.Format( "?servicename=keys&method=padresse&road={0}&houseno={1}&postno={2}", "First Ave*", "", "123" );
    var request = CreateRequest( template );
    var asyncHandle = client.ExecuteAsync<PostAdresse>( request, response => {
// <-- error
        _nearestAdresse = response.Data;
        DisplayAddresses( ); // show the _nearestAdresse on the map
    } );

}

internal static RestClient CreateClient( string ns ) {  
// the server sends text/plain and not application/json so
// detach any text/plain deserializers and attach KeysDeserializer to it
    var client = new RestClient( Constants.ApiBaseUrl ); 
    client.RemoveHandler( "text/plain;charset=utf-8" );
    var aad = new KeysDeserializer { Namespace = ns };
    client.AddHandler( "text/plain;charset=utf-8", aad );
    return client;
}

internal static RestRequest CreateRequest( string template ) {
    var request = new RestRequest( template, Method.GET );
    request.RequestFormat = DataFormat.Json;
// make sure KeysDeserializer is used
    request.OnBeforeDeserialization = resp => { resp.ContentType = "application/json"; };
    request.OnBeforeDeserialization = resp => { resp.ContentEncoding = "utf-8"; };
    return request;
}

Does anyone know how I can get around this?
 

 
2013/3/4 Cristovão Morgado <cristova...@gmail.com>

Cristovão Morgado

unread,
Mar 5, 2013, 4:43:32 AM3/5/13
to RestSharp
this is how I usually use RESTSHARP

   public void GetCompanies(Action<Models.Output.Companies> sucess, Action<string> failure)
        {
            if (hasNetworkConnection)
            {
                string Url = Constants.URLs.LIST_COMPANIES;

                var client = new RestClient(Url);
                var rq = new RestRequest("", Method.GET);
                rq.RequestFormat = DataFormat.Json;

                rq.Parameters.Add(new Parameter { Name = "api_key", Value = Constants.AppKeys.APP_KEY, Type = ParameterType.GetOrPost });
                rq.Parameters.Add(new Parameter { Name = "limit", Value = 3000, Type = ParameterType.GetOrPost });
                try
                {



                    var asyncHandle = client.ExecuteAsync(rq, (response, async) =>
                    {
                        Debug.WriteLine(response.Content);
                        if (response.StatusCode == HttpStatusCode.OK)
                        {
                            var r = JsonConvert.DeserializeObject<Models.Output.Companies>(response.Content);
                            sucess(r);

                        }
                        else
                        {

                            failure(response.ErrorMessage);

                        }
                    });
                }
                catch (Exception)
                {

                    failure("ocorreu um erro, tente mais tarde");

                    throw;
                }
            }
            else
            {
                failure("O seu telefone está sem internet");
            }
        }

Ole Jørgensen

unread,
Mar 9, 2013, 4:12:49 PM3/9/13
to rest...@googlegroups.com
Thank you, I will keep that technique in mind! 

In this case it turned out to be caused by the order (or lack) of my using statements:
It was:

using System.Collections.Generic;
using Newtonsoft.Json;
using System.Diagnostics;
using System;

when i changed it to

using System.Collections.Generic;
using Newtonsoft.Json;
using System;
using RestSharp;
using System.Diagnostics;

then the error 1 below and code works fine

so if you see 

Error Delegate 'System.Action<RestSharp.IRestResponse<T>,RestSharp.RestRequestAsyncHandle>' does not take 1 arguments 
then check your imports!

Cristovão Morgado

unread,
Mar 10, 2013, 5:01:59 AM3/10/13
to RestSharp
that was an example using WindowsPhone RESTSHARP
Reply all
Reply to author
Forward
Message has been deleted
0 new messages