C# 当控制器返回图像文件(非视图结果类型)时,为什么MVC中涉及_ViewStart?
使用ASP.NET 4.6 MVC 5,我有一个控制器操作返回gif图像(因此,不是视图),如下所示:C# 当控制器返回图像文件(非视图结果类型)时,为什么MVC中涉及_ViewStart?,c#,asp.net,asp.net-mvc,razor,C#,Asp.net,Asp.net Mvc,Razor,使用ASP.NET 4.6 MVC 5,我有一个控制器操作返回gif图像(因此,不是视图),如下所示: [Route("Content/Images/GetThatGifImage.gif", Name = "Get the gif image")] public ActionResult GetThatGif() { // Some logic here... return new FilePathResult("TheGifImage.gif", "image/gif")
[Route("Content/Images/GetThatGifImage.gif", Name = "Get the gif image")]
public ActionResult GetThatGif()
{
// Some logic here...
return new FilePathResult("TheGifImage.gif", "image/gif"));
}
@{
Layout = "~/Views/Shared/TheLayout.cshtml";
}
at ASP._Page_Views_Shared_TheLayout_cshtml.Execute() in c:\inetpub\ewp\Views\Shared\TheLayout.cshtml:line 81
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy()
at System.Web.Mvc.WebViewPage.ExecutePageHierarchy()
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
at System.Web.WebPages.WebPageBase.<>c__DisplayClass3.<RenderPageCore>b__2(TextWriter writer)
at System.Web.WebPages.WebPageBase.Write(HelperResult result)
at System.Web.WebPages.WebPageBase.RenderSurrounding(String partialViewName, Action`1 body)
at System.Web.WebPages.WebPageBase.PopContext()
at StackExchange.Profiling.Mvc.WrappedView.Render(ViewContext viewContext, TextWriter writer)
at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
同时,我有一个\u ViewStart.cshtml
只做一件事:为应用程序中的所有视图定义布局。看起来像这样:
[Route("Content/Images/GetThatGifImage.gif", Name = "Get the gif image")]
public ActionResult GetThatGif()
{
// Some logic here...
return new FilePathResult("TheGifImage.gif", "image/gif"));
}
@{
Layout = "~/Views/Shared/TheLayout.cshtml";
}
at ASP._Page_Views_Shared_TheLayout_cshtml.Execute() in c:\inetpub\ewp\Views\Shared\TheLayout.cshtml:line 81
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy()
at System.Web.Mvc.WebViewPage.ExecutePageHierarchy()
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
at System.Web.WebPages.WebPageBase.<>c__DisplayClass3.<RenderPageCore>b__2(TextWriter writer)
at System.Web.WebPages.WebPageBase.Write(HelperResult result)
at System.Web.WebPages.WebPageBase.RenderSurrounding(String partialViewName, Action`1 body)
at System.Web.WebPages.WebPageBase.PopContext()
at StackExchange.Profiling.Mvc.WrappedView.Render(ViewContext viewContext, TextWriter writer)
at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
TheLayout.cshtml
包含需要设置某个ViewBag
属性的代码,否则它会正确抛出NullReferenceException
据我所知,如果控制器返回的类型不是ViewResult
,则不应以任何方式涉及\u ViewStart.cshtml
。对吧?
但是,当访问者请求Content/Images/gethatgigimage.gif
时,他们常常会被异常捕获,并得到500内部服务器错误
。有趣的是,无论我怎么努力,我自己都无法重现这个错误。我可以在IIS服务器上的事件日志中看到访问者遇到的错误。这似乎是武断的,不是每一个请求都会发生。事件日志中的堆栈跟踪如下所示:
[Route("Content/Images/GetThatGifImage.gif", Name = "Get the gif image")]
public ActionResult GetThatGif()
{
// Some logic here...
return new FilePathResult("TheGifImage.gif", "image/gif"));
}
@{
Layout = "~/Views/Shared/TheLayout.cshtml";
}
at ASP._Page_Views_Shared_TheLayout_cshtml.Execute() in c:\inetpub\ewp\Views\Shared\TheLayout.cshtml:line 81
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy()
at System.Web.Mvc.WebViewPage.ExecutePageHierarchy()
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
at System.Web.WebPages.WebPageBase.<>c__DisplayClass3.<RenderPageCore>b__2(TextWriter writer)
at System.Web.WebPages.WebPageBase.Write(HelperResult result)
at System.Web.WebPages.WebPageBase.RenderSurrounding(String partialViewName, Action`1 body)
at System.Web.WebPages.WebPageBase.PopContext()
at StackExchange.Profiling.Mvc.WrappedView.Render(ViewContext viewContext, TextWriter writer)
at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
最后,我的问题总结如下:
\u ViewStart
文件)谢谢你的帮助 我发现了这个bug,是的,它是我的:/ 该操作有一个自定义操作筛选器(
OnActionExecuting
),用于从cookie中读取值。这很尴尬,但在获取值之前,我没有检查cookie是否为null(cookie缺失)。因此,当cookie丢失时,它抛出一个NullReferenceException
。(我无法再现错误,因为在我的环境中设置了cookie。)
我仍然不明白为什么layout.cshtml(通过
\u ViewStart.cshtml
)会牵涉进来,给我一些误导性的错误信息。可能是因为第一个未处理的异常(我的bug)以某种方式将结果类型切换为ViewResult
。毕竟这个动作即将显示一种“视图”,即ASP.NET死亡黄屏(YSOD)。也许它与线程有关,就像@Robert McKee建议的那样。似乎只有在customErrors mode=“RemoteOnly”
时才会发生这种情况。如果我切换到customErrors mode=“Off”
我会得到正确的错误信息。(我没有进一步探讨这最后一点,所以我不确定。)只是一个粗略的猜测,但是您有一个异步调用,它抛出了一个错误,没有被捕获,并且带来的不仅仅是它本身。关闭托管在同一线程上的其他无关调用。