最近我正在尝试从 Django 转换为 ASP.NET MVC 4 。我不明白的一件事是如何只编辑模型的几个字段,以及 ViewModel 是如何形成的。在示例中,我不想更新条目创建日期。 [Bind(Exclude = "Date")
以某种方式不起作用,而且我注意到建议使用ViewModel。我想告诉你我是怎么做到的,你问这是否正确以及其他一些问题。
模型和ViewModel:
//Movie Model
public class Movie
{
[Key]
public int MovieId { get; set; }
[Required]
[Display(Name = "Title")]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 2)]
public string MovieTitle { get; set; }
[DataType(DataType.Date)]
[Display(Name = "Release Date")]
public DateTime MovieReleaseDate { get; set; }
[Required]
[Display(Name = "Category")]
public int CategoryId { get; set; }
public Category MovieCategory { get; set; }
}
//MovieEdit ViewModel
public class MovieEdit
{
[Key]
public int MovieId { get; set; }
[Required]
[Display(Name = "Title")]
//[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 2)]
public string MovieTitle { get; set; }
[Required]
[Display(Name = "Category")]
public int CategoryId { get; set; }
}
控制器:
//
// GET: /Default1/Edit/5
public ActionResult Edit(int id = 0)
{
Movie movie = db.Movies.Find(id);
if (movie == null)
{
return HttpNotFound();
}
ViewBag.CategoryId = new SelectList(db.Categories, "CategoryId", "CategoryName", movie.CategoryId);
return View(Mapper.Map<MovieEdit>(movie));
}
//
// POST: /Default1/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(MovieEdit movie)
{
if (ModelState.IsValid)
{
var movieToUpdate = db.Movies.Single(p => p.MovieId == movie.MovieId);
movieToUpdate.MovieTitle = movie.MovieTitle;
movieToUpdate.CategoryId = movie.CategoryId;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(movie);
}
查看:
@model MegaTest.ViewModels.MovieEdit
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>Movie</legend>
@Html.HiddenFor(model => model.MovieId)
<div class="editor-label">
@Html.LabelFor(model => model.MovieTitle)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.MovieTitle)
@Html.ValidationMessageFor(model => model.MovieTitle)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.CategoryId)
</div>
<div class="editor-field">
@Html.DropDownList("CategoryId", "-- Choose Category --")
@Html.ValidationMessageFor(model => model.CategoryId)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
这项工作对我来说似乎有点奇怪。
使用比原始模型更少的字段使编辑ViewModel
完全相同是正确的,特别是如果最后我以这种方式保存编辑的信息。这是对的吗?:
var movieToUpdate = db.Movies.Single(p => p.MovieId == movie.MovieId);
movieToUpdate.MovieTitle = movie.MovieTitle;
movieToUpdate.CategoryId = movie.CategoryId;
db.SaveChanges();
这个"ViewModel"
内容如何用于DRY方法。如果我做得对。如果。当我在StringLenght
中评论EditModel
属性时,验证不起作用并引发错误"Validation failed for one or more entities. See 'EntityValidationErrors' property for more details."
。我不得不将一个模型的一部分重写为不同的模型,其中包括属性。我读到一些开发人员为每个View创建ViewModel
。如果必须这样做,在我的例子中似乎更像是“重复你自己”的方法而不是DRY。
为什么[Bind(Exclude = "MovieReleaseDate")
在这个例子中不起作用?为什么不推荐它?
最后一件事,在 Django 中,您只需创建ModelForm
并排除或包含您想要的字段。然后在保存模型时,它只对ModelForm
中包含的字段执行“更新”。这个ModelForm
继承了所选字段的所有验证属性......就像这样:
class ColorsForm(ModelForm):
class Meta:
model = UserAdditionalData
fields = ('show_color', 'color')
我在.NET中做错了吗?