5

注: MVC3+Razor、EF4、CF-CTP5を使用しています

  1. クライアント上で組織ごとに複数の Address クラスを動的に追加し、投稿時にモデルに強くバインドする機能をビューに許可するにはどうすればよいでしょうか?

  2. (ModelState.IsValid == false) の場合、3 つのアドレスを入力して無効なモデルを投稿すると、番号のアドレスとそれらの適切な値が再入力されるように、ビューでモデルの値を解析するにはどうすればよいでしょうか?

ここに私のモデルがあります:

public class Organization
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Address> Addresses { get; set; }
    public virtual ICollection<PhoneNumber> PhoneNumbers { get; set; }
    ...
}

public class Address
{
    public int Id { get; set; }
    public string Line1 { get; set; }
    public string Line2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string PostalCode { get; set; }
    public string Country { get; set; }
    public int Type { get; set; }
}

組織 (/Organization/Create) の作成アクションで次のように作成を処理する方法を理解しようとしています (住所と電話番号が送信されたモデルの一部になるように)。

[HttpPost]
public ActionResult Create(Organization organization)
{
    if (ModelState.IsValid)
    {
        _db.Organizations.Add(organization);
        _db.SaveChanges();
        return RedirectToAction("Details", organization.Id);
    }

    return View(organization);

}
4

3 に答える 3

1

あなたの質問は非常に広大です:)これはあなたの要件を達成できる方法の1つにすぎず、私のものよりも優れていると確信しています。

2 番目の質問から始めます。

(ModelState.IsValid == false) の場合、3 つのアドレスを入力して無効なモデルを投稿すると、番号のアドレスとそれらの適切な値が再入力されるように、ビューでモデルの値を解析するにはどうすればよいでしょうか?

私があなたの要求を正しく理解していれば、それは非常に簡単に見えます。答えは、アクションで行っているのとまったく同じように、Model クラスのコンテンツをレンダリングし、無効なモデルをクライアントに返すようにビューをコーディングするだけです。Create

フォーム (およびそのフィールド) がValidationSummary/ValidationMessagehtml ヘルパーで装飾されている場合、検証メッセージも表示されます。

  1. クライアント上で組織ごとに複数の Address クラスを動的に追加し、投稿時にモデルに強くバインドする機能をビューに許可するにはどうすればよいでしょうか?

組織の属性を表示するメイン ビューを作成してから、関連するアドレスを表示する別のビューを作成できます。ここに、新しいアドレス オブジェクトを追加するためのダイアログを開くハイパーリンクまたはボタンを配置し、完了したらアドレス リストを更新できます。同様に、編集ボタンと削除ボタンをアイコンとしてリストに表示できます。

アドレス リストは、クライアント側で完全に処理されるマークアップの一部であり、サーバー側のモデル クラスに正しくバインドするには、入力属性の単純な命名規則に従う必要があります。

Default Model Binder クラスをフォームに正しくバインドするには、Organizationクラスに次のスニペットを使用します

@using (Html.BeginForm()) {
    @Html.HiddenFor(o => o.Id)
    @Html.ValidationSummary( true )
    <fieldset>
        <legend>My Organization</legend>
        <div class="editor-label">@Html.LabelFor( model => model.Name )</div>
        <div class="editor-field">
            @Html.EditorFor( model => model.Name )
            @Html.ValidationMessageFor( model => model.Name )
        </div>
        <br />
        <div id="container">
            <div>Address List</div>
            @foreach (Address a in Model.Addresses ) {
                Html.EditorFor(a);
            }
        </div>
        <div style="text-align:right;margin-top:14px;">
            <input type="submit" id="btnSubmit" value="Save" />
        </div>
    </fieldset>
}

自動的にバインド可能にするには、フォームの結果のコードは次のようになります。

<form action="..." id="..." method="post">
    <input type="hidden" name="Id" value="2">
    <input type="hidden" name="Name" value="Acme Corporation">

    <!-- markup for each address -->
    <input type="hidden" name="Addresses[0].Id" value="1">
    <input type="hidden" name="Addresses[0].Line1" value="Line 1">
    <input type="hidden" name="Addresses[0].Line2" value="Line 2">
    ... and so on...
</form>

という名前のプロパティを持っていAddresses[index].PropertyNameます。クライアントに新しいアドレスを追加する場合は、それほど重要ではありません。コードがこのルールを尊重している限り、デフォルトの Model Binder に仕事を任せることができます。

お役に立てれば

于 2011-01-03T22:09:05.823 に答える
0

あなたの質問を正しく理解しているかどうかはわかりませんが、質問 1 に関しては、ViewModel を探していると思います。このように、おそらく..

OrganizationViewModel.cs

public class OrganizationViewModel
{
  public OrganizationViewModel(Organization org, IList<Address> addresses)
     {
       this.Organization = org;
       this.Addresses = addresses
     }
     public Organization Organization {get;set;}
     public IList<Address> Addresses {get;set;}
}

OrganizationController.cs

public class OrganizationController : Controller
{
  private readonly IOrganizationService _organizationService: //or whatever method you use
  public OrganizationController(IOrganizationService orgService)
     {
       this._organizationService = orgService;
     }

   public ActionResult Item(int id)
     {
       var org = _organizationService.GetOrganizationById(id);
       var addresses = _organizationService.GetOrgAddressesByOrgId(id);
       return View(new OrganizationViewModel(program, addresses));
     }
}

アイテム.cshtml

@model OrganizationViewModel
<h1>@Model.Organization.Name</h1>
<ul>
@foreach(var a in Model.Addresses)
{
<li>@a.Line1</li>
<li>@a.Line2</li>}
</ul>

2 番に答える前に、質問 1 を正しく理解しているかどうかを示す必要があるかもしれません。これがお役に立てば幸いです。

于 2011-01-28T15:15:01.490 に答える
0

LINQ to SQL を使用してこれを行うことができました。現在、代わりに Entity Framework を使用しようとしていますが、実際にはすべてがより複雑になります。だから私はあなたのための解決策を持っていませんが、おそらく私のL2Sソリューションが役立つでしょうか?

私のデータベースから生成されたモデルを使用して、私はこれを行うことができました:

@for (int i = 0; i < Model.Contact.EmailAddresses.Count; ++i)
{
    <li>
        @Html.TextBoxFor(x => x.Contact.EmailAddresses[i].EmailAddress)
        @Html.HiddenFor(x => x.Contact.EmailAddresses[i].EmailAddressID)
    </li>
} 

ビューモデルクラスがありました:

class ContactViewModel
{
    Contact contact { get; set; }
}

これは正常に機能し、コントローラー アクションで、Contact.ContactEmailAddresses リストが期待どおりに入力された Contact オブジェクトを取得しました。

しかし、EF では、データベースから生成された EmailAddresses プロパティで [i] を使用できなくなりました。私が思いついた最高のものは次のとおりです。

@Html.TextBox("Contact.EmailAddresses[" + i + "].EmailAddress", Model.Contact.EmailAddresses.ElementAt(i).EmailAddress)
于 2011-03-04T18:21:50.517 に答える