在ASP.NET MVC应用程序中过滤json输出的域对象的最佳方法

时间:2008-12-16 22:14:09

标签: asp.net-mvc json

如果我在asp.net mvc中渲染常规视图,那么我在页面中显示的唯一域对象属性是我专门写出来的。例如:

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

但是,如果我为json序列化一个域对象,它将包含每个属性。例如:

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

    return Json (customer);
}

由于我不希望每个Customer属性都暴露出在这种情况下过滤json输出属性的最佳方法是什么?你可以使用像UpdateModel()这样的包含/排除列表吗?使用代理类,如公共类JsonCustomer?你会推荐什么?

6 个答案:

答案 0 :(得分:19)

我使用匿名类型:

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

这不仅仅是一个好主意。相反,如果对象图包含循环引用,它可以防止在调用Json()时遇到的异常。

答案 1 :(得分:6)

您可以使用[ScriptIgnore]属性(在System.Web.Extensions中)。有关示例,请参阅http://www.creave.dk/post/2009/10/07/Excluding-properties-from-being-serialized-in-ASPNET-MVC-JsonResult.aspx

答案 2 :(得分:4)

请使用视图模型。视图模型是UI用于在屏幕上表示域对象的对象。每个屏幕都有自己的视图模型。

当您制作视图模型(DTO)时,它是域对象的展平,零安全投影,不要映射您不希望在屏幕上显示的属性。

序列化视图模型,而不是域对象。

答案 3 :(得分:1)

您可以使用Newtonsoft库和[JsonIgnore]属性来标记您不希望公开的类的属性。还有其他库(可能有不同的属性忽略属性名称),我个人更喜欢这个,因为它在JSON转换器扩展等方面非常灵活+它可以轻松地序列化匿名对象。

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; } }
}

答案 4 :(得分:0)

我遇到了同样的问题,解决方案之一就是

使用[ScriptIgnore]属性..它将解决问题。

添加system.web.extensions引用并添加命名空间:

使用System.Web.Script.Serialization。

如果您还有疑问......请阅读...以获得详细解释..

我有一个带有..的用户类

使用System;

使用System.Collections.Generic;

使用System.Linq;

使用System.Web;

使用Iesi.Collections.Generic;

使用System.Runtime.Serialization;

名称空间RAPortal.Core.Entities

{

公共类用户

{

   private int _userId;

   private string _firstName;

   private string _lastName;

私人IList _applications;

   private IList<Group> _groups;

   private IList<ApplicationRequest> _applicationRequests;

...属性..

   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;

       }

   }

公共虚拟IList群组

   {

       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;

       }

   }

...等......

我有群组课程..

使用System;

使用System.Collections.Generic;

使用System.Linq;

使用System.Web;

使用System.Web.Script.Serialization;

使用System.Runtime.Serialization;

名称空间RAPortal.Core.Entities

{

公共类组

{

   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;

       }

   }

}

}

由于组中引用了用户,因此json认为它是循环引用,它将引发异常。所以修复是在用户之上添加[ScriptIgnore]。并将引用和命名空间添加到此类中..

它解决了我的问题..我相信有更好的方法!干杯...

请记住,您应该只在groups类中添加[scriptIgnore],而不是在Users类中添加..

答案 5 :(得分:0)

根据我的经验,JavaScriptSerializer也尊重一些XmlSerialization属性,例如XmlIgnore。