JavaScriptSerializer 对虚拟属性无效?
我已经返回了一个Json(myObj)动作结果。 myObj是Badge类型
Badge具有的唯一两个可能导致序列化程序循环的对象是:
public class Badge { public Badge() { } public Badge(String Name, String Description) { this.Name = Name; this.Description = Description; } [ScriptIgnore] public virtual BadgeType BadgeType { get; set; } [ScriptIgnore] public virtual ICollection Users { get; set; } public int ID { get; set; } public string Name { get; set; } public string Description { get; set; } public string PrerequisiteCriteriaRef { get; set; } //PrerequisiteID public static Badge CreateForSeeder(BaseDBContext db, String Name, String Description, int TypeID) { Badge b = new Badge(); b.Name = Name; b.Description = Description; b.BadgeType = db.BadgeTypes.Where(x => x.TypeID == TypeID).FirstOrDefault(); return b; } }
我已经给出了这个属性,但它根本没有帮助……?
JavaScriptSerializer
( return Json
时使用的内容)肯定尊重[ScriptIgnore]
属性。
这是一个certificate:
模型:
public class User { public Badge Badge { get; set; } } public class Badge { [ScriptIgnore] public virtual ICollection Users { get; set; } public int ID { get; set; } public string Name { get; set; } }
控制器:
public class HomeController : Controller { public ActionResult Index() { var badge = new Badge { ID = 1, Name = "badge" }; var user = new User { Badge = badge }; badge.Users = new[] { user }.ToList(); return Json(badge, JsonRequestBehavior.AllowGet); } }
如果从Users属性中删除[ScriptIgnore]
属性,则会出现循环引用错误。
所以我想你的问题就在别的地方。
但我个人建议你使用视图模型而不是那些[ScriptIgnore]
属性。
因此,您只需定义一个视图模型,该模型仅包含给定视图所需的属性:
public class BadgeViewModel { public int ID { get; set; } public string Name { get; set; } }
然后在您的控制器操作中,您在域模型和视图模型之间进行映射,并将视图模型传递给视图:
public class HomeController : Controller { public ActionResult Index() { Badge badge = ... BasgeViewModel vm = new BasgeViewModel { Id = badge.Id, Name = badge.Name }; return Json(vm, JsonRequestBehavior.AllowGet); } }
如果您厌倦了在控制器中编写映射代码,只需转到NuGet包控制台并输入以下命令:
Install-Package AutoMapper
为了充分利用优秀的AutoMapper库。
您应该将ApplyToOverrides
参数设置为true
:
[ScriptIgnore(ApplyToOverrides = true)]
这里的问题是您的virtual
参数被覆盖到动态创建的类中。 在这种情况下, [ScriptIgnore]
属性也会被覆盖。
这就是为什么你应该使用[ScriptIgnore(ApplyToOverrides = true)]
,以便将[ScriptIgnore]
属性保持为派生类的有效性。