最近、 DjangoからASP.NET MVC 4に変換しようとしています。私が理解していないことの 1 つは、モデルのいくつかのフィールドのみを編集する方法と、ViewModelがこれにどのように到達するかです。例では、エントリの作成日を更新したくありません。[Bind(Exclude = "Date")
どういうわけかうまくいかなかった、さらに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."
。あるモデルの一部を別のモデルに書き直さなければなりませんでした。すべての属性が含まれていました。ViewModel
ビューごとに作成する開発者もいると読みました。これが私の例のように行われなければならない場合、私にはDRYよりも「Repeat Yourself」方法論のように思えます。[Bind(Exclude = "MovieReleaseDate")
この例でうまくいかなかったのはなぜですか? そして、なぜそれが推奨されないのですか?
最後に、DjangoModelForm
では、必要なフィールドを作成して除外または含めるだけです。次に、モデルを保存するときに、に含まれるフィールドで「UPDATE」を実行しますModelForm
。これModelForm
は、選択したフィールドのすべての検証属性を継承します...次のように:
class ColorsForm(ModelForm):
class Meta:
model = UserAdditionalData
fields = ('show_color', 'color')
.NET で何か間違ったことをしていますか?