在我的网站上,我希望用户能够从任何页面登录/注销。当用户选择登录按钮时,将向用户显示模态对话框,供他输入他的凭证。
由于登录将在每个页面上,我想我会为登录创建一个局部视图并将其添加到布局页面。但是当我这样做时,我收到以下错误:异常详细信息:System.InvalidOperationException:持续时间必须是正数。
还有其他方法可以解决这个问题,不会使用部分视图,但我相信这应该可行。
因此,为了测试这一点,我决定使用以下代码使一切变得简单:
使用以下代码
创建布局页面@{Html.RenderAction("_Login", "Account");}
在AccountController中:
public ActionResult _Login()
{
return PartialView("_Login");
}
部分查看_Login
<a id="signin">Login</a>
但是当我运行这个简单的版本时,我仍然会收到此错误: 异常详细信息:System.InvalidOperationException:持续时间必须为正数。
错误来源指向“@ {Html.RenderAction(”_ Login“,”Account“);}”
网上有一些类似于我的问题的对话,它将此识别为MVC的错误(请参阅下面的链接)。但链接与缓存有关,我没有做任何缓存。
OuputCache缓存配置文件不适用于子操作
http://aspnet.codeplex.com/workitem/7923
Asp.Net MVC 3部分页面输出缓存不符合配置设置 Asp.Net MVC 3 Partial Page Output Caching Not Honoring Config Settings
使用缓存配置文件缓存ChildActions不起作用? Caching ChildActions using cache profiles won't work?
我不确定这是否有所作为,但我会继续将其添加到此处。我正在使用带有Razor的MVC 3。
更新
堆栈跟踪
[InvalidOperationException: Duration must be a positive number.]
System.Web.Mvc.OutputCacheAttribute.ValidateChildActionConfiguration() +624394
System.Web.Mvc.OutputCacheAttribute.OnActionExecuting(ActionExecutingContext filterContext) +127
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +72
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +784922
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +314
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +784976
System.Web.Mvc.Controller.ExecuteCore() +159
System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +335
System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +62
System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +20
System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +54
System.Web.Mvc.<>c__DisplayClass4.<Wrap>b__3() +15
System.Web.Mvc.ServerExecuteHttpHandlerWrapper.Wrap(Func`1 func) +41
System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride) +1363
[HttpException (0x80004005): Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'.]
System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride) +2419
System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage) +275
System.Web.HttpServerUtilityWrapper.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm) +94
System.Web.Mvc.Html.ChildActionExtensions.ActionHelper(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues, TextWriter textWriter) +838
System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues) +56
ASP._Page_Views_Shared_SiteLayout_cshtml.Execute() in c:\Projects\prj Projects\prj\Source\Presentation\prj.PublicWebSite\Views\Shared\SiteLayout.cshtml:80
System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +280
System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +104
System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +173
System.Web.WebPages.WebPageBase.Write(HelperResult result) +89
System.Web.WebPages.WebPageBase.RenderSurrounding(String partialViewName, Action`1 body) +234
System.Web.WebPages.WebPageBase.PopContext() +234
System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +384
System.Web.Mvc.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19() +33
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +784900
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +784900
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +265
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +784976
System.Web.Mvc.Controller.ExecuteCore() +159
System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +335
System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +62
System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +20
System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +54
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +453
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +371
更新
当我在代码中断时,它在@ {Html.RenderAction(“_ Login”,“Account”);}处出现错误,但有以下异常。内部异常
Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'.
at System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride)
at System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage)
at System.Web.HttpServerUtilityWrapper.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm)
at System.Web.Mvc.Html.ChildActionExtensions.ActionHelper(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues, TextWriter textWriter)
at System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues)
at ASP._Page_Views_Shared_SiteLayout_cshtml.Execute() in c:\Projects\prj Projects\prj\Source\Presentation\prj.PublicWebSite\Views\Shared\SiteLayout.cshtml:line 80
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.Write(HelperResult result)
at System.Web.WebPages.WebPageBase.RenderSurrounding(String partialViewName, Action`1 body)
at System.Web.WebPages.WebPageBase.PopContext()
at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)
答案 谢谢Darin Dimitrov
快来找出,我的AccountController有以下属性
[System.Web.Mvc.OutputCache(NoStore = true,Duration = 0,VaryByParam =“*”)]。
我不相信这会导致问题,但是当我删除属性时一切正常。
BarDev
答案 0 :(得分:17)
将我的评论添加为答案:
嗯,这很奇怪。通过阅读你的问题,我准备下注5块钱你已经以某种方式启用了缓存。尝试重命名动作,控制器。确保您调用的操作未使用[OutputCache]
属性进行修饰。尝试在一个从头开始的新项目中执行此操作。我相信你能缩小范围。
答案 1 :(得分:3)
答案 2 :(得分:2)
我通过创建自定义OutputCache
属性解决了这个问题,该属性从个人资料中手动加载Duration
,VarByCustom
和VarByParam
:
public class ChildActionOutputCacheAttribute : OutputCacheAttribute
{
public ChildActionOutputCacheAttribute(string cacheProfile)
{
var settings = (OutputCacheSettingsSection)WebConfigurationManager.GetSection("system.web/caching/outputCacheSettings");
var profile = settings.OutputCacheProfiles[cacheProfile];
Duration = profile.Duration;
VaryByParam = profile.VaryByParam;
VaryByCustom = profile.VaryByCustom;
}
}
这种方法的优点是您可以将所有配置文件保留在web.config中的一个位置。
这也发布在相关问题中:https://stackoverflow.com/a/13866280/1373170
答案 3 :(得分:1)
在某些情况下,可能只需创建第二个操作方法,并禁用主要操作调用的缓存。
/// Use this for normal HTTP requests which need to be cached
[OutputCache(CacheProfile = "Script")]
public ContentResult Foo(string id)
{
return _Foo(id);
}
/// Use this for Html.Action
public ContentResult _Foo(string id)
{
return View();
}
当你需要Html.Action
时,你只需要调用_Foo而不是Foo。
@Html.Action("_Foo", "Bar").ToString();
然后,您可以依赖父页面进行缓存。
另一种方法是绕过ActionMethod的整个'CacheProfile'并改为使用my 'DonutCacheAttribute'。
ActionMethods的'CacheProfile'目前仅尊重Duration
和varyByParam
属性 - 这种方法可以在调试与部署中轻松设置不同的缓存持续时间(假设您正在使用XDT转换) )。