问题描述
我试图找出在创建新对象的情况下使用视图模型的最佳途径。
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()));
}
我的问题是在控制器上创建方法。
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表单字段传递对象值回 contact.forename
当使用 HTML.EditorFor $ C $的格式C>助手...
@Html.EditorFor(model => model.contact.forename)
如果我用我可以访问他们的FormCollection
我的创建操作方法paremeter然后显式搜索 contact.value
但我不能用一个联系对象作为参数,以保持我的code非常干净,而不是每次都要建立一个新的联系人对象。
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操作,将prepare和填充这个视图模型:
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操作:
[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视图模型模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!