MVCでのChildActionOnlyの使用


回答:


161

このChildActionOnly属性により、アクションメソッドはビュー内から子メソッドとしてのみ呼び出すことができます。アクションメソッドは、この属性を子アクションとして使用する必要はありませんが、ユーザーの要求の結果としてアクションメソッドが呼び出されないようにするために、この属性を使用する傾向があります。アクションメソッドを定義したら、アクションが呼び出されたときにレンダリングされるものを作成する必要があります。子のアクションは通常、部分的なビューに関連付けられていますが、これは必須ではありません。

  1. [ChildActionOnly]ビューのコードを介した制限付きアクセスを許可

  2. 特定のページURLの状態情報の実装。例:支払いページのURL(1回のみ支払う)かみそりの構文により、特定のアクションを条件付きで呼び出すことができます


ビューでの使用例:<%Html.RenderAction( "MyChildAction"、 "MyController"); %>。したがって、GETとルーティングを使用して子アクションを呼び出すことはできません
Erik Bergstedt 2013年

12
コード例:@ Clark-Kent // 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を直接防止しますが、別のコントローラー/アクション内からのみです。可能性が高い:_部分的なビュー。
ランゲレッペル2013

1
InvalidOperationExceptionマークされたメソッド<ChildActionOnly>がブラウザを介して呼び出されたときにを最も適切にキャッチする方法は?
BernhardDöbler、2014

@ Html.Actionを使用する必要があった:)
chris c

125

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

私はこの説明は、「フルストップ」だったと思う、感謝の男性
TAHA SULTAN TEMURI

しかし、それを使用してNonActionも達成できますが、どのような違いがありますか?
Imad

74

RenderActionいずれかのビューで使用している場合、通常は部分ビューをレンダリングするために使用します。

でマークする理由[ChildActionOnly]は、それを呼び出すことができるようにコントローラーメソッドをパブリックにする必要があるRenderActionが、誰かがURL(例:/ Controller / SomeChildAction)に移動してその結果を表示できるようにしたくないためです。直接アクション。


2
[NonAction]に似ています。それは...ですか?では、違いは何ですか?
DarthVader 2012年

10
@DarthVader-同様ですが、[NonAction]を使用すると、RenderActionどちらを使用しても呼び出すことができません
Eric Petroelje

@EricPetroelje:NonActionAttribute実際のプロジェクトのようにアクションメソッドをマークするメリットは何ですか?
wuhcwdc 2013年

1
@Pankaj-正直なところ、本当に良い理由は考えられません。コントローラのメソッドにURL経由でアクセスしたくない場合は、メソッドprivateまたはを作成するのが最善の解決策protectedです。あなたは、コントローラのメソッドを作成する理由私は本当に何か良い理由を考えることができないpublicあなたが直接または経由でそれを呼び出すことができるようしたい場合を除いてRenderAction
エリックPetroelje

@Eric:計算のために小さなコードを記述する必要がある場合があります。そのため、それがコントローラーで公開されている場合は、URLからアクセスできます。URLでまったくアクセスしたくない場合は、[NonAction ]
Ali Adravi 2014


8

パーティーには少し遅れますが...

他の答えは、[ChildActionOnly]属性がどのような影響を与えるかをうまく説明しています。ただし、ほとんどの例で@Html.Partial("_MyParialView")は、ビューに直接レンダリングするだけの場合に、別のビュー内の部分ビューをレンダリングするためだけに新しいアクションメソッドを作成する理由を自問し続けました。不要なレイヤーのように見えました。しかし、調査したところ、1つの利点は、子アクションが別のモデルを作成し、それを部分ビューに渡すことができることです。部分ビューに必要なモデルは、部分ビューがレンダリングされているビューのモデルでは使用できない場合があります。モデル構造を変更して、部分的なビューをレンダリングするためだけに必要なオブジェクト/プロパティを取得する代わりに、子アクションを呼び出して、アクションメソッドに部分的なビューに必要なモデルの作成を処理させることができます。

これは、たとえばで役立ち_Layout.cshtmlます。すべてのページに共通するいくつかのプロパティがある場合、これを実現する1つの方法は、ベースビューモデルを使用し、他のすべてのビューモデルにそれを継承させることです。次に、は_Layoutベースビューモデルと共通のプロパティを使用できます。欠点(主観的)は、すべてのビューモデルがベースビューモデルを継承して、これらの共通プロパティが常に利用可能であることを保証する必要があることです。代替手段は@Html.Action、これらの一般的な場所でレンダリングすることです。アクションメソッドは、すべてのページに共通の部分ビューに必要な個別のモデルを作成しますが、「メイン」ビューのモデルには影響しません。この代替案では、_Layoutページにモデルがなくてもかまいません。したがって、他のすべてのビューモデルは、ベースビューモデルから継承する必要はありません。

[ChildActionOnly]属性を使用する理由は他にもあると思いますが、これは私には良いもののように思えるので、共有したいと思いました。


1
別の利点は、部分的な呼び出しがアクションの呼び出しにラップされている場合、それにキャッシュ属性を追加できることです。
kamgman

0
    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 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.