Tutorial :Best way to filter domain objects for json output in an ASP.NET MVC application



Question:

If I'm rendering a regular view in asp.net mvc the only domain object properties that show up in my page the ones I specifically write out. For example:

<div><%= Customer.FirstName %></div>  

However, if I serialize a domain object for json it will include every property. Example:

public JsonResult Customer (int? id)  {      Customer customer = _serviceLayer.GetCustomer (id.Value);        return Json (customer);  }  

Since I don't want every Customer property exposed what is the best way to filter the output properties for json in this case? Can you use an include/exclude list like UpdateModel()? Use a proxy class such as public class JsonCustomer? What would you recommend?


Solution:1

I use anonymous types for this:

var customer = from c in serviceLayer.GetCustomers()                 where c.Id == id.Value                 select new { FirstName = c.FirstName };  

This is not just a good idea. Rather, it's protection against the exception that you will get when calling Json() if your object graph contains a circular reference.


Solution:2

You may use the [ScriptIgnore] attribute (in System.Web.Extensions). See http://www.creave.dk/post/2009/10/07/Excluding-properties-from-being-serialized-in-ASPNET-MVC-JsonResult.aspx for an example.


Solution:3

Please use a view model. A view model is an object that the UI uses to represent your domain objects on the screen. Each screen has its own view model.

When you make your view model, which is a DTO, which is a flattened, null-safe projection of domain objects, do not map properties you do not wish to be displayed on the screen.

Serialize the view model, not your domain object.


Solution:4

You could use the Newtonsoft library and [JsonIgnore] attribute for marking properties of your class you don't want to expose. There are other libraries (with possible different property ignore attribute name), I personally prefer this one since it's very flexible in JSON converter extensions etc + it can easily serialize anonymous objects.

public class Customer  {      ...      [JsonIgnore]      public string UrlIn { get; set; }      public string FirstName { get; set; }      // following example of a converter, you could write your own as well      [JsonConverter(typeof(Newtonsoft.Json.Converters.JavaScriptDateTimeConverter))]      public DateTime Created { get { return _created; } }  }  


Solution:5

I ran into the same problem and THE ONE OF SOLUTION IS to

Use [ScriptIgnore] atribute .. it will solve the problem.

add system.web.extensions reference and add namespace:

Using System.Web.Script.Serialization.

If you still have questions..Read on..for some detailed explanation..

i have a User class with..

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using Iesi.Collections.Generic;

using System.Runtime.Serialization;

namespace RAPortal.Core.Entities

{

public class User

{

   private int _userId;       private string _firstName;       private string _lastName;  

private IList _applications;

   private IList<Group> _groups;       private IList<ApplicationRequest> _applicationRequests;  

....Properties..

   public virtual int UserId       {           get           {               return _userId;           }           set           {               _userId = value;           }       }       public virtual string Title       {           get           {               return _title;           }           set           {               _title = !String.IsNullOrEmpty(value) ? value.ToUpper().Trim() : null;           }       }  

public virtual IList Groups

   {           get           {               return _groups;           }           set           {               _groups = value;           }       }       public virtual IList<UserPrivilege> UserPrivileges       {           get           {               return _userPrivileges;           }           set           {               _userPrivileges = value;           }       }       public virtual IList<UserRole> UserRoles       {           get           {               return _userRoles;           }           set           {               _userRoles = value;           }       }  

...so on...

and I have Groups class..

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Script.Serialization;

using System.Runtime.Serialization;

namespace RAPortal.Core.Entities

{

public class Group

{

   private int _groupId;       private string _name;       private IList<User> _users;       public virtual int GroupId       {           get           {               return _groupId;           }           set           {               _groupId = value;           }       }       public virtual string Name       {           get           {               return _name;           }           set           {               _name = !String.IsNullOrEmpty(value) ? value.ToUpper().Trim() : null;           }       }       [ScriptIgnore]       public virtual IList<User> Users       {           get           {               return _users;           }           set           {               _users = value;           }       }  

}

}

Since User is referenced in the groups.. the json think that it is Circular reference and It will throw an exception..so the fix is to add [ScriptIgnore] on top of the User. And add the reference and namespace to this class like it..

It solved my problem .. I am sure there are better ways out there !!! Cheers...

And remember you should add [scriptIgnore] only in the groups class and not in the Users class..


Solution:6

In my experience, the JavaScriptSerializer respects some of the XmlSerialization attributes such as XmlIgnore too.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »