Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Odata Controller: How to convert Odata response to C# object at client

Tags:

c#

json.net

odata

We have got a Odata response as below:

"{\r\n  \"@odata.context\":\"http://localhost/ApplicationService/model/$metadata#Edm.String\",\"value\":\"{\\\"Messages\\\":[\\\"message 1\\\",\\\"message 2\\\",\\\"message 3\\\",\\\"message 4\\\"],\\\"IsValidEntity\\\":false}\"\r\n}"

Now say we have a class:

    public class myValidationResult
    {
        public myValidationResult()
        {
            Messages = new List<string>();
        }
        public List<string> Messages { get; set; }
        public bool IsValidEntity { get; set; }
    }

This class used in MyOdataController class as below:

public class MyODataController : ODataController 
{
        [Authorize(Roles = "Admin")]
        public async Task<IHttpActionResult> Post(T entity)
        {
                myValidationResult  vResult = new myValidationResult();
                vResult.Messages.Add("message 1");
                vResult.Messages.Add("message 2");
                vResult.Messages.Add("message 3");
                vResult.Messages.Add("message 4");
                vResult.IsValidEntity = false;

                 var strResult = JsonConvert.SerializeObject(vResult);
                var resp = Content(HttpStatusCode.BadRequest, strResult );

                return resp;
        }
}

For the client Consuming this, we created below Class:

public class OData<T> 
{
    [JsonProperty("odata.context")]
    public string Metadata { get; set; }
    public T value { get; set; }
}

In the method where we call the Odata method & store response in 'msg':

var resp = msg.Result.Content.ReadAsStringAsync().Result;

resp is:

"{\r\n  \"@odata.context\":\"http://localhost/ApplicationService/model/$metadata#Edm.String\",\"value\":\"{\\\"Messages\\\":[\\\"message 1\\\",\\\"message 2\\\",\\\"message 3\\\",\\\"message 4\\\"],\\\"IsValidEntity\\\":false}\"\r\n}"


var odatares = JsonConvert.DeserializeObject<OData<myValidationResult>>(resp);

But the above line giving error:

Can not convert value\":\"{\\\"Messages\\\":[\\\"message 1\\\",\\\"message 2\\\",\\\"message 3\\\",\\\"message 4\\\"],\\\"IsValidEntity\\\":false}  to <.....namespace......>myValidationResult

Please suggest accordingly.

like image 896
Bharat Mishra Avatar asked Jan 05 '16 14:01

Bharat Mishra


1 Answers

The OData response contains a string, not an instance of myValidationResult. Also, the response looks like it's missing some backslashes. (Are you sure the response shown is exactly what you received from the service?)

You can either fix the serialization of myValidationResult on the service:

// Don't serialize vResult yourself. OData will do it for you.
var resp = Content(HttpStatusCode.BadRequest, vResult );

Or deserialize in two steps as follows.

var data = "{\r\n \"@odata.context\":\"http://localhost/ApplicationService/model/$metadata#Edm.String\",\"value\":\"{\\\"Messages\\\":[\\\"message 1\\\",\\\"message 2\\\",\\\"message 3\\\",\\\"message 4\\\"],\\\"IsValidEntity\\\":false}\"\r\n}";
var outer = Newtonsoft.Json.JsonConvert.DeserializeObject<OData<string>>(data);
var inner = Newtonsoft.Json.JsonConvert.DeserializeObject<myValidationResult>(outer.value);

One more thing: The JsonProperty on OData<T> should be named @odata.context.

like image 181
lencharest Avatar answered Oct 26 '22 15:10

lencharest