8

I am consuming a REST API service. In the service response JSON, there are attribute names that include spaces and reserved words. I'm trying to map it to a C# class, but I can't assign attribute names that are the same as the field names.

Currently, the mapping only succeeds when the JSON attribute and C# class name of a field matches exactly, otherwise the value comes in as null.

Below is the JSON returned from the service:

{
   "value": [   {
      "accountNo": "JKBXXXXXXXXXVNX1",
      "mainSalesPerson": "XXXXX",
      "accountName": "XXXXXX",
      "ledgerBalance": "-2,298.70",
      "T+3": "0.00",
      "T+4": "0.00",
      "T+5 and Above": "2,298.70",
      "riskRatedPortfolioValue": "109,057.50",
      "exposure": "106,758.80",
      "costToFirm": "",
      "incomeToFirm": "14.59",
      "costToIncome(%)": "",
      "exposure(%)": "2.11",
      "O/S Balance": "-2,298.70"
   }],
   "success": true
}

I have used the following mapping class:

public class CountObject
{
    public string value { get; set; }
    public string success { get; set; }
}

public class RiskManagementQueryValueObject
{
    public string accountNo { get; set; }
    public string mainSalesPerson { get; set; }
    public string accountName { get; set; }
    public string ledgerBalance { get; set; }

    [SerializeAs(Name = "T+3")]
    public string T3 { get; set; }

    [SerializeAs(Name = "T+4")]
    public string T4 { get; set; }

    [SerializeAs(Name = "T+5 and Above")]
    public string T5_and_Above { get; set; }
    public string riskRatedPortfolioValue { get; set; }
    public string exposure { get; set; }
    public string costToFirm { get; set; }
    public string incomeToFirm { get; set; }

    [SerializeAs(Name = "costToIncome(%)")]
    public string costToIncome { get; set; }

    [SerializeAs(Name = "exposure(%)")]
    public string exposure_per { get; set; }

    [SerializeAs(Name = "O/S Balance")]
    public string OS_Balance { get; set; }
}

public class RiskManagementQueryHeadertObject
{
    public List<RiskManagementQueryValueObject> value { get; set; }
    public bool success { get; set; }
}

And this how I talk to the service:

public List<RiskManagementQueryValueObject> getOverdues()
{
    List<RiskManagementQueryValueObject> overdues = new List<RiskManagementQueryValueObject>();
    var count = 0.0;

    try
    {
        var restProxy = new RESTProxy();
        var request = restProxy.initRestRequest("/cam/riskmanagement/1/query/count", Method.POST, new { requestCriteriaMap = new { currency = "LKR" } });
        CountObject data = restProxy.Execute<CountObject>(request);

        if (data.success.ToString().ToLower() != "true")
            return null;

        //get the page count
        var pageCount = Math.Truncate(count / 300) + 1;

        for (int j = 0; j < pageCount; j++)
        {
            var request2 = restProxy.initRestRequest(string.Format("/cam/riskmanagement/1/query/{0}", (j + 1).ToString()), Method.POST, new { requestCriteriaMap = new { currency = "LKR" } });
            RiskManagementQueryHeadertObject data2 = restProxy.Execute<RiskManagementQueryHeadertObject>(request2);

            overdues.AddRange(data2.value);
        }
    }
    catch (Exception)
    {
        overdues = null;
    }

    return overdues;
}
public class RESTProxy
{
    string DEFAULT_HOST = "http://xxx.xxx.xxx.xxx:xxx/";
    string DEFAULT_MODULE = "xxx-rest";
    string DEFAULT_USER = "xxx:xxx:xxx";
    string DEFAULT_PASS = "xxx";

    public T Execute<T>(RestRequest request) where T : new()
    {
        var client = new RestClient(string.Concat(DEFAULT_HOST, DEFAULT_MODULE))
        {
            Authenticator = new DigestAuthenticator(DEFAULT_USER, DEFAULT_PASS, DEFAULT_HOST)
        };

        var response = client.Execute<T>(request);

        if (response.ErrorException != null)
        {
            throw response.ErrorException;
        }
        return response.Data;
    }

    public RestRequest initRestRequest(string pRestResourceName, Method pRestServiceVerb, object pRestRequestBody)
    {
        var request = new RestRequest(pRestResourceName, pRestServiceVerb);
        request.RequestFormat = DataFormat.Json;


        if (pRestRequestBody != null)
        {
            request.AddBody(pRestRequestBody);
        }

        return request;
    }
}

How can I resolve this and serialize all the fields into my class definition?

2 Answers 2

10

Using the JsonProperty attribute worked for me:

Example:

This C# class:

public class Product
{
    [JsonProperty(PropertyName = "Name/ + 1")]
    public string Name { get; set; }
}

maps to the following javascript object:

var input = {"Name/ + 1": "PostName"};
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your response. But at this point RiskManagementQueryHeadertObject data2 = restProxy.Execute<RiskManagementQueryHeadertObject>(request2); it does not map to the correct property/attribute name. I am still getting the value as null
This property worked wonderfully! Just a reminder, you need to use the Newtonsoft.Json namespace in any reference to JsonProperty for this to work.
2

I solved the issue. I added [DeserializeAs(Name ="")] instead of [SerializeAs(Name ="")]. I just did this in my C# Map class:

public class RiskManagementQueryValueObject
    {
        public string accountNo { get; set; }
        public string mainSalesPerson { get; set; }
        public string accountName { get; set; }
        public string ledgerBalance { get; set; }

        [DeserializeAs(Name = "T+3")]
        public string T3 { get; set; }

        [DeserializeAs(Name = "T+4")]
        public string T4 { get; set; }

        [DeserializeAs(Name = "T+5 and Above")]
        public string T5_and_Above { get; set; }
        public string riskRatedPortfolioValue { get; set; }
        public string exposure { get; set; }
        public string costToFirm { get; set; }
        public string incomeToFirm { get; set; }

        [DeserializeAs(Name = "costToIncome(%)")]
        public string costToIncome { get; set; }

        [DeserializeAs(Name = "exposure(%)")]
        public string exposure_per { get; set; }

        [DeserializeAs(Name = "O/S Balance")]
        public string OS_Balance { get; set; }
    }

2 Comments

What namespace is DeserializeAs in? I cant find it?
@jeffkenn it is RestSharp.Deserializers namespace

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.