Asp.net mvc 如何在ASP.NET MVC中实现自己的错误视图

Asp.net mvc 如何在ASP.NET MVC中实现自己的错误视图,asp.net-mvc,error-handling,Asp.net Mvc,Error Handling,在我的ASP.NET MVC应用程序中,我有一个ErrorController,目前只有一个action方法,该方法接收名为Error的自定义类,并将其呈现到名为Error.cshtml的视图中。目前,Error类中只有两个属性: public class Error{ public string UserFriendlyMmessage{get;set;} public string ErrorMessage{get;set;} } Error.cshtml视图是Error类的强

在我的ASP.NET MVC应用程序中,我有一个ErrorController,目前只有一个action方法,该方法接收名为Error的自定义类,并将其呈现到名为Error.cshtml的视图中。目前,Error类中只有两个属性:

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));
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
下面是ErrorController的操作方法:

    public ActionResult Index(Error error)
    {
        return View(model: error, viewName:"Error");
    }

虽然这样做效果很好,但通过这种方式,所有模型属性都显示在url中。是否有更好、更常用的方法来执行此操作?

当您在每个操作中填充错误类并具有相同视图时,是否需要重定向到特殊错误操作?您可以只执行以下操作:

Error error = new Error { UserFriendlyText = "The friendly message", ErrorDescription = "Error to be logged" };
return RedirectToAction("Index", "Error", new System.Web.Routing.RouteValueDictionary(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;
    }
    
    }


  • 我们只返回相同的视图,但包含其他消息。因此,客户可以在不丢失上下文的情况下检查问题或看到一些警告/信息消息。

    当您在每个操作中填充错误类并具有相同视图时,是否需要重定向到特殊错误操作?您可以只执行以下操作:

    Error error = new Error { UserFriendlyText = "The friendly message", ErrorDescription = "Error to be logged" };
    return RedirectToAction("Index", "Error", new System.Web.Routing.RouteValueDictionary(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;
    }
    
    }


  • 我们只返回相同的视图,但包含其他消息。因此,客户可以在不丢失上下文的情况下检查问题或看到一些警告/信息消息。

    除了难看的查询字符串外,您还可能面临超出查询字符串限制的风险,特别是如果您的消息很长并且您向
    错误添加了更多属性时

    一个选项是将
    Error
    持久化为
    TempData
    属性,然后
    返回RedirectToAction(“Index”,“Error”)
    ,并在
    Index()
    方法中从
    TempData
    获取值并呈现视图

    另一个选项是使用该属性根据特定异常渲染视图。比如说

    [HandleError(ExceptionType = typeof(MyException), View = "MyError")]
    [HandleError(ExceptionType = typeof(AnotherException), View = "AnotherError")]
    public class BaseController : Controller
    {
    }
    
    /Views/Shared
    文件夹中,添加特定的错误视图(MyError.cshtml)

    注意:允许您访问控制器和操作名称以及异常详细信息

    然后,在特定方法中,如果抛出异常,将显示关联的视图

    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>
    

    除了丑陋的查询字符串外,您还面临着超出查询字符串限制的风险,特别是如果您的消息很长,并且您向
    错误添加了更多属性时

    一个选项是将
    Error
    持久化为
    TempData
    属性,然后
    返回RedirectToAction(“Index”,“Error”)
    ,并在
    Index()
    方法中从
    TempData
    获取值并呈现视图

    另一个选项是使用该属性根据特定异常渲染视图。比如说

    [HandleError(ExceptionType = typeof(MyException), View = "MyError")]
    [HandleError(ExceptionType = typeof(AnotherException), View = "AnotherError")]
    public class BaseController : Controller
    {
    }
    
    /Views/Shared
    文件夹中,添加特定的错误视图(MyError.cshtml)

    注意:允许您访问控制器和操作名称以及异常详细信息

    然后,在特定方法中,如果抛出异常,将显示关联的视图

    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>
    

    我不喜欢使用
    重定向操作
    进行错误处理的原因之一是它会更改您正在浏览的页面的url,这不是最佳的用户体验

    最简单的方法是将
    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约定,它将在“Controller”目录中搜索
    Error.cshtml
    文件,如果找不到该文件,则在
    Shared
    目录中搜索


    如果您需要自定义该控制器的错误页面,只需在需要自定义错误的控制器内创建一个新的
    error.cshtml
    页面。

    我不喜欢使用
    重定向到操作
    进行错误处理的原因之一是它会更改您正在浏览的页面的url,这不是最好的用户体验

    最简单的方法是将
    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约定,它将在“Controller”目录中搜索
    Error.cshtml
    文件,如果找不到该文件,则在
    Shared
    目录中搜索


    如果您需要自定义该控制器的错误页面,只需在需要自定义错误的控制器内创建一个新的
    error.cshtml
    页面。

    当错误发生时,您可以将
    error
    分配给
    TempData
    属性,然后
    返回重定向到操作(“索引”,“错误”)
    并在
    Index()
    方法中从
    Tempdata
    中获取值并渲染视图。是的,我确实可以这样做吗?但也许还有另外一种方法?人们甚至会这样做吗