2016-12-27 117 views
0

我的主题开头是here如何在1个视图中实现2个模型的编辑方法

使用DropDownList不允许我编辑作者的名字..但是这个解决方案真的很好。

我需要编辑所有4个字段,如名称,标题,年份和价格。

我尽量让类似的复合模式:

public class BookAuthorCompositeModel 
{ 
    public Author author { get; set; } 
    public Book book { get; set; } 
} 

更改我的get方法:

// GET: Books/Edit/5  
public ActionResult Edit(int? id) 
{ 
    if (id == null) 
    { 
     return HttpNotFound(); 
    } 
    var compModel = new BookAuthorCompositeModel(); 
    compModel.book = dbBooks.Books.ToList().Where(a => a.Id == id).SingleOrDefault(); 
    compModel.author = dbBooks.Authors.ToList().Where(x => x.Id == id).SingleOrDefault(); 
    return View(bookEdit); 
} 

,它会显示所有我需要(我点击“编辑”,并看到有关名称的信息,标题,年份和价格)。

我的看法是:

@model BookStorage.Models.BookAuthorCompositeModel 

@{ 
    ViewBag.Title = "Edit"; 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 

<h2>Edit</h2> 

@using (Html.BeginForm()) 
{ 
    @Html.AntiForgeryToken() 

    <div class="form-horizontal"> 
     <h4>Book</h4> 
     <hr /> 
     @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 
     @Html.HiddenFor(model => model.book.Id) 

     <div class="form-group"> 
      @Html.LabelFor(model => model.author.AuthorName, "AuthorName", htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.EditorFor(model => model.author.AuthorName, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.author.AuthorName, "", new { @class = "text-danger" }) 
      </div> 
     </div> 
     <div class="form-group"> 
      @Html.LabelFor(model => model.book.Title, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.EditorFor(model => model.book.Title, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.book.Title, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.book.YearPublish, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.EditorFor(model => model.book.YearPublish, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.book.YearPublish, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.book.Price, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.EditorFor(model => model.book.Price, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.book.Price, "", new { @class = "text-danger" }) 
      </div> 
     </div> 


     <div class="form-group"> 
      <div class="col-md-offset-2 col-md-10"> 
       <input type="submit" value="Save" class="btn btn-default" /> 
      </div> 
     </div> 
    </div> 
} 

<div> 
    @Html.ActionLink("Back to List", "Index") 
</div> 

@section Scripts { 
    @Scripts.Render("~/bundles/jqueryval") 
} 

但蹊跷的是Post方法:

[HttpPost] 
public ActionResult Edit(Book book) 
{ 
    if (ModelState.IsValid) 
    { 
     dbBooks.Entry(BAmodel.book).State = EntityState.Modified; 
     dbBooks.Entry(BAmodel.author).State = EntityState.Modified; 

     dbBooks.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 
    return View(book); 
} 

dbBooks.SaveChanges();导致错误(存储更新,插入或删除语句影响了意外的行数(0)。)。我认为使用这种ViewModel有助于编辑所有行,但它不会将数据发送到数据库,并且我不明白什么是错误的。

+0

FWIW,您应该*从不*更新由模型绑定器创建的实体从发布数据。始终将新实体从数据库中拉出来,并将发布的数据映射到其上。 –

回答

2

如果我理解正确,你想要的是更新上下文“书”和上下文“作者”在相同的API方法。

要做到这一点,首先我会做一个包含两个对象,你已经有一个视图模型:

public class BookAuthorCompositeModel 
{ 
    public Author author { get; set; } 
    public Book book { get; set; } 
} 

(这可以被修改为了进行验证,也许创造了验证新对象至少,但我们继续吧)

现在,您需要在API调用中接收相同的ViewModel,然后根据对象执行相应的操作。为此,我通常会在我的上下文中执行Get调用,以获取要修改的对象。然后我可以自由更新我的上下文:

[HttpPost] 
    public ActionResult Edit(BookAuthorCompositeModel model) 
    { 
     ... 
    } 

要获取要修改的对象,取决于您使用的是什么。简单的存储库模式,单元模式,并不重要。当你得到Book条目时,只需修改它,使用更新函数,我相信它是dbBooks.BookContext.Update(book),其中“book”是可变的。事情是这样的:

var book = dbBooks.BooksContext.Get(model.Book.BookId); 

book.name = "New Name"; 

dbBooks.BooksContext.Update(book); 
dbBooks.SaveChanges(); 

用于获取和更新(获得()和.Update())必须从模式的,你正在使用,但也许这可以帮助你的方法。

祝你好运!

相关问题