代码之家  ›  专栏  ›  技术社区  ›  Todd Smith Brandon

为ASP.NET MVC应用程序中的JSON输出筛选域对象的最佳方法

  •  8
  • Todd Smith Brandon  · 技术社区  · 16 年前

    如果我在ASP.NET MVC中呈现一个常规视图,那么在我的页面中出现的惟一域对象属性就是我专门写出的那些属性。例如:

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

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

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

    既然我不希望每个客户属性都公开,那么在这种情况下,筛选JSON的输出属性的最佳方法是什么?可以使用像updateModel()这样的包含/排除列表吗?使用代理类,如公共类JSonCustomer?你会推荐什么?

    6 回复  |  直到 15 年前
        1
  •  19
  •   Craig Stuntz    16 年前

    我对此使用匿名类型:

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

    这不仅仅是个好主意。相反,如果对象图包含循环引用,那么它可以防止在调用json()时出现异常。

        2
  •  6
  •   JacobE    15 年前

    您可以使用[scriptIgnore]属性(在system.web.extensions中)。见 http://www.creave.dk/post/2009/10/07/Excluding-properties-from-being-serialized-in-ASPNET-MVC-JsonResult.aspx 举个例子。

        3
  •  4
  •   Matt Hinze    16 年前

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

    当您创建视图模型(DTO)时,它是域对象的扁平、空的安全投影,不映射您不希望在屏幕上显示的属性。

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

        4
  •  1
  •   aprilchild    16 年前

    你可以用 Newtonsoft 库和[jsonignore]属性,用于标记您不想公开的类的属性。还有其他库(可能具有不同的属性ignore attribute name),我个人更喜欢这个库,因为它在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; } }
    }
    
        5
  •  0
  •   bluwater2001    15 年前

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

    使用[scriptIgnore]属性..它将解决这个问题。

    添加System.Web.Extensions引用并添加命名空间:

    使用system.web.script.serialization。

    如果您还有问题,请继续阅读,以获得详细的解释。

    我有一个用户类……

    使用系统;

    使用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应用程序;

       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.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类中添加。

        6
  •  0
  •   Jeremy Bell    15 年前

    在我的经验中,javascriptserializer也尊重一些XML序列化属性,如xmlignore。