10

これは変です。複雑な型のネストされたオブジェクトでASP.NET MVCにBindAttributeIncludeExculudeのプロパティを使用することはできません。ここで複雑なタイプのネストされたオブジェクトを含むbind属性のincludeおよびexcludeプロパティ

は私がやったことです:

これは私のモデルである:

public class FooViewModel { 

    public Enquiry Enquiry { get; set; } 
} 

public class Enquiry { 

    public int EnquiryId { get; set; } 
    public string Latitude { get; set; } 
} 

HTTPポストアクション:

[ActionName("Foo"), HttpPost] 
public ActionResult Foo_post(
    [Bind(Include = "Enquiry.EnquiryId")] 
    FooViewModel foo) { 

    return View(foo); 
} 

ビュー:

@using (Html.BeginForm()) { 

    @Html.TextBoxFor(m => m.Enquiry.EnquiryId) 
    @Html.TextBoxFor(m => m.Enquiry.Latitude) 

    <input type="submit" value="push" /> 
} 

はでは動作しませんすべて。

How do I use the [Bind(Include="")] attribute on complex nested objects?

+1

私はあなたが参照した他の投稿に記載されているようにすることをお勧めします。 – JoJa

+0

ええ、それはそのように思えます。■ドメインモデルプロジェクトの中ではできません。私はmvcプロジェクトの中で部分的なクラスを定義し、それを考えるべきです。 – tugberk

+0

私の解決策をここに試してくださいhttps://stackoverflow.com/questions/47644699/how-to-bind-nested-objects-on-httppost-in-asp-net-mvc/47645228#47645228 –

答えて

15

はい、あなたはそれがそのように動作させることができます:ここに記載されているように私はEnquiryクラスのBindAttributeを定義する場合、私はこれだけの作品を作ることができます

[Bind(Include = "EnquiryId")] 
public class Enquiry 
{ 
    public int EnquiryId { get; set; } 
    public string Latitude { get; set; } 
} 

とあなたの行動:

[ActionName("Foo"), HttpPost] 
public ActionResult Foo_post(FooViewModel foo) 
{ 
    return View(foo); 
} 

これは、バインディングでのみEnquiryIdを含めるとLatitude NULを残しますl。

これは、Bind属性を使用することは私がお勧めするものではないと言われています。私の推奨は、ビューモデルを使用することです。これらのビューモデルの中には、この特定のビューに合ったプロパティだけが含まれています。

だから、単にあなたのビューモデルをreadapt:

public class FooViewModel 
{ 
    public EnquiryViewModel Enquiry { get; set; } 
} 

public class EnquiryViewModel 
{ 
    public int EnquiryId { get; set; } 
} 

そこに行きます。もはやバインディングについて心配する必要はありません。

+0

@darinに感謝します。これは唯一の方法と思われます。私はこれを掘り下げたわけではありませんが、新しいカスタムモデルバインダーを作成してこの作業を行うために 'DefaultModelBinder'クラスを微調整できますか? – tugberk

+2

@tugberk、私は本当にその道を行くことはありません。このような問題を解決するには、ビューモデルを使用する方法があります。そして、その種の問題だけではありません。 ASP.NET MVCアプリケーションでは常にビューモデルを使用する必要があります。 –

+0

2番目の推奨事項として、私は常にこれのために間に合っています:s – tugberk

1

IMHOこれを行うより良い方法があります。

ビューモデルに複数のモデルがある場合、ポストコントローラの署名には、ビューモデルではなく同じモデルが含まれます。

I.E.

public class FooViewModel { 
    public Bar BarV { get; set; } 
    public Enquiry EnquiryV { get; set; } 
    public int ThisNumber { get; set; } 
} 

public class Bar { 
    public int BarId { get; set; } 
} 

public class Enquiry { 
    public int EnquiryId { get; set; } 
    public string Latitude { get; set; } 
} 

コントローラのポストアクションは、このようになります。

[ActionName("Foo"), HttpPost] 
public ActionResult Foo_post(
    [Bind(Include = "EnquiryId")] 
    Enquiry EnquiryV, 
    [Bind(Include = "BarId"])] 
    Bar BarV, 
    int ThisNumber 
{ 
    return View(new FooViewModel { Bar = BarV, Enquiry = EnquiryV, ThisNumber = ThisNumber }); 
} 

すべてのビューはまだそれが含まれていないがために、このフォームはまだ戻って(あなたがそれを設定していた道を)緯度を掲載します、覚えておいてください。この

@using (Html.BeginForm()) { 

    @Html.TextBoxFor(m => m.EnquiryV.EnquiryId) 
    @Html.TextBoxFor(m => m.EnquiryV.Latitude) 
    @Html.TextBoxFor(m => m.BarV.BarId) 
    @Html.TextBoxFor(m => m.ThisNumber) 

    <input type="submit" value="push" /> 
} 

のように見えながら、ポストアクションに関する照会のためのバインド文字列を含む場合、そのアクションは結果の照会に新しい値を受け入れません。緯度を無効にするか、追加の投稿データを防ぐためにフォーム要素を作成しないことをお勧めします。

他のシナリオでは、バインドは問題ありませんが、何らかの理由で複雑なモデルのドット表記が嫌いです。

副次的な注意点として、私は、コード複製のような他の問題の原因となる可能性があるため、クラスに直接bind属性を設定しないで、別のバインディングが必要な特定のシナリオを考慮しません。

(私はあなたの質問がむしろ日付であることを知っていますが、自分自身で解決策を試してみる前に、他の人が同じ問題を解決するのに役立つことを願っています。)

関連する問題