在我的ASP.NET MVC应用程序中,我有一个ErrorController,目前只有一个动作方法,它接收一个名为Error的自定义类,并将其呈现给名为Error.cshtml的视图。目前,Error类中只有2个属性:
public class Error{
public string UserFriendlyMmessage{get;set;}
public string ErrorMessage{get;set;}
}
Error.cshtml视图强类型为Error类。每当在action方法中抛出异常时,我都会执行以下操作:
Error error = new Error { UserFriendlyText = "The friendly message", ErrorDescription = "Error to be logged" };
return RedirectToAction("Index", "Error", new System.Web.Routing.RouteValueDictionary(error));
这里是ErrorController的动作方法:
public ActionResult Index(Error error)
{
return View(model: error, viewName:"Error");
}
虽然这很有效,但这样所有模型属性都会显示在网址中。是否有更好,更常用的方法?
答案 0 :(得分:5)
除了丑陋的查询字符串之外,您还有可能超出查询字符串限制,特别是如果您的邮件很长并且您向Error
添加了更多属性。
一种选择是将Error
保留到TempData
属性,然后return RedirectToAction("Index", "Error")
并在Index()
方法中获取TempData
的值并渲染观点。
另一种选择是使用HandleErrorAttribute属性根据特定异常呈现视图。例如
[HandleError(ExceptionType = typeof(MyException), View = "MyError")]
[HandleError(ExceptionType = typeof(AnotherException), View = "AnotherError")]
public class BaseController : Controller
{
}
并在/Views/Shared
文件夹中添加特定的错误视图(MyError.cshtml)
@model System.Web.Mvc.HandleErrorInfo
....
@Model.Exception.Message // display error message
...
注意HandleErrorInfo使您可以访问控制器和操作名称以及异常详细信息。
然后,在特定方法中,如果抛出异常,将显示关联的视图
public class MyController : BaseController
{
public ActionResult SomeAction()
{
if(someCondition)
{
throw new MyException("Some friendly error message");
}
return View();
}
}
MyException
是内置异常,或者您拥有源自Exception
的自定义异常
请注意,您还需要在web.config
<system.web>
<customErrors mode="On" defaultRedirect="Error" />
</system.web>
答案 1 :(得分:1)
当您在每个操作中填充Error类并且具有相同的视图时,是否需要重定向到特殊错误操作?您可以执行以下操作:
try{
DoSomeStuff();
}
except (Exception e)
{
Error error = new Error { UserFriendlyText = "The friendly message", ErrorDescription = "Error to be logged" };
return View("Error", error); //error view
}
return View(); //Default way
对于我们自己,我们选择了另一种方法来显示错误。没有特殊视图来显示错误。在这种情况下,用户将丢失发生错误的上下文。我们创建了以下结构,而不是特殊视图。
我们有BaseController,它有几个有用的功能:
protected void AddErrorMessage(String errorMessage)
{
var errorMessages = TempData["ErrorMessages"] as List<String>;
if (errorMessages == null)
errorMessages = new List<String>();
errorMessages.Add(errorMessage);
TempData["ErrorMessages"] = errorMessages;
}
protected void AddSuccessMessage(String successMessage)
{
var successMessages = TempData["SuccessMessages"] as List<String>;
if (successMessages == null)
successMessages = new List<String>();
successMessages.Add(successMessage);
TempData["SuccessMessages"] = successMessages;
}
protected void AddWarningMessage(String warningMessage)
{
var warningMessages = TempData["WarningMessages"] as List<String>;
if (warningMessages == null)
warningMessages = new List<String>();
warningMessages.Add(warningMessage);
TempData["WarningMessages"] = warningMessages;
}
我们修改了_Layout以显示这些消息:
@if (@TempData.ContainsKey("ErrorMessages"))
{
foreach (var errorMessage in TempData["ErrorMessages"] as List<String>)
{
<div class="alert alert-error">
<button type="button" class="close" data-dismiss="alert">×</button>
@(new HtmlString(errorMessage))
</div>
}
}
//The same stuff for warnings and messages
在控制器中我们按如下方式使用它:
public ActionResult CreateCustomer(客户客户) {
if (!ModelState.IsValid)
{
this.AddErrorMessage("Something wrong with your model");
return View(customer);
}
}
我们只返回相同的视图,但附加了其他消息。因此,客户可以检查问题或查看某些警告/信息消息而不会丢失上下文。
答案 2 :(得分:1)
我不想使用RedirectToAction
进行错误处理的原因之一是它会更改您正在浏览的网页的网址,这不是最好的用户体验。
最简单的方法是将Error.cshtml
移到/Views/Shared
文件夹中,并确保控制器中存在该文件并不存在错误。然后你可以这样做:
Error error = new Error { UserFriendlyText = "The friendly message", ErrorDescription = "Error to be logged" };
return RedirectToAction("Error", new System.Web.Routing.RouteValueDictionary(error));
默认情况下,它会在MVC约定中搜索&#34; Controller&#34;中的Error.cshtml
文件。目录,如果没有找到,则在Shared
目录中搜索。
如果您需要自定义该控制器的错误页面,您只需在Controller中创建一个需要自定义错误的新Error.cshtml
页面。