MVC HTML.RenderAction - ошибка: длительность должна быть положительным числом

На моем веб-сайте я хочу, чтобы у пользователя была возможность входа/выхода из любой страницы. Когда пользователь выбирает кнопку входа в систему, пользователю будет предоставлен модальный диалог, чтобы он мог ввести свои учетные данные.

Поскольку логин будет на каждой странице, я думал, что создаю частичное представление для входа и добавлю его на страницу макета. Но когда я это сделал, я получил следующую ошибку: Сведения об исключении: 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 частичное кэширование выходных данных Не соблюдение настроек конфигурации

Кэширование ChildActions с использованием профилей кеша не будет работать? Кэширование ChildActions с использованием профилей кеша не будет работать?

Я не уверен, что это имеет значение, но я продолжу и добавлю его здесь. Я использую MVC 3 с Razor.


Update
Трассировка стека

[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

Update
Когда я нарушаю код, он вызывает ошибки в @{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)

enter image description here


Ответ Спасибо Дарин Димитров

Приходите, чтобы узнать, у моего AccountController был следующий атрибут

[System.Web.Mvc.OutputCache(NoStore = true, Duration = 0, VaryByParam = "*" )].

Я не думаю, что это должно было вызвать проблему, но когда я удалил атрибут, все сработало.

BarDev

Ответы

Ответ 1

Добавление комментария в ответ:

Хм, это странно. Читая свой вопрос, я готов сделать ставку на 5 долларов, что у вас есть кеширование. Попробуйте переименовать действие, контроллер. Убедитесь, что действие, которое вы вызываете, не украшено атрибутом [OutputCache]. Попробуйте сделать это в новом проекте, который вы начинаете с нуля. Я уверен, что вы сможете сузить его.

Ответ 3

У меня возникла проблема, создав собственный атрибут 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.

Это также опубликовано в соответствующем вопросе: fooobar.com/questions/32987/...

Ответ 4

В некоторых случаях может быть целесообразно просто создать второй метод действия с отключенным кэшированием, вызываемым вашим основным действием.

    /// 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();

Затем вы можете полагаться на родительскую страницу для выполнения кэширования.


Другой способ - просто обойти все "CacheProfile" для ActionMethod и использовать мой 'DonutCacheAttribute вместо этого.

"CacheProfile" для ActionMethods в настоящее время только уважает свойства Duration и varyByParam - и этот метод упрощает настройку разных длительностей кеширования при отладке и развертывании (при условии, что вы используете преобразования XDT).