Asp.net mvc MVC控制器中重构和处理非异常错误的设计模式
在我的MVC3应用程序中,我有一个特定于每个控制器的“查询”类,该类执行域实体之间的转换,并将它们转换为视图模型。我这样做是为了保持我的控制器干净,并且更容易单独对控制器和查询进行单元测试 但是,在某些情况下,查询方法需要将非异常错误消息传递给视图(例如,找不到实体)。但是,由于我的控制器仅从查询方法接收ViewModel,而没有任何类型的返回代码,因此我发现传递此错误的仅有两个选项如下:Asp.net mvc MVC控制器中重构和处理非异常错误的设计模式,asp.net-mvc,design-patterns,error-handling,refactoring,controller,Asp.net Mvc,Design Patterns,Error Handling,Refactoring,Controller,在我的MVC3应用程序中,我有一个特定于每个控制器的“查询”类,该类执行域实体之间的转换,并将它们转换为视图模型。我这样做是为了保持我的控制器干净,并且更容易单独对控制器和查询进行单元测试 但是,在某些情况下,查询方法需要将非异常错误消息传递给视图(例如,找不到实体)。但是,由于我的控制器仅从查询方法接收ViewModel,而没有任何类型的返回代码,因此我发现传递此错误的仅有两个选项如下: 从查询方法引发异常,并使用Try/Catch块捕获控制器中的异常 向视图模型添加一个名为“ErrorMes
- 当发生错误时,控制器必须接收整个视图模型才能获取ErrorMessage属性
- 视图必须有硬编码逻辑和两个部分来显示错误或正常内容
- 虽然我可以将
逻辑放在我的控制器中,以确定要传递哪个视图,但它仍然不像是一个“干净”的解决方案if(Model.ErrorMessage!=null)
public class ApplicationViewModel
{
public string ErrorMessage { get; set; }
public int Id { get; set; }
public string Name { get; set; }
// Other properties here...
}
public ActionResult Retrieve(Guid guid)
{
return View("Application", _applicationQueries.GetApplicationViewModel(guid));
}
public ApplicationViewModel GetApplicationViewModel(Guid guid)
{
var applicationViewModel = new applicationViewModel();
if (!_applicationServices.Exists(guid))
{
applicationViewModel.ErrorMessage = "The requested application does not exist.";
return applicationViewModel;
}
// More code here that checks things which might set the ErrorMessage property...
var application = _applicationServices.GetApplicationByGuid((Guid)guid);
Mapper.Map(grantApplication, grantApplicationViewModel);
return grantApplicationViewModel;
}
@model MyApp.Web.Areas.Application.Models.ApplicationViewModel
if (Model.ErrorMessage != null)
{
<div>@Model.ErrorMessage</div>
}
else
{
<!-- Display "normal" content here //>
}
控制器方法示例:
public class ApplicationViewModel
{
public string ErrorMessage { get; set; }
public int Id { get; set; }
public string Name { get; set; }
// Other properties here...
}
public ActionResult Retrieve(Guid guid)
{
return View("Application", _applicationQueries.GetApplicationViewModel(guid));
}
public ApplicationViewModel GetApplicationViewModel(Guid guid)
{
var applicationViewModel = new applicationViewModel();
if (!_applicationServices.Exists(guid))
{
applicationViewModel.ErrorMessage = "The requested application does not exist.";
return applicationViewModel;
}
// More code here that checks things which might set the ErrorMessage property...
var application = _applicationServices.GetApplicationByGuid((Guid)guid);
Mapper.Map(grantApplication, grantApplicationViewModel);
return grantApplicationViewModel;
}
@model MyApp.Web.Areas.Application.Models.ApplicationViewModel
if (Model.ErrorMessage != null)
{
<div>@Model.ErrorMessage</div>
}
else
{
<!-- Display "normal" content here //>
}
示例应用程序查询方法:
public class ApplicationViewModel
{
public string ErrorMessage { get; set; }
public int Id { get; set; }
public string Name { get; set; }
// Other properties here...
}
public ActionResult Retrieve(Guid guid)
{
return View("Application", _applicationQueries.GetApplicationViewModel(guid));
}
public ApplicationViewModel GetApplicationViewModel(Guid guid)
{
var applicationViewModel = new applicationViewModel();
if (!_applicationServices.Exists(guid))
{
applicationViewModel.ErrorMessage = "The requested application does not exist.";
return applicationViewModel;
}
// More code here that checks things which might set the ErrorMessage property...
var application = _applicationServices.GetApplicationByGuid((Guid)guid);
Mapper.Map(grantApplication, grantApplicationViewModel);
return grantApplicationViewModel;
}
@model MyApp.Web.Areas.Application.Models.ApplicationViewModel
if (Model.ErrorMessage != null)
{
<div>@Model.ErrorMessage</div>
}
else
{
<!-- Display "normal" content here //>
}
从Application.cshtml视图中单击以进行错误处理:
public class ApplicationViewModel
{
public string ErrorMessage { get; set; }
public int Id { get; set; }
public string Name { get; set; }
// Other properties here...
}
public ActionResult Retrieve(Guid guid)
{
return View("Application", _applicationQueries.GetApplicationViewModel(guid));
}
public ApplicationViewModel GetApplicationViewModel(Guid guid)
{
var applicationViewModel = new applicationViewModel();
if (!_applicationServices.Exists(guid))
{
applicationViewModel.ErrorMessage = "The requested application does not exist.";
return applicationViewModel;
}
// More code here that checks things which might set the ErrorMessage property...
var application = _applicationServices.GetApplicationByGuid((Guid)guid);
Mapper.Map(grantApplication, grantApplicationViewModel);
return grantApplicationViewModel;
}
@model MyApp.Web.Areas.Application.Models.ApplicationViewModel
if (Model.ErrorMessage != null)
{
<div>@Model.ErrorMessage</div>
}
else
{
<!-- Display "normal" content here //>
}
@model MyApp.Web.Areas.Application.Models.ApplicationViewModel
如果(Model.ErrorMessage!=null)
{
@Model.ErrorMessage
}
其他的
{
您可以将ModelState
实例传递到querys
层,它会注意添加错误:
public ApplicationViewModel GetApplicationViewModel(Guid guid, ModelStateDictionary modelState)
{
var applicationViewModel = new applicationViewModel();
if (!_applicationServices.Exists(guid))
{
modelState.AddModelError("", "The requested application does not exist.");
return applicationViewModel;
}
// More code here that checks things which might set the ErrorMessage property...
var application = _applicationServices.GetApplicationByGuid((Guid)guid);
Mapper.Map(grantApplication, grantApplicationViewModel);
return grantApplicationViewModel;
}
在你看来:
@model MyApp.Web.Areas.Application.Models.ApplicationViewModel
@Html.ValidationSummary()
@if (ViewData.ModelState.IsValid)
{
<!-- Display "normal" content here //>
}
@model MyApp.Web.Areas.Application.Models.ApplicationViewModel
@Html.ValidationSummary()
@if(ViewData.ModelState.IsValid)
{
事实上,我认为你得到的非常好。你是对的,你不应该对这种非异常错误使用try/catch。我不会担心传回整个视图模型:这并不是说你在返回错误之前用大量数据填充它。至于必须在视图中切换,真的没有办法得到aro而且:如果你要对错误条件进行自定义显示,对有效情况进行不同的显示,你必须有一个条件。我能想到的唯一其他方法是使用多态性。谢谢Darin。我喜欢你的方法,我会使用它。