ASP.NET MVC POST方式のRedirectを実現

5424 ワード

1つ目の方法は、ASP.NET MVCでは、1つのActionから別のActionにジャンプするには、通常、「Redirect」で始まる一連の方法が使用されることを知っています.
  • Redirect
  • RedirectToAction
  • RedirectToRoute

  • とか.
    しかし、Redirectシリーズのメソッドを使用してジャンプを行う場合、デフォルトではGETメソッドが使用されます.つまり、ジャンプ要求にパラメータがある場合、これらのパラメータはすべてジャンプ後のurlに露出し、セキュリティが増加します(特にパラメータにパスワード、鍵などの機密データが含まれている場合).
    そこで,少なくとも一般の訪問者がurlから機密情報を取得できないようにPOST法でデータを伝達することを考えた.しかしMSDNとStackOverflowをよく調べてみると、「RedirectメソッドはPOSTをサポートしていない」という答えが返ってきました.
    StackOverflowで答えを見つけた  ,私にヒントを与えてくれた.直接POSTではだめです.間接POSTで、まずGET方法でページを取得し、このページを仲介してデータPOSTを本当に要求を処理するページに渡します.
    次に、サンプルコードを示します.このサンプルコードには、2つのページLoginとAfterLoginがあり、Loginにユーザー名とパスワードを入力してAfterLoginにジャンプし、UserAppModelで定義されたデータリストを携帯する必要があります.
    public class UserAppModel
    {
        public string UserId { get; set; }
        public string ClientId { get; set; }
        public string RedirectUri { get; set; }
    }

    これらの情報は、GETメソッドを使用してLoginページをロードしたときに取得されます.
    public ActionResult Login(string client_id, string redirect_uri)
    {
        HttpCookie cookie = new HttpCookie("app");
        cookie["client_id"] = client_id;
        cookie["redirect_uri"] = redirect_uri;
        Response.Cookies.Add(cookie);
        return View();
    }

    インタフェースの設計は省略され、2つのテキストボックスとsubmitボタンにほかならない.
    その後、LoginにはHttpPostメソッドが必要で、ログインデータを受信し、UserAppModelのデータを構築して新しいAfterLoginページに送信します.
    [HttpPost]
    public ActionResult Login(UserModel model)
    {
        if (ModelState.IsValid)
        {
            HttpCookie cookie = Request.Cookies["app"];
            if (cookie != null)
            {
                if (model.UserId == "AAA" && model.Password == "aaa")
                {
                    UserAppModel newModel = new UserAppModel();
                    newModel.UserId = model.UserId;
                    newModel.ClientId = cookie["client_id"];
                    newModel.RedirectUri = cookie["redirect_uri"];
    
                    TempData["model"] = newModel;
                    return RedirectToAction("AfterLogin", "Home");
    
                }
                ViewBag.Message = "Login error! Invalid user ID or password.";
            }
        }
        return View();
    }

    AfterLoginは2つの方法が必要で、1つはGET方式を採用して、1つはPOST方式を採用して、1つはGET方式のページを通じてPOST方式のページを呼び出して、POSTのリダイレクトを実現しました
    //
    // POST: /Home/AfterLogin
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult AfterLogin(UserAppModel model)
    {
        ViewData["model"] = model;
    
        return View(model);
    }
    
    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult AfterLogin()
    {
        return AfterLogin(TempData["model"] as UserAppModel);
    }

    結論:RedirectシリーズメソッドはPOSTをサポートしていないが、間接的なアプローチでPOST方式のリダイレクトを実現することができる.
    2つ目の方法:
    ASP.NET MVCを使用してページジャンプを実現する場合、よく使われるのは次のとおりです.
      ① Redirect
      ② RedirectToAction
      ③RedirectToRoute
    ④またはフロントでスクリプトを使用してジャンプします.
    しかし、これらのジャンプ方式はGetリクエストに基づいており、特定のシーンでは適用されない場合があります.たとえば、ビッグデータ量パラメータや複雑なオブジェクトタイプパラメータを渡すシーンでは、get方式に制限があるに違いありません.Webformでは、サーバー側のジャンプ方法があります.Server.Transfer、皆さんはきっと覚えていると思います.この方法では、現在のページの実行を中止し、実行プロセスを新しいページに転送し、前のページで作成した応答フローを使用します.この方法には、次のような特徴があります.
    ①アドレスバーURLは変わりません.
    ②前のページのバックグラウンドで生成されたパラメータとオブジェクトは、新しいページに直接渡すことができます.
    ③クライアントからサーバへの要求を減らす.
    ASP.NET MVCには、「コンフィギュレーションよりも約束が優れている」という核心思想があることを知っています.例えば、actionを実行した後、ビューディレクトリの下でcontroller名に基づいて対応するビューを探してレンダリングしますが、約束のやり方は変更できないという意味ではありません.
    ASP.NET MVCでは、現在のActionでレンダリングされているviewパスを動的に変更することで、同様の効果を実現できます.
    非一般パスをレンダリングするView
    まず、カスタムのViewEngineを実装します.
    public
    class
    ChangeViewEngine : System.Web.Mvc.RazorViewEngine    {        
    public
    ChangeViewEngine(
    string
    controllerPathName,
    string
    viewName)        {            this.ViewLocationFormats
    を選択します.
    new
    [] {
    "
    ~/Views/
    "

    controllerPathName

    "
    /
    "

    viewName  

    "
    .cshtml
    "
    };                    }    }
    もう一つのActionAttributeを実現
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]    
    public
    class
    ChangeViewPathAttribute : ActionFilterAttribute    {        
    private
    string
    _controllerPath;        
    private
    string
    _viewName;        
    public
    ChangeViewPathAttribute(
    string
    controllerPath,
    string
    viewName)        {            this._controllerPath
    を選択します.
    controllerPath;            this._viewName
    を選択します.
    viewName;        }        
    public
    override void OnResultExecuting(ResultExecutingContext filterContext)        {            
    //
    base.OnResultExecuting(filterContext);            
    //
    ViewEngines.Engines.Clear();                        ViewEngines.Engines.Add(
    new
    ChangeViewEngine(_controllerPath,_viewName));        }    }
    このセグメントコードでは、ChangeViewPathAttributeクラスがActionFilterに継承され、OnResultExecutingメソッドが書き換えられ、カスタムのViewEngineがグローバルViewEngineコレクションに追加されます.
    最後に、異なるパスをレンダリングするアクションにAttributeを追加します.
         [HttpPost]        [
    Filter
    .ChangeViewPath(
    "
    Invoice
    "
    ,
    "
    Create
    "
    )]        
    public
    ActionResult PreInvoice(
    string
    strIds,bool flag)
    以上の手順を完了すると、actionがレンダリングするviewを任意に指定し、サーバ側でジャンプしてServer.Transferのような効果を実現できます.もちろん、上記は簡単な例にすぎません.より優雅に、より柔軟なパス構成を実現することができます:)