如何将某些公共属性排除在序列化为JsonResult之外?

时间:2009-09-15 17:38:20

标签: asp.net-mvc json serialization

我有一个使用JsonResult序列化的自定义viewmodel。 ViewModel具有一些必须公开的属性,但同时这些属性在生成的Json输出中不可见。

我已经尝试过使用[NonSerialized]属性,但这似乎没有任何效果。

有没有简单的方法可以做到这一点?或者我是否必须编写自己的结果类型(在这种情况下我可能不会打扰)?

6 个答案:

答案 0 :(得分:25)

您可以在不应序列化的成员上添加[ScriptIgnore]属性。有关示例,请参阅ScriptIgnoreAttribute Class in MSDN

答案 1 :(得分:2)

看看James Newton-King的JSON.NET。它会做你想要的。

答案 2 :(得分:2)

只需创建一个返回而不是类的接口。

public interface IMyViewModel {
   string MyPublicProperty { get; set; }
}

然后创建一个继承接口

的类
public class MyViewModel : IMyViewModel {
   public string MyPublicProperty { get; set; }
   public string MyNotSoPublicProperty { get; set; }
}

并在Controller Action

中返回接口,而不是类
public JsonResult MyJson(){
    IMyViewModel model = new MyViewModel();
    return Json(model);
}

结果JSON将是

{
    'MyPublicProperty': ''
}

客户端脚本编写的一个挑战是,如果您要更改类,则不知道是否要破坏客户端实现。如果您在JSON中使用接口类型,您就会明白,如果您更改了接口,那么您可能正在做一些可能会破坏客户端实现的事情。如果您正在更改不在接口中的内容(因此不会被序列化),它还可以避免您对客户端进行双重检查。

此外,很多时候,您的ViewModel可能包含大型集合或复杂类型,您不一定要输出到客户端。这些可能需要很长时间才能序列化或公开不属于客户端代码的信息。使用接口可以更加透明地了解输出中的内容。

此外,在属性上使用[ScriptIgnore]等属性仅适用于特定方案(JavaScript序列化),如果您以后序列化为XML,则会强制您面对完全相同的问题。这将不必要地使用大量属性丢弃您的视图模型。你真的想要多少人?使用intefaces适用于任何地方,并且不需要使用额外的属性来填充视图模型。

答案 3 :(得分:1)

JavaScriptConverter类扩展为不包含NonSerializedAttribute的属性。然后,您可以创建一个使用ActionResult序列化对象的自定义JavaScriptConverter

这将创建一个可靠且可测试的类,而无需(重新)生成包装类或使用匿名对象。

答案 4 :(得分:0)

不完全是您正在寻找的答案,但您可以使用以下代码和匿名类作弊Json()

MyModel model = ...;
return Json(new MyModel {model.Prop1, model.Prop2});

答案 5 :(得分:0)

您可以创建一个包装类,只在JsonResult中公开您想要的那些属性。在下面的例子中,Cow有2个属性 - “Leg”和“Moo”。假设您只想将“Leg”作为属性公开。然后

Dim cw as CowWrapper = New CowWrapper(c)

将返回仅暴露“Leg”的包装类。如果您只想显示属性的某些子集,这对于像DataGridView这样的东西也很有用。

Public Class Cow

Public ReadOnly Property Leg()as String

   get

      return "leg"

   end get

结束财产

Public ReadOnly Property Moo()as String

   get

      return "moo"

   end get

结束财产

结束课

Public Class CowWrapper

Private m_cow as Cow = Nothing

Public Sub New(ByVal cow as Cow)

   m_cow = cow

end Sub


    m_cow = cow

Public ReadOnly Property Leg()as String

   get

      return m_cow.Leg()

   end get

结束财产

结束课