2

Json(myObj)アクションの結果を返しました。myObjはバッジタイプです

シリアライザーからのループを引き起こす可能性のあるバッジの2つのオブジェクトは次のとおりです。

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;
    }
}

私が属性を与えたが、それはまったく役に立たない...?

4

3 に答える 3

12

ApplyToOverrides次のパラメータをScriptIgnore設定する必要がありますtrue

[ScriptIgnore(ApplyToOverrides = true)]
于 2015-02-23T15:06:44.980 に答える
4

ここでの問題は、virtualパラメーターが動的に作成されたクラスにオーバーライドされることです。この場合、[ScriptIgnore]属性もオーバーライドされます。

そのため、派生クラス[ScriptIgnore(ApplyToOverrides = true)]で属性を有効に保つために、を使用する必要があります。[ScriptIgnore]

于 2017-05-02T19:13:43.023 に答える
1

JavaScriptSerializerこれはあなたが使用するときに使用されるものですreturn 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ライブラリを最大限に活用するために。

于 2012-08-18T07:25:44.333 に答える