我正在尝试在创建新对象的情况下找出使用viewmodel的最佳方法.
我有一个非常简单的视图模型,其中包含联系对象和公司的选择列表.
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");
}
Run Code Online (Sandbox Code Playgroud)
然后我有联系控制器使用这个视图模型,并让我为我的联系人选择一个相关的公司.
[Authorize]
public ActionResult Create()
{
return View(new ContactCompanyViewModel(new Contact()));
}
Run Code Online (Sandbox Code Playgroud)
我的问题是控制器上的create方法.
[Authorize]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Contact _Contact)
{
try
{
_Service.Save(_Contact);
return RedirectToAction("Index");
}
catch
{
return View();
}
}
Run Code Online (Sandbox Code Playgroud)
问题是视图返回一个空的联系人对象,但是!填充公司ID,这是因为下拉列表显式声明了其字段名称.
@Html.DropDownList("parent_company_id",Model.ContactCompanyList)
Run Code Online (Sandbox Code Playgroud)
标准的html表单字段以contact.forename使用HTML.EditorFor帮助程序时的格式传回对象值...
@Html.EditorFor(model => model.contact.forename)
Run Code Online (Sandbox Code Playgroud)
我可以访问它们,如果我使用一个FormCollection作为我的创建操作方法paremeter然后显式搜索contact.value但我不能使用Contact对象作为参数来保持我的代码漂亮和干净,而不必每次都建立一个新的联系人对象.
我尝试将实际的视图模型对象作为参数传回,但这只会导致构造函数错误(由于视图绑定到视图模型而不是联系对象,因此看起来很混乱).
有没有一种方法可以定义Html.EditFor字段的名称,以便在传回控制器上的create action方法时,值正确映射回联系对象?或者我在某处犯了一些FUBAR错误(这是最可能的解释,因为这是一次学习练习!).
Dar*_*rov 15
您的视图模型似乎有误.View模型不应该引用任何服务.视图模型不应引用任何域模型.视图模型应该具有无参数构造函数,以便它们可以用作POST操作参数.
所以这是一个更逼真的场景视图模型:
public class ContactCompanyViewModel
{
public string SelectedCompanyId { get; set; }
public IEnumerable<SelectListItem> CompanyList { get; set; }
... other properties that the view requires
}
Run Code Online (Sandbox Code Playgroud)
然后你可以有一个GET动作来准备和填充这个视图模型:
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);
}
Run Code Online (Sandbox Code Playgroud)
和一个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);
}
}
Run Code Online (Sandbox Code Playgroud)
现在在您的视图中,您可以使用视图模型:
@model ContactCompanyViewModel
@using (Html.BeginForm())
{
@Html.DropDownListFor(x => x.SelectedCompanyId, Model.CompanyList)
... other input fields for other properties
<button type="submit">Create</button>
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3610 次 |
| 最近记录: |