我有一个使用JsonResult序列化的自定义viewmodel。 ViewModel具有一些必须公开的属性,但同时这些属性在生成的Json输出中不可见。
我已经尝试过使用[NonSerialized]属性,但这似乎没有任何效果。
有没有简单的方法可以做到这一点?或者我是否必须编写自己的结果类型(在这种情况下我可能不会打扰)?
答案 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
结束财产
结束课