いつ属性を使用しますChildActionOnly
か?ChildAction
この属性を使用してアクションを制限する必要があるのはどのような状況ですか?
いつ属性を使用しますChildActionOnly
か?ChildAction
この属性を使用してアクションを制限する必要があるのはどのような状況ですか?
回答:
このChildActionOnly
属性により、アクションメソッドはビュー内から子メソッドとしてのみ呼び出すことができます。アクションメソッドは、この属性を子アクションとして使用する必要はありませんが、ユーザーの要求の結果としてアクションメソッドが呼び出されないようにするために、この属性を使用する傾向があります。アクションメソッドを定義したら、アクションが呼び出されたときにレンダリングされるものを作成する必要があります。子のアクションは通常、部分的なビューに関連付けられていますが、これは必須ではありません。
[ChildActionOnly]ビューのコードを介した制限付きアクセスを許可
特定のページURLの状態情報の実装。例:支払いページのURL(1回のみ支払う)かみそりの構文により、特定のアクションを条件付きで呼び出すことができます
// example from Music Store // GET: /ShoppingCart/CartSummary [ChildActionOnly] public ActionResult CartSummary() { // your stuff } /ShoppingCart/CartSummary will return "The action 'CartSummary' is accessible only by a child request."
したがって、特定のコントローラーへのGETを直接防止しますが、別のコントローラー/アクション内からのみです。可能性が高い:_部分的なビュー。
InvalidOperationException
マークされたメソッド<ChildActionOnly>
がブラウザを介して呼び出されたときにを最も適切にキャッチする方法は?
で [ChildActionOnly]注釈付き属性、アクションメソッドは、唯一のビュー内からの子メソッドとして呼び出すことができます。[ChildActionOnly]の例を次に示します。。
2つのアクションメソッドがあります:Index()とMyDateTime()および対応するビュー:Index.cshtmlとMyDateTime.cshtml。これはHomeController.csです
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "This is from Index()";
var model = DateTime.Now;
return View(model);
}
[ChildActionOnly]
public PartialViewResult MyDateTime()
{
ViewBag.Message = "This is from MyDateTime()";
var model = DateTime.Now;
return PartialView(model);
}
}
これがIndex.cshtmlのビューです。
@model DateTime
@{
ViewBag.Title = "Index";
}
<h2>
Index</h2>
<div>
This is the index view for Home : @Model.ToLongTimeString()
</div>
<div>
@Html.Action("MyDateTime") // Calling the partial view: MyDateTime().
</div>
<div>
@ViewBag.Message
</div>
これがMyDateTime.cshtmlの部分ビューです。
@model DateTime
<p>
This is the child action result: @Model.ToLongTimeString()
<br />
@ViewBag.Message
</p>
アプリケーションを実行してこの要求を行うと、http:// localhost:57803 / home / mydatetime 結果は次のようなサーバーエラーになります。
つまり、部分ビューを直接呼び出すことはできません。ただし、Index.cshtmlのように、Index()ビューを介して呼び出すことができます。
@ Html.Action( "MyDateTime")//部分ビューを呼び出す:MyDateTime()
[ChildActionOnly]を削除して同じリクエストhttp:// localhost:57803 / home / mydatetimeを実行すると、mydatetime部分ビューの結果を取得できます。
This is the child action result. 12:53:31 PM
This is from MyDateTime()
NonAction
も達成できますが、どのような違いがありますか?
RenderAction
いずれかのビューで使用している場合、通常は部分ビューをレンダリングするために使用します。
でマークする理由[ChildActionOnly]
は、それを呼び出すことができるようにコントローラーメソッドをパブリックにする必要があるRenderAction
が、誰かがURL(例:/ Controller / SomeChildAction)に移動してその結果を表示できるようにしたくないためです。直接アクション。
RenderAction
どちらを使用しても呼び出すことができません
NonActionAttribute
実際のプロジェクトのようにアクションメソッドをマークするメリットは何ですか?
private
またはを作成するのが最善の解決策protected
です。あなたは、コントローラのメソッドを作成する理由私は本当に何か良い理由を考えることができないpublic
あなたが直接または経由でそれを呼び出すことができるようしたい場合を除いてRenderAction
パーティーには少し遅れますが...
他の答えは、[ChildActionOnly]
属性がどのような影響を与えるかをうまく説明しています。ただし、ほとんどの例で@Html.Partial("_MyParialView")
は、ビューに直接レンダリングするだけの場合に、別のビュー内の部分ビューをレンダリングするためだけに新しいアクションメソッドを作成する理由を自問し続けました。不要なレイヤーのように見えました。しかし、調査したところ、1つの利点は、子アクションが別のモデルを作成し、それを部分ビューに渡すことができることです。部分ビューに必要なモデルは、部分ビューがレンダリングされているビューのモデルでは使用できない場合があります。モデル構造を変更して、部分的なビューをレンダリングするためだけに必要なオブジェクト/プロパティを取得する代わりに、子アクションを呼び出して、アクションメソッドに部分的なビューに必要なモデルの作成を処理させることができます。
これは、たとえばで役立ち_Layout.cshtml
ます。すべてのページに共通するいくつかのプロパティがある場合、これを実現する1つの方法は、ベースビューモデルを使用し、他のすべてのビューモデルにそれを継承させることです。次に、は_Layout
ベースビューモデルと共通のプロパティを使用できます。欠点(主観的)は、すべてのビューモデルがベースビューモデルを継承して、これらの共通プロパティが常に利用可能であることを保証する必要があることです。代替手段は@Html.Action
、これらの一般的な場所でレンダリングすることです。アクションメソッドは、すべてのページに共通の部分ビューに必要な個別のモデルを作成しますが、「メイン」ビューのモデルには影響しません。この代替案では、_Layout
ページにモデルがなくてもかまいません。したがって、他のすべてのビューモデルは、ベースビューモデルから継承する必要はありません。
[ChildActionOnly]
属性を使用する理由は他にもあると思いますが、これは私には良いもののように思えるので、共有したいと思いました。
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.TempValue = "Index Action called at HomeController";
return View();
}
[ChildActionOnly]
public ActionResult ChildAction(string param)
{
ViewBag.Message = "Child Action called. " + param;
return View();
}
}
The code is initially invoking an Index action that in turn returns two Index views and at the View level it calls the ChildAction named “ChildAction”.
@{
ViewBag.Title = "Index";
}
<h2>
Index
</h2>
<!DOCTYPE html>
<html>
<head>
<title>Error</title>
</head>
<body>
<ul>
<li>
@ViewBag.TempValue
</li>
<li>@ViewBag.OnExceptionError</li>
@*<li>@{Html.RenderAction("ChildAction", new { param = "first" });}</li>@**@
@Html.Action("ChildAction", "Home", new { param = "first" })
</ul>
</body>
</html>
Copy and paste the code to see the result .thanks