开发者

ASP.NET MVC 3 One-To-Many Form

开发者 https://www.devze.com 2023-03-23 01:21 出处:网络
I have this classes who is mapped using Entity Framework Code First: public class Person { public int PersonId { get; set; }

I have this classes who is mapped using Entity Framework Code First:

public class Person
{
    public int PersonId { get; set; }
    public string Name { get; set; }
    //... additional properties
    [Required]
    public virtual ICollection<Address> Addresses { get; set; }
}
public class Address
{
    public int AddressId { get; set; }
    public string Street { get; set; }
    //... additional properties

    public int PersonId { get; set; }
    public virtual Person Person { get; set; }
}

So, using ASP.NET MVC 3, how can I perform the Edit View for Person to fill all Person properties within an Address in just one Form?

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Person</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>

        <div class="editor-label">
            @Html.LabelFor(model => model.Adresses.FirstOrDefault().Street)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Adresses.FirstOrDefault().Street)
            @Html.ValidationMessageFor(model => model.Adresses.FirstOrDefault().Street)
        </div>

        <p>
            <input type="submit" value="Create" />
   开发者_运维知识库     </p>
    </fieldset>
}

This works fine to show the inputs with Street from database, but when I do the submit, the Street doesnt change.

[HttpPost]
public ActionResult Edit(int id, FormCollection formCollection)
{
    Person person = unityOfWork.PersonRepository.GetById(id);

    UpdateModel<Person>(person);

    if (ModelState.IsValid)
    {
        unityOfWork.PersonRepository.Update(person);
        unityOfWork.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(person);
}


Because of the way the model binder has to fix up collections, it will be struggling because the relevant ID's aren't present.

It would be better to create a ViewModel for this screen and translate between it and the underlying domain model.

If you were providing a facility to edit all addresses, I'd use Steve Sanderson's BeginCollectionItem helper. But since you're only editing a single address, a new ViewModel class with a Person property and a separate Address property would be easier, or use a class that included the properties from Person and Address that are relevant to this view.

I'm a big proponent of the Separation of Concerns. There are logically three models in your application; the Entity model that describes the implementation of data storage in your database, the View model that describes the implementation of data representation in the UI and the Domain model which is the logical representation of the data within your application. It is tempting to use the same model for each purpose, as you're doing here. But as soon as your requirements become none-trivial, it becomes a burden, so you're better off creating classes that work best where you need them.

0

精彩评论

暂无评论...
验证码 换一张
取 消