cll*_*pse 4 c# asp.net-mvc asp.net-mvc-routing
在强类型视图上使用内置验证助手实现错误处理时,通常在控制器中创建一个try/catch块,并返回一个视图,其中相应的模型作为View()方法的参数:
控制器
public class MessageController : Controller
{
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Models.Entities.Message message)
{
try
{
// Insert model into database
var dc = new DataContext();
dc.Messages.InsertOnSubmit(message);
dc.SubmitChanges();
return RedirectToAction("List");
}
catch
{
/* If insert fails, return a view with it's corresponding model to
enable validation helpers */
return View(message);
}
}
}
Run Code Online (Sandbox Code Playgroud)
风景
<%@ Page
Language="C#"
Inherits="System.Web.Mvc.ViewPage<Models.Entities.Message>" %>
<%= Html.ValidationSummary("Fill out fields marked with *") %>
<% using (Html.BeginForm()) { %>
<div><%= Html.TextBox("MessageText") %></div>
<div><%= Html.ValidationMessage("MessageText", "*") %></div>
<% } %>
Run Code Online (Sandbox Code Playgroud)
我已经以ActionFilterAttribute的形式实现了一个简单的错误处理程序,它可以重定向到一般错误视图,或者重定向到引发异常的视图,并让验证助手恢复生机.
以下是我的ActionFilterAttribute的外观:
public class ErrorLoggingAttribute : ActionFilterAttribute, IExceptionFilter
{
private Boolean _onErrorRedirectToGenericErrorView;
/// <param name="onErrorRedirectToGenericErrorView">
/// True: redirect to a generic error view.
/// False: redirect back the view which threw an exception
/// </param>
public ErrorLoggingAttribute(Boolean onErrorRedirectToGenericErrorView)
{
_onErrorRedirectToGenericErrorView = onErrorRedirectToGenericErrorView;
}
public void OnException(ExceptionContext ec)
{
if (_onErrorRedirectToGenericErrorView)
{
/* Redirect back to the view where the exception was thrown and
include it's model so the validation helpers will work */
}
else
{
// Redirect to a generic error view
ec.Result = new RedirectToRouteResult(new RouteValueDictionary
{
{"controller", "Error"},
{"action", "Index"}
});
ec.ExceptionHandled = true;
}
}
}
Run Code Online (Sandbox Code Playgroud)
重定向到抛出异常的视图非常简单.但这里是踢球者:为了使验证助手工作,你需要为视图提供它的模型.
你将如何返回抛出异常的视图并提供具有相应模型的视图?(在这种情况下Models.Entities.Message).
我得到了它的工作!
出于某种奇怪的原因,我需要做的就是将其传递ViewData给新的ResultView.
这是完整的代码:
public class ErrorLoggingAttribute : ActionFilterAttribute, IExceptionFilter
{
private String _controllerName, _actionName;
private Boolean _redirectToGenericView = false;
public ErrorLoggingAttribute()
{
}
public ErrorLoggingAttribute(String actionName, String controllerName)
{
_controllerName = controllerName;
_actionName = actionName;
_redirectToGenericView = true;
}
void IExceptionFilter.OnException(ExceptionContext ec)
{
// log error
if (_redirectToGenericView)
{
ec.Result = new RedirectToRouteResult(new RouteValueDictionary
{
{"controller", _controllerName},
{"action", _actionName}
});
}
else
{
ec.Result = new ViewResult
{
ViewName = ((RouteData) ec.RouteData).Values["action"].ToString(),
TempData = ec.Controller.TempData,
ViewData = ec.Controller.ViewData
};
}
ec.ExceptionHandled = true;
}
}
Run Code Online (Sandbox Code Playgroud)
以下是如何在控制器操作上使用该属性,重定向到同一视图(使用它的关联模型),以便在发生异常时启用标准验证帮助程序:
[ErrorLogging]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Models.Entities.Message message)
{
var dc = new Models.DataContext();
dc.Messages.InsertOnSubmit(message);
dc.SubmitChanges();
return RedirectToAction("List", new { id = message.MessageId });
}
Run Code Online (Sandbox Code Playgroud)
以下是发生异常时如何使用该属性重定向到通用视图:
[ErrorLogging("ControllerName", "ViewName")]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Models.Entities.Message message)
Run Code Online (Sandbox Code Playgroud)
这是一个完全的逻辑分离.控制器中没有任何东西,但非常基础.