处理 MVC 发布模型的最佳实践是什么?
本文关键字:最佳 是什么 模型 MVC 布模型 处理 | 更新日期: 2023-09-27 17:57:18
我对 MVC 很陌生,仍然对 2 种具有相同结果的案例的最佳和正确方法感到困惑。假设某个用户应该为特定的根类别添加新的子类别。
案例1:子类别是 EF 映射的类,其中所有属性都不可为空。
控制器:
[Authorize]
public ActionResult Create()
{
SubCategory subCategory = new SubCategory();
subCategory.RootCategoryID = 1;
return View(subCategory);
}
[Authorize]
[HttpPost]
public ActionResult Create(SubCategory thisSubCategory)
{
if (ModelState.IsValid)
{
//And some BL logic called here to handle new object...
}
}
视图:
@Html.HiddenFor(model => model.ID)
@Html.HiddenFor(model => model.RootCategoryID)
<h3>Sub Category Name: </h3>
@Html.EditorFor(model => model.CategoryName)
@Html.ValidationMessageFor(model => model.CtaegoryName)
<input id="btnAdd" type="submit" value="Add" />
案例2:将帮助程序类添加为控制器的模型,并在发布后填充 EF 对象
控制器:
class SubCategoryHelper
{
public string Name { get; set; }
}
[Authorize]
public ActionResult Create()
{
SubCategoryHelper subCategory = new SubCategoryHelper();
return View(subCategory);
}
[Authorize]
[HttpPost]
public ActionResult Create(SubCategoryHelper thisSubCategory)
{
if (ModelState.IsValid)
{
SubCategory newSubCategory = new SubCategory();
newSubCategory.RootCategoryID = 1;
newSubCategory.CtaegoryName = thisSubCategory.Name;
//And some BL logic called here to handle new object...
}
}
视图:
子类别名称:
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
<input id="btnAdd" type="submit" value="Add" />
这两种方式都是一样的,但第一种方法看起来不太安全,因为可以在客户端更改隐藏。第二种方式更长,想象一下对于客户端或产品等丰富对象相同的方式......我应该选择什么?还是有其他方法?
第一种情况有利于简单。如果您扩展模型,则必须在较少的地方进行更改。它同样安全。您可以通过多种方式绕过创建或绑定隐藏的输入字段。
使用 BindAttribute
绕过属性绑定:
ActionResult Create([Bind(Exclude = "RootCategoryId")]
SubCategoryHelper thisSubCategory) {//....}
或者ScaffoldColumnAttribute
模型类属性(例如,当您使用编辑模板时):
[ScaffoldColumn(false)]
public int RootCategoryId {get; set;}
或者只是简单地不要公开它(就像您在示例中使用 Html.HiddenInput
帮助程序所做的那样)。
您已经描述的第二种方法通常称为视图模型模式。它鼓励将演示文稿和域图层分开。优点是,您的域模型不会被表示层特定的代码(如各种显示属性等)污染。Hovewer 它带来了域模型和视图模型之间映射的另一个开销。
可能没有通用的经验法则。这取决于您的应用类型。
如果它基本上是一些简单的数据驱动的CRUD应用程序,则可以轻松地使用第一个。然而,当您的应用程序变得更大时,您肯定会欣赏在单独的层上自由发挥双手的自由。如果您的 BLL 代码与除 ASP MVC 之外的其他类型的"客户端"(Web 服务、桌面等)一起使用,我肯定会选择第二个选项。
我还建议阅读这篇很棒的文章:分层值得映射吗
我总是使用案例 2,无论是我从事的小项目还是大项目,我总是将数据层(实体框架)和 UI 层分开。 特别是如果您使用的是实体框架,因为这些对象可能会变得很大,并且您传递的废话很多,您通常不需要。
与其称其为Helper
类,不如称它们为 ViewModel
或 Model
. 在您的情况下,SubCategoryViewModel
.
public class SubCategoryViewModel
{
public int Id {get;set;}
public int RootCategoryId {get;set;}
[Required]
public string Name { get; set; }
}
[Authorize]
public ActionResult Create()
{
var subCategoryViewModel = new SubCategoryViewModel();
return View(subCategoryViewModel);
}
[Authorize]
[HttpPost]
public ActionResult Create(SubCategoryViewModel viewModel)
{
if (ModelState.IsValid)
{
var subCategory = new SubCategory();
subCategory.RootCategoryID = 1;
subCategory.CategoryName = viewModel.Name;
//And some BL logic called here to handle new object...
}
}