C# 如何避免在控制器中放置域逻辑?
在PRO ASP.NET MVC手册中: 这当然是有可能把域名 将逻辑输入控制器,即使 你不应该,只是因为看起来 在有压力的时刻,权宜之计 只是一个人为的例子,如果应用程序不允许负序,那么将数量更改为1放在哪里?如果我们遵循域逻辑不应放在控制器中的原则,那么这当然不建议使用:C# 如何避免在控制器中放置域逻辑?,c#,asp.net-mvc,C#,Asp.net Mvc,在PRO ASP.NET MVC手册中: 这当然是有可能把域名 将逻辑输入控制器,即使 你不应该,只是因为看起来 在有压力的时刻,权宜之计 只是一个人为的例子,如果应用程序不允许负序,那么将数量更改为1放在哪里?如果我们遵循域逻辑不应放在控制器中的原则,那么这当然不建议使用: [AcceptVerbs(HttpVerbs.Post)] public ActionResult PlaceOrder(Order order) { if (ModelState.IsValid) {
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult PlaceOrder(Order order)
{
if (ModelState.IsValid)
{
order.Submit();
return View("Thanks", order);
}
else
{
if (order.Quantity <= 0)
{
ModelState.Remove("Quantity");
order.Quantity = 1;
}
return View(order);
}
}
这种方法唯一的问题是,模型(顺序)不能影响模型状态,因此,程序总是显示用户最后输入的内容
为了避免在控制器中放置域逻辑并且视图仍然能够反映模型属性的值,最好的方法是什么?验证不是控制器的任务。您可以将所有必需的逻辑放在不同的模块中,只需在其中分发请求。验证不是控制器的任务。您可以将所有必需的逻辑放在不同的模块中,只需在其中分发请求。啊,但是业务层可以影响模型状态。使用服务层验证时签出。这也是对存储库和控制反转的一个很好的介绍 一般的方法是为模型状态创建一个包装器,该包装器实现一个简单的接口,用于向模型状态添加错误。您的业务层对接口起作用-因此它与您的modelstate没有任何关系。您的单元测试可以实现一个伪包装器,该包装器也可以实现相同的接口
看起来您的特定示例正在将用户的无效输入更改为有效输入。我的建议是简单地保留无效输入,并在控制器返回视图时使用AddModelError来反映这一点。啊,但是业务层可以影响模型状态。使用服务层验证时签出。这也是对存储库和控制反转的一个很好的介绍 一般的方法是为模型状态创建一个包装器,该包装器实现一个简单的接口,用于向模型状态添加错误。您的业务层对接口起作用-因此它与您的modelstate没有任何关系。您的单元测试可以实现一个伪包装器,该包装器也可以实现相同的接口
看起来您的特定示例正在将用户的无效输入更改为有效输入。我的建议是简单地保留无效输入,并在控制器返回视图时使用AddModelError来反映这一点。撇开具体示例不谈,有没有方法使模型与ModelState同步?理想情况下(正如MVC原则所鼓励的那样),ModelState的更新不应该在控制器特定的示例上进行,有没有一种方法可以使模型与ModelState同步?理想情况下(MVC原则鼓励),ModelState的更新不应该在控制器上进行
public class Order : IDataErrorInfo
{
public int OrderId { set; get; }
public int ProductId { set; get; }
public int Quantity { set; get; }
public string Error { get { return null; } }
public string this[string propName]
{
get
{
if (propName == "Quantity" && Quantity <= 0)
{
Quantity = 1;
return "0 or negative quantity not allowed, changed it to 1";
}
else
return null;
}
}
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult PlaceOrder(Order order)
{
if (ModelState.IsValid)
{
order.Submit();
return View("Thanks", order);
}
else
{
// Response.Write(order.Quantity.ToString()); // this was changed in Model
return View(order); // but the View didn't reflect that fact
}
}