ASP.NET MVC 3 视图模型模式 [英] ASP.NET MVC 3 Viewmodel Pattern

查看:25
本文介绍了ASP.NET MVC 3 视图模型模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试找出在创建新对象的情况下使用视图模型的最佳方式.

I am trying to work out the best way of using a viewmodel in the case of creating a new object.

我有一个非常简单的视图模型,其中包含一个联系人对象和一个选择的公司列表.

I have a very simple view model that contains a contact object and a select list of companies.

private ICompanyService _Service;
public SelectList ContactCompanyList { get; private set; }
public Contact contact { get; private set; }

public ContactCompanyViewModel(Contact _Contact)
{
    _Service = new CompanyService();
    contact = _Contact;
    ContactCompanyList = GetCompanyList();
}

private SelectList GetCompanyList()
{
    IEnumerable<Company> _CompanyList = _Service.GetAll();
    return new SelectList(_CompanyList, "id", "name");       
}

然后我有使用此视图模型的联系人控制器,并使我能够为我的联系人选择相关公司.

I then have contact controller that uses this viewmodel and enable me to select a related company for my contact.

[Authorize]
public ActionResult Create()
{                       
    return View(new ContactCompanyViewModel(new Contact()));
}

我的问题是控制器上的 create 方法.

My issue is with the create method on the controller.

[Authorize]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Contact _Contact)
{
    try
    {
        _Service.Save(_Contact);
        return RedirectToAction("Index");
    }
    catch
    {
       return View();
    }
}

问题是视图返回了一个空的联系人对象,但是!填充了公司 ID,这是因为下拉列表显式声明了其字段名称.

The problem is that the view returns an empty contact object, but! the company id is populated, this is because the dropdown list explicitly declares its field name.

 @Html.DropDownList("parent_company_id",Model.ContactCompanyList)

当使用 HTML.EditorFor 帮助器时,标准 html 表单字段以 contact.forename 的格式将对象值传回...

The standard html form fields pass the objects values back in the format of contact.forename when using the HTML.EditorFor helper...

@Html.EditorFor(model => model.contact.forename)

如果我使用 FormCollection 作为我的创建操作方法参数,然后显式搜索 contact.value,我可以访问它们,但我不能使用 Contact 对象作为参数保持我的代码干净整洁,而不必每次都构建一个新的联系人对象.

I can access them if I use a FormCollection as my create action method paremeter and then explicitly search for contact.value but I cannot use a Contact object as a parameter to keep my code nice and clean and not have to build a new contact object each time.

我尝试将实际的视图模型对象作为参数传回,但这只会因构造函数错误而爆炸(这令人困惑,因为视图绑定到视图模型而不是联系对象).

I tried passing the actual view model object back as a parameter but that simply blows up with a constructor error (Which is confusing seeing as the view is bound to the view model not the contact object).

有没有一种方法可以定义 Html.EditFor 字段的名称,以便在传递回控制器上的创建操作方法时,该值正确映射回联系人对象?或者我是否在某处犯了一些 FUBAR 错误(这是最有可能的解释,因为这是一个学习练习!).

Is there a way that I can define the name of the Html.EditFor field so that the value maps correctly back to the contact object when passed back to the create action method on my controller? Or Have I made some FUBAR mistake somewhere (that is the most likely explanation seeing as this is a learning exercise!).

推荐答案

您的视图模型似乎有误.视图模型不应引用任何服务.视图模型不应引用任何域模型.视图模型应该具有无参数构造函数,以便它们可以用作 POST 操作参数.

Your view model seems wrong. View models should not reference any services. View models should not reference any domain models. View models should have parameterless constructors so that they could be used as POST action parameters.

这里有一个更适合您的场景的视图模型:

So here's a more realistic view model for your scenario:

public class ContactCompanyViewModel
{
    public string SelectedCompanyId { get; set; }
    public IEnumerable<SelectListItem> CompanyList { get; set; }

    ... other properties that the view requires
}

然后你可以有一个 GET 动作来准备和填充这个视图模型:

and then you could have a GET action that will prepare and populate this view model:

public ActionResult Create()
{
    var model = new ContactCompanyViewModel();
    model.CompanyList = _Service.GetAll().ToList().Select(x => new SelectListItem
    {
        Value = x.id.ToString(),
        Text = x.name
    });
    return View(model);
}

和一个 POST 操作:

and a POST action:

[HttpPost]
public ActionResult Create(ContactCompanyViewModel model)
{
    try
    {
        // TODO: to avoid this manual mapping you could use a mapper tool
        // such as AutoMapper
        var contact = new Contact
        {
            ... map the contact domain model properties from the view model
        };
        _Service.Save(contact);
        return RedirectToAction("Index");
    }
    catch 
    {
        model.CompanyList = _Service.GetAll().ToList().Select(x => new SelectListItem
        {
            Value = x.id.ToString(),
            Text = x.name
        });
        return View(model);
    }
}

现在在您的视图中您可以使用您的视图模型:

and now in your view you work with your view model:

@model ContactCompanyViewModel
@using (Html.BeginForm())
{
    @Html.DropDownListFor(x => x.SelectedCompanyId, Model.CompanyList)

    ... other input fields for other properties

    <button type="submit">Create</button>
}

这篇关于ASP.NET MVC 3 视图模型模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆