ASP.NET MVC POST方式のRedirectを実現
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で定義されたデータリストを携帯する必要があります.
これらの情報は、GETメソッドを使用してLoginページをロードしたときに取得されます.
インタフェースの設計は省略され、2つのテキストボックスとsubmitボタンにほかならない.
その後、LoginにはHttpPostメソッドが必要で、ログインデータを受信し、UserAppModelのデータを構築して新しいAfterLoginページに送信します.
AfterLoginは2つの方法が必要で、1つはGET方式を採用して、1つはPOST方式を採用して、1つはGET方式のページを通じてPOST方式のページを呼び出して、POSTのリダイレクトを実現しました
結論: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のような効果を実現できます.もちろん、上記は簡単な例にすぎません.より優雅に、より柔軟なパス構成を実現することができます:)
とか.
しかし、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のような効果を実現できます.もちろん、上記は簡単な例にすぎません.より優雅に、より柔軟なパス構成を実現することができます:)