是否可以重定向到MVC中的非控制器类进行查看

时间:2016-08-15 00:00:10

标签: c# asp.net-mvc

正在使用NLOG进行日志记录,并且在日志记录发生的地方有单独的类@ global级别。每个要求,必须在记录结束后从该类重定向到“错误”视图(RedirectToAction())。

但它是一个非控制器类,因此无法使用return View("Error")Response.Redirect()等常用方法。

有可能做到这一点吗?我试过HttpContext.Current.Response.Redirect("/Help/Error",true); 但没有做任何事情。

Error.cshtml

Views/Shared/*是一个简单的HTML文件,其文本类似于有一些错误...请与logging文件夹下的管理员联系。

记录类存在于根文件夹下的Result.body单独文件夹中。

每次调用Action方法时,如果发生任何异常,则会自动调用记录器,这会记录日志,最后应重定向到错误视图。

2 个答案:

答案 0 :(得分:2)

您可以创建自己的基本控制器并处理onexception事件中的异常

public class BaseController : Controller
{
    protected override void OnException(ExceptionContext filterContext)
    {
       //Do your logging
       // and redirect / return error view
        filterContext.ExceptionHandled = true;
        // If the exception occured in an ajax call. Send a json response back
        // (you need to parse this and display to user as needed at client side)
        if (filterContext.HttpContext.Request.Headers["X-Requested-With"]=="XMLHttpRequest")
        {
            filterContext.Result = new JsonResult
            {
                JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                Data = new { Error = true, Message = filterContext.Exception.Message }
            };
            filterContext.HttpContext.Response.StatusCode = 500; // Set as needed
        }
        else
        {
            filterContext.Result = new ViewResult { ViewName = "Error.cshtml" }; 
            //Assuming the view exists in the "~/Views/Shared" folder
        }
    }
}

现在,对于其他控制器,继承此bascontroller。

public class ProductsController : BaseController 
{
   public ActionResult Die()
   {
     throw new Exception("I lost!");
   }
}

如果要对Error操作方法进行重定向(新的GET调用),可以将ViewResult替换为RedirectToRouteResult

filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary {
                                               {"controller", "Home"}, {"action", "Error"}
                                              };

答案 1 :(得分:1)

您没有说明如何自动调用日志记录代码"记录器会自动调用"。所以我将推荐一个HandleErrorAttribute。这要求您在共享视图文件夹中有一个Error.cshtml,但您可以在filterContext.Result中指定一个不同的视图

public class CustomErrorAttribute : HandleErrorAttribute 
{

    public override void OnException(ExceptionContext filterContext)
    {
        filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;// This causes the webconfig httpErrors section to be ignored, since we are handling the exception
        filterContext.ExceptionHandled = true;

        //... log error

        filterContext.HttpContext.Response.ClearContent();// Removes partially rendered content

        // just information to be passed in the view model, this does NOT define which view is displayed next.  It tells us where the error came from.
        var controllerName = (string)filterContext.RouteData.Values["controller"];
        var actionName = (string)filterContext.RouteData.Values["action"];
        var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
        // This presents an error page view.  By default if a View is not passed to the Attribute, then this is Error.cshtml in Shared.
        filterContext.Result = new ViewResult
        {
            ViewName = View,  // View & Master are parameters from the attribute e.g. [ErrorAttribute(View="OtherErrorView")], by default the view is the "Error.cshtml" view
            MasterName = Master,
            ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
            TempData = filterContext.Controller.TempData
        };

        filterContext.Exception = null;


    }
}
相关问题