web-dev-qa-db-ja.com

MVC HTML.RenderAction –エラー:期間は正の数である必要があります

私のウェブサイトでは、ユーザーがどのページからでもログイン/ログアウトできるようにしたいと思っています。ユーザーがログインボタンを選択すると、モーダルダイアログが表示され、ユーザーは資格情報を入力できます。

ログインはすべてのページにあるので、ログインの部分ビューを作成してレイアウトページに追加しようと思いました。しかし、これを行うと、次のエラーが発生しました:例外の詳細:System.InvalidOperationException:期間は正の数である必要があります。

部分的なビューを使用しないこれを回避する他の方法がありますが、これは機能するはずです。

したがって、これをテストするために、次のコードを使用してすべてを単純にすることにしました。

次のコードでレイアウトページを作成しました

@{Html.RenderAction("_Login", "Account");}

AccountControllerの場合:

public ActionResult _Login()
{
    return PartialView("_Login");
}

部分ビュー_ログイン

<a id="signin">Login</a>

しかし、この単純なバージョンを実行すると、このエラーが発生します:例外の詳細:System.InvalidOperationException:期間は正の数である必要があります。

エラーの原因は「@ {Html.RenderAction( "_ Login"、 "Account");}」を指しています。

私の問題に似た会話がWeb上にいくつかあり、これはMVCのバグとして識別されます(以下のリンクを参照)。しかし、リンクはキャッシングに関連しており、私はキャッシングを行っていません。

OuputCacheキャッシュプロファイルは子アクションでは機能しません
http://aspnet.codeplex.com/workitem/792

Asp.Net MVC 3の部分的なページ出力のキャッシュが構成設定を尊重しない Asp.Net MVC 3の部分的なページ出力のキャッシュが構成の設定を尊重しない

キャッシュプロファイルを使用してChildActionsをキャッシュしても機能しませんか? キャッシュプロファイルを使用したChildActionsのキャッシュは機能しませんか?

これが違いを生むかどうかはわかりませんが、先に進んでここに追加します。私はRazorでMVC3を使用しています。


更新
スタックトレース

[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)

enter image description here


回答ありがとうダリンディミトロフ

調べてみると、私のAccountControllerには次の属性がありました

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

これが問題を引き起こすとは思わないが、属性を削除するとすべてが機能した。

BarDev

15

答えとして私のコメントを追加する:

うーん、それは変だ。あなたの質問を読むことによって、私はあなたが何らかの方法でキャッシュを有効にしている5ドルを賭ける準備ができています。アクション、コントローラーの名前を変更してみてください。呼び出しているアクションが[OutputCache]属性で装飾されていないことを確認してください。ゼロから開始する新しいプロジェクトでこれを実行してみてください。きっと絞り込めるはずです。

17
Darin Dimitrov
3
Wayne Brantley

プロファイルからOutputCacheDuration、および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の1か所に保持できることです。

これは関連する質問にも投稿されています: https://stackoverflow.com/a/13866280/137317

2
Pablo Romeo

場合によっては、プライマリアクションによって呼び出されるキャッシュを無効にして、2番目のアクションメソッドを作成することが適切な場合があります。

    /// 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.ActionFooの代わりに_Fooを呼び出すだけです。

@Html.Action("_Foo", "Bar").ToString();

その後、親ページを使用してキャッシュを実行できます。


もう1つの方法は、ActionMethodの「CacheProfile」全体をバイパスして、代わりに my'DonutCacheAttribute ' を使用することです。

ActionMethodsの「CacheProfile」は現在、DurationプロパティとvaryByParamプロパティのみを尊重します。このメソッドを使用すると、デバッグとデプロイで異なるキャッシュ期間を簡単に設定できます(XDT変換を使用している場合)。 。

1
Simon_Weaver