JavaScriptSerializer [ScriptIgnore]对虚拟属性无效?

时间:2012-08-17 22:01:23

标签: c# asp.net-mvc 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<User> 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;
    }
}

我已经给出了属性,但它根本没有帮助......?

3 个答案:

答案 0 :(得分:9)

您应该将ApplyToOverrides的{​​{1}}参数设置为ScriptIgnore

true

答案 1 :(得分:4)

此处的问题是您的virtual参数会覆盖到动态创建的类中。在这种情况下,[ScriptIgnore]属性也会被覆盖。

这就是您应该使用[ScriptIgnore(ApplyToOverrides = true)]的原因,以便将[ScriptIgnore]属性保持为派生类的有效性。

答案 2 :(得分:0)

JavaScriptSerializerreturn Json时使用的内容)肯定尊重[ScriptIgnore]属性。

这是一个证据:

型号:

public class User
{
    public Badge Badge { get; set; }
}

public class Badge
{
    [ScriptIgnore]
    public virtual ICollection<User> 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库。