我有一个简单的模型,它使用多选列表框来处理多对多 EF 关系。
在我的Create
行动中,我得到了错误
从类型“System.String”到类型“MyProject.Models.Location”的参数转换失败,因为没有类型转换器可以在这些类型之间进行转换。
我有 2 个模型,一个文章和一个位置:
文章.cs
namespace MyProject.Models
{
public class Article
{
public Article()
{
Locations = new List<Location>();
}
[Key]
public int ArticleID { get; set; }
[Required(ErrorMessage = "Article Title is required.")]
[MaxLength(200, ErrorMessage = "Article Title cannot be longer than 200 characters.")]
public string Title { get; set; }
public virtual ICollection<Location> Locations { get; set; }
}
位置.cs:
namespace MyProject.Models
{
public class Location
{
[Key]
public int LocationID { get; set; }
[Required(ErrorMessage = "Location Name is required.")]
[MaxLength(100, ErrorMessage = "Location Name cannot be longer than 100 characters.")]
public string Name { get; set; }
public virtual ICollection<Article> Articles { get; set; }
}
}
我有一个视图模型:
namespace MyProject.ViewModels
{
public class ArticleFormViewModel
{
public Article article { get; set; }
public virtual List<Location> Locations { get; set; }
public ArticleFormViewModel(Article _article, List<Location> _locations)
{
article = _article;
Locations = _locations;
}
}
}
创建.cshtml:
@model MyProject.ViewModels.ArticleFormViewModel
<h2>Create</h2>
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>Article</legend>
<div class="editor-label">
@Html.LabelFor(model => model.article.Title)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.article.Title)
@Html.ValidationMessageFor(model => model.article.Title)
</div>
<h3>Locations</h3>
@Html.ListBoxFor(m=>m.article.Locations,new MultiSelectList(Model.Locations,"LocationID","Name"))
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
最后我的控制器动作:
// GET: /Article/Create
public ActionResult Create()
{
var article = new Article();
var AllLocations = from l in db.Locations
select l;
ArticleFormViewModel viewModel = new ArticleFormViewModel(article, AllLocations.ToList());
return View(viewModel);
}
//
// POST: /Article/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Article article)
{
var errors = ModelState.Values.SelectMany(v => v.Errors);
if (ModelState.IsValid)
{
var locations = Request.Form["article.Locations"];
if (locations != null)
{
var locationIDs = locations.Split(',');
foreach (var locationID in locationIDs)
{
int id = int.Parse(locationID);
Location location = db.Locations.Where(l => l.LocationID == id).First();
article.Locations.Add(location);
}
}
db.Articles.Add(article);
db.SaveChanges();
return RedirectToAction("Index");
}
var AllLocations = from l in db.Locations
select l;
ArticleFormViewModel viewModel = new ArticleFormViewModel(article, AllLocations.ToList());
return View(viewModel);
}
这一切都工作得很好,我的位置列表框被正确填充:
如果我没有选择位置,那么我的模型会正确保存。如果我选择一个或多个位置,则我的 Model.IsValid 检查失败并出现异常
从类型“System.String”到类型“MyProject.Models.Location”的参数转换失败,因为没有类型转换器可以在这些类型之间进行转换。
但是,如果我删除 ModelState.IsValid 检查,那么尽管出现错误,但我的值都已正确保存到数据库中——只是我失去了对模型标题等内容的验证。
希望有人能帮忙!