Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Tommy Enger 71 posts 276 karma points c-trib
    Mar 27, 2015 @ 12:26
    Tommy Enger
    0

    Exclude type parameter from JSON output by UmbracoApiController

    This is more of a WEB.API question than Umbraco, but here goes: I have created a simple UmbracoApiController like this:

    public class LicenseController : UmbracoApiController
    {
        public IList<WaterwayLicense> GetAll()
        {
            var service = new LicenseService();
            var result = service.GetWaterwayLicenses();
            return result;
        }
    }
    

    The output of this becomes like this:

    {
      "$type": "System.Collections.Generic.List`1[[Umbraco.MyNamespace.DAL.Licenses.WaterwayLicense, Umbraco.MyNamespace.DAL]], mscorlib",
      "$values": [
        {
          "$type": "Umbraco.MyNamespace.DAL.Licenses.WaterwayLicense, Umbraco.MyNamespace.DAL",
          "ID": 1,
          "Tittel": "Title 1"
        },
        {
          "$type": "Umbraco.MyNamespace.DAL.Licenses.WaterwayLicense, Umbraco.MyNamespace.DAL",
          "ID": 2,
          "Tittel": "Title 2"
        }    
      ]
    }
    

    But I really don't need the $type parameters and would like to have it like this:

    {
      "$values": [
        {
          "ID": 1,
          "Tittel": "Title 1"
        },
        {
          "ID": 2,
          "Tittel": "Title 2"
        }         
      ]
    }
    

    How can this be achieved?

  • Stephen Roberts 47 posts 516 karma points c-trib
    Mar 27, 2015 @ 12:37
    Stephen Roberts
    0

    If your WaterwayLicense class is outside of your control, then you would have to do it with a custom view model like this

     public List<WaterwayLicenseViewModel> GetAll()
            {
                var service = new LicenseService();
                var result = service.GetWaterwayLicenses();
    
                return result.Select(licence=> new WaterwayLicenseViewModel(){ID = licence.ID, Tittel = licence.Tittel}).ToList();
            }
    
            public class WaterwayLicenseViewModel
            {
                public int ID { get; set; }
                public string Tittel { get; set; }
            }
    
  • Tommy Enger 71 posts 276 karma points c-trib
    Mar 27, 2015 @ 13:16
    Tommy Enger
    0

    Thanks for the reply Stephen. I also managed to solve it by rewriting the method like this:

    public HttpResponseMessage GetAll()
    {
        var service = new LicenseService();
        var result = service.GetWaterwayLicenses();
    
        var jsonResult = JsonConvert.SerializeObject(result);
        var response = this.Request.CreateResponse(HttpStatusCode.OK);
        response.Content = new StringContent(jsonResult, Encoding.UTF8, "application/json");
        return response;
    }
    

    What method would you prefer when it comes to performance? The JSON serialization has to happen some place, so could I just do it in the code? The list will contain up to 10 000 records so I think first getting the items from the LicenseService then copy it to a new list will add more overhead.

    One drawback I see is that it will ruin the option to retrieve the data as XML, but in this case performance has a higher priority.

  • Stephen Roberts 47 posts 516 karma points c-trib
    Mar 27, 2015 @ 13:25
    Stephen Roberts
    1

    That would work too, JsonConvert is Newtonsoft's json.net which is usually regarded as the fastest.

    if you wanted to support Xml you could do something like this

    public HttpResponseMessage GetAll()
            {
                var service = new LicenseService();
                var result = service.GetWaterwayLicenses();
                var response = this.Request.CreateResponse(HttpStatusCode.OK);
    
                if (Request.AcceptTypes.Contains("application/json"))
                {
                    var jsonResult = JsonConvert.SerializeObject(result);
                    response.Content = new StringContent(jsonResult, Encoding.UTF8, "application/json");
                }
                else if (Request.AcceptTypes.Contains("application/xml"))
                {
                    XmlSerializer xmlSerializer = new XmlSerializer(result.GetType());
                    using (StringWriter textWriter = new StringWriter())
                    {
                        xmlSerializer.Serialize(textWriter, result);
                        response.Content = new StringContent(textWriter.ToString(), Encoding.UTF8, "application/xml");
                    }
                }
                else
                {
                    throw new Exception("Accepted content type not supported.");
                }
                return response;
            }
    

    Although you may want to save the XmlSerializer in a static variable so you don't have to instantiate it every time.

Please Sign in or register to post replies

Write your reply to:

Draft