1

最近我正在尝试从Django转换为ASP.NET MVC 4。我不明白的一件事是如何只编辑模型的几个字段,以及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>

这个作品对我来说似乎有点奇怪。

  1. 使用比原始模型更少的字段使编辑ViewModel完全相同,这是否正确,特别是如果最后我以这种方式保存编辑的信息。这个对吗?:

    var movieToUpdate = db.Movies.Single(p => p.MovieId == movie.MovieId); movieToUpdate.MovieTitle = movie.MovieTitle; movieToUpdate.CategoryId = movie.CategoryId; db.SaveChanges();

  2. "ViewModel"东西怎么干的方法论。如果我做得对。如果。当我在中评论StringLenght属性时EditModel,验证不起作用并引发错误"Validation failed for one or more entities. See 'EntityValidationErrors' property for more details."。我不得不将一个模型的一部分重写为不同的模型,包括属性在内的所有内容。我读到一些开发人员ViewModel为每个视图创建。如果必须像我的示例中那样这样做,在我看来更像是“重复自己”方法而不是 DRY。

  3. 为什么[Bind(Exclude = "MovieReleaseDate")在这个例子中不起作用?为什么不推荐?

最后一件事,在Django中,您只需创建ModelForm并排除或包含您想要的字段。然后在保存模型时,它只需对包含在ModelForm. 这ModelForm继承了选定字段的所有验证属性......像这样:

class ColorsForm(ModelForm):
    class Meta:
        model = UserAdditionalData
        fields = ('show_color', 'color')

我在 .NET 中做错了吗?

4

0 回答 0