web-dev-qa-db-ja.com

ASP.NET MVCログインReturnUrlは常にNULLですか?

サイトに再度ログインするときにASP.NET MVCでフォーム認証を使用すると、クエリ文字列にReturnUrlパラメーターが設定されます。ログオンアクションメソッドは「returnUrl」文字列を受け入れます。ただし、クエリ文字列に明確に含まれている場合でも、returnUrl文字列は常にnullのようです。なぜそうなのか、修正の可能性があるのか​​についての考えはありますか?

56
aherrick

おそらく、ログインフォームのアクション属性にReturnURLパラメーターを含めないので、そのパラメーターなしでURLに投稿しますか?

24
Çağdaş Tekin

これは、1つの汎用ログオンフォームを使用している場合に発生する傾向がありますが、ControllerとActionMethodを明示的に指定している(フォームポストは発生しますが、クエリ文字列は失われます)

明確にするために、これはBeginFormでのコードの外観です。

Html.BeginForm("LogOn", "Account", new { ReturnUrl = Request.QueryString["ReturnUrl"] })

[〜#〜] edit [〜#〜]これはRickAndが以下のコメントで言及しているように設計によるものです。ただし、匿名ユーザーが許可されている場合、サイトの奥深くにある[ログオン]をクリックし、以前に表示していたページに戻るというUIパターンは許可されません。これは一般的に要求されるパターンです。 LogOffへのDavid Allenのアプローチは、LogOnでのクリーンリダイレクトに対してもうまく機能します。

120
davewasthere

基本的に、Asp.net MVCにはいくつかの隠された機能があります。たとえば、変数 'id'をコントローラーアクションに渡すと、 'id'が既定の識別子として解釈され、フォアスラッシュを使用してブラウザークエリに配置されます。'id 'の代わりに別の名前を使用すると、'? 'フォアスラッシュではなく。 global.asaxファイルのRegisterRoutesメソッドに 'id'名を設定するため。

この問題では、次のコードを使用してコントローラーへのカスタムデータの受け渡しを作成しました。

using(Html.BeginForm("LogOn", "Account", FormMethod.Post))
{
//form fields
}

そのため、Asp.net MVCは、コントローラーアクションに渡す他の有用なデータを無視し、returnUrlが常にnullと表示されます。

一方、これを使用すると、Asp.net MVCが正しく動作し、returnUrlがマウントされます。

using(Html.BeginForm())
{
//form fields in LogOn View
}

ところで、コントローラーアクションにカスタムデータパサーを使用する場合、次のように別のデータを渡す必要があります手動

using(Html.BeginForm("LogOn", "Account", new {ReturnUrl = Request.QueryString["ReturnUrl"] }))
{
//form fields
}

ログオンとログオフのシナリオに対処するには、2つの方法が考えられます。 Dave Beerは上記の1つの方法を概説しました。多くの状況で機能する別のアプローチがあります。 NerdDinnerチュートリアルをコーディングしたときに使用しました。このチュートリアルでは、ログオフ機能を提供し、ログオフして家に帰ります。私はそれを望んでいませんでした。ログオフする前に表示していたページに戻りたいと思いました。そこで、アカウントコントローラーのログオフアクションを次のように変更しました

   public ActionResult LogOff()
    {
        FormsService.SignOut();
        return Redirect(Request.UrlReferrer.ToString());
    }

この振る舞いをオーバーライドしたい場合は、より洗練されたreturnUrlを渡してテストすることができます。しかし、私はそれを必要としません。これにより、目的の結果が得られます。ログオンも同様に機能します。 MVCフレームワークを使用してこれを行う方法があるかもしれませんが、それらを学ぶまで、これは非常に簡単で、確実に機能します。

3
David Allen

以下を試してください:

        public static MvcForm BeginForm(this HtmlHelper htmlHelper, string id)
    {
        string formAction = htmlHelper.ViewContext.HttpContext.Request.RawUrl;

        TagBuilder tagBuilder = new TagBuilder("form");

        tagBuilder.MergeAttribute("id", id);
        tagBuilder.MergeAttribute("action", formAction);
        tagBuilder.MergeAttribute("method", HtmlHelper.GetFormMethodString(FormMethod.Post), true);

        HttpResponseBase httpResponse = htmlHelper.ViewContext.HttpContext.Response;
        httpResponse.Write(tagBuilder.ToString(TagRenderMode.StartTag));

        return new MvcForm(htmlHelper.ViewContext.HttpContext.Response);
    }

最初にweb.configでログインURLを設定したことを確認し、次に、サインインフォームにアクションなどの何かが含まれていないことを確認します。次に例を示します。

見る:

アクションを指定すると、戻りURLに対して常にnullが取得されます。

コントローラ:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SignIn(string userName, string password, bool? rememberMe, string returnUrl)
{
}
1