Asp.net mvc TryUpdateModel的实例,ASP.NETMVC3
我不明白,如何在使用TryUpdateModel的同时保存MVC架构 如果我没有弄错的话,使用DataContext必须在模型中。那么这样的代码,Asp.net mvc TryUpdateModel的实例,ASP.NETMVC3,asp.net-mvc,model,controller,Asp.net Mvc,Model,Controller,我不明白,如何在使用TryUpdateModel的同时保存MVC架构 如果我没有弄错的话,使用DataContext必须在模型中。那么这样的代码, var db=new TestEverybody();//it is class, which was generated by EntityFramework var currentTesting=db.Testing.(t => t.id == id).First(); 必须位于模型中,而不是控制器中,不是吗 但是TryUpdateMo
var db=new TestEverybody();//it is class, which was generated by EntityFramework
var currentTesting=db.Testing.(t => t.id == id).First();
必须位于模型中,而不是控制器中,不是吗
但是TryUpdateModel使用的示例如下:
public ActionResult Edit(Testing obj)//Testing collection
{
var db = new TestEverybody();
var currentTesting=db.Testing.(t => t.id == obj.id).First();
TryUpdateModel(currentTesting);
db.SaveChanges();
return RedirectToAction("Index");
}
这种方式是否打破了MVC架构?我们在控制器中使用数据库,而不是在特殊的模型类中
那么,在实际项目中使用TryUpdateModel的最佳方式是什么
所以,这些代码必须位于模型中,而不是控制器中,不是吗
不一定。就个人而言,我更喜欢将数据访问代码放在存储库中。然后使用构造函数注入将一些特定的存储库实现传递给控制器(例如,如果我使用EF,我将编写一个EF存储库实现)。因此控制器将如下所示:
public class HomeController: Controller
{
private readonly IMyRepository _repository;
public HomeController(IMyRepository repository)
{
_repository = repository;
}
public ActionResult Edit(int id)
{
var currentTesting = _repository.GetTesting(id);
TryUpdateModel(currentTesting);
_repository.SaveChanges();
return RedirectToAction("Index");
}
}
由于OP的要求,这里有一个ViewModel模式的示例,或者我喜欢称之为ASP.NET MVC done Rightly 那么为什么要使用视图特定的模型呢
public class Product {
public int Id {get;set;}
public string Name {get;set;}
public string Description {get;set;}
public decimal Price {get;set;}
}
假设您有一个简单的表单,其中用户只能更新产品的名称
和说明
。但是您使用的是(非常贪婪的)TryUpdateModel
因此,我使用任意数量的工具(如Fiddler)自己构建一个帖子,并发送以下内容:
public ActionResult Edit(Testing obj)//Testing collection
{
var db = new TestEverybody();
var currentTesting=db.Testing.(t => t.id == obj.id).First();
TryUpdateModel(currentTesting);
db.SaveChanges();
return RedirectToAction("Index");
}
Name=WhatverIWant&Description=UnluckyFool&Price=0
NET MVC模型绑定器将检查输入表单集合,查看实体上是否存在这些属性,并自动为您绑定它们。因此,当您对刚从数据库检索到的实体调用“TryUpdateModel”时,所有匹配的属性都将更新(包括价格!)。是时候换个新的选择了
视图特定模型
它只包含视图中所需的属性。注意,我们还添加了一些验证属性、显示属性和一些特定于mvc的属性
通过不受视图模型的限制,它可以使您的视图更清晰。例如,我们可以通过在视图中显示以下内容来渲染整个编辑表单:
@Html.EditorFor(model => model)
Mvc将检查我们添加到视图模型中的所有属性,并自动连接验证、标签和正确的输入字段(即用于描述的文本区域)
张贴表格
从这段代码中可以明显看出它的作用。更新实体时不会产生任何不良影响,因为我们在实体上显式设置属性
我希望这足以解释视图模型模式,让您愿意使用它。我的建议是,在实际项目中,不要使用它。您应该使用视图特定的模型,并在视图模型的属性与要更新的实体上的属性之间进行映射。TryUpdateModel/UpdateModel是贪婪的,最终会咬到你。这是MVVM模式吗?我在哪里可以读到你的方法?不,这是MVC(正确完成)。我在下面添加了一个答案来解释。希望这有帮助。谢谢。自动属性映射的最佳方式是什么?“model”只有名称和描述,因此如果我尝试使用ApplyCurrentValues,价格将替换为null,不是吗?您可以使用类似AutoMapper的工具自动将实体的属性映射到viewmodel。在我看来(以及AutoMapper组中的大多数人),您不应该反过来映射(从viewmodel映射回实体),因为这可能会导致意外的结果。我不理解这个问题。您不能避免从viewModel映射到模型,您也不应该这样做。这就是上面的要点,向您展示了如何在视图特定模型和实体之间进行映射。+1这是一个很好的答案,帮助我克服了应用程序中遇到的一些问题。这似乎总是有很多重复,但您的回答说明了为什么这是一个好主意-它实际上使您的应用程序更易于开发和维护。@BenFoster如果您使用带有要包括/排除的字符串列表的TryUpdateModel,这不就消除了它的攻击性吗?您不能在ActionResult参数中指定Bind属性以防止过度过帐吗?我宁愿这样做,也不愿像您在示例中那样为每个要更新的属性指定正确的赋值语句。这通常仅用于模拟测试,因此您的控制器可以在其默认构造函数中创建
ActulRepository
的实例。然而,新手开发人员可能会看到这一点,并不知如何在不在本地实例化的情况下将其实际回购协议放入\u存储库。@JoeBrockhaus,我同意,因为我是他们中的一员=)
[HttpPost]
public ActionResult EditProduct(EditProductViewModel model) {
var product = repository.GetById(model.Id);
if (product == null) {
return HttpNotFound();
}
// input validation
if (ModelState.IsValid) {
// map the properties we **actually** want to update
product.Name = model.Name;
product.Description = model.Description;
repository.Save(product);
return RedirectToAction("index");
}
return View(model)
}