C# 在 MVC 中使用 ChildActionOnly

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10253769/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 13:03:32  来源:igfitidea点击:

Using ChildActionOnly in MVC

c#asp.net-mvc

提问by Rafael Carvalho

When would you use the attribute ChildActionOnly? What is a ChildActionand in what circumstance would you want restrict an action using this attribute?

ChildActionOnly什么时候会使用这个属性?什么是 aChildAction以及在什么情况下您希望使用此属性限制操作?

采纳答案by Tomasz Jaskuλa

The ChildActionOnlyattribute ensures that an action method can be called only as a child method from within a view. An action method doesn't need to have this attribute to be used as a child action, but we tend to use this attribute to prevent the action methods from being invoked as a result of a user request. Having defined an action method, we need to create what will be rendered when the action is invoked. Child actions are typically associated with partial views, although this is not compulsory.

ChildActionOnly属性确保操作方法只能作为视图中的子方法调用。一个动作方法不需要有这个属性来用作子动作,但我们倾向于使用这个属性来防止动作方法作为用户请求的结果被调用。定义了一个动作方法后,我们需要创建调用动作时将呈现的内容。子操作通常与部分视图相关联,尽管这不是强制性的。

  1. [ChildActionOnly] allowing restricted access via code in View

  2. State Information implementation for specific page URL. Example: Payment Page URL (paying only once) razor syntax allows to call specific actions conditional

  1. [ChildActionOnly] 允许通过视图中的代码进行受限访问

  2. 特定页面 URL 的状态信息实现。示例:支付页面 URL(只支付一次)razor 语法允许有条件地调用特定操作

回答by Eric Petroelje

You would use it if you are using RenderActionin any of your views, usually to render a partial view.

如果您RenderAction在任何视图中使用它,通常会使用它来呈现局部视图。

The reason for marking it with [ChildActionOnly]is that you need the controller method to be public so you can call it with RenderActionbut you don't want someone to be able to navigate to a URL (e.g. /Controller/SomeChildAction) and see the results of that action directly.

将其标记为的原因[ChildActionOnly]是您需要将控制器方法设为公开,以便您可以调用它,RenderAction但您不希望有人能够导航到 URL(例如 /Controller/SomeChildAction)并查看其结果直接行动。

回答by yantaq

With [ChildActionOnly]attribute annotated, an action method can be called only as a child method from within a view. Here is an example for [ChildActionOnly]..

there are two action methods: Index() and MyDateTime() and corresponding Views: Index.cshtml and MyDateTime.cshtml. this is HomeController.cs

[ChildActionOnly]注释的属性,动作方法可以被调用仅作为从一个视图内的子方法。这是[ChildActionOnly]的示例.

有两种操作方法: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);
    } 
}

Here is the view for Index.cshtml.

这是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>

Here is MyDateTime.cshtmlpartial view.

这是MyDateTime.cshtml部分视图。

@model DateTime

<p>
This is the child action result: @Model.ToLongTimeString()
<br />
@ViewBag.Message
</p>
 if you run the application and do this request http://localhost:57803/home/mydatetime
 The result will be Server Error like so: 

enter image description here

在此处输入图片说明

This means you can not directly call the partial view. but it can be called via Index() view as in the Index.cshtml

这意味着您不能直接调用局部视图。但它可以通过 Index() 视图调用,如 Index.cshtml

     @Html.Action("MyDateTime")  // Calling the partial view: MyDateTime().
 

If you remove [ChildActionOnly] and do the same request http://localhost:57803/home/mydatetime it allows you to get the mydatetime partial view result:
This is the child action result. 12:53:31 PM 
This is from MyDateTime()

回答by neizan

A little late to the party, but...

聚会有点晚了,但是......

The other answers do a good job of explaining what effect the [ChildActionOnly]attribute has. However, in most examples, I kept asking myself why I'd create a new action method just to render a partial view, within another view, when you could simply render @Html.Partial("_MyParialView")directly in the view. It seemed like an unnecessary layer. However, as I investigated, I found that one benefit is that the child action can create a different model and pass that to the partial view. The model needed for the partial might not be available in the model of the view in which the partial view is being rendered. Instead of modifying the model structure to get the necessary objects/properties there just to render the partial view, you can call the child action and have the action method take care of creating the model needed for the partial view.

其他答案很好地解释了该[ChildActionOnly]属性的作用。但是,在大多数示例中,我一直问自己为什么我要创建一个新的操作方法来在另一个视图中渲染局部视图,而您可以@Html.Partial("_MyParialView")直接在视图中直接渲染。这似乎是一个不必要的层。然而,当我调查时,我发现一个好处是子操作可以创建不同的模型并将其传递给局部视图。局部视图所需的模型在呈现局部视图的视图模型中可能不可用。您可以调用子动作并让动作方法负责创建局部视图所需的模型,而不是修改模型结构以获得必要的对象/属性来渲染局部视图。

This can come in handy, for example, in _Layout.cshtml. If you have a few properties common to all pages, one way to accomplish this is use a base view model and have all other view models inherit from it. Then, the _Layoutcan use the base view model and the common properties. The downside (which is subjective) is that all view models must inherit from the base view model to guarantee that those common properties are always available. The alternative is to render @Html.Actionin those common places. The action method would create a separate model needed for the partial view common to all pages, which would not impact the model for the "main" view. In this alternative, the _Layoutpage need not have a model. It follows that all other view models need not inherit from any base view model.

这可以派上用场,例如,在_Layout.cshtml. 如果您有一些对所有页面通用的属性,实现此目的的一种方法是使用基本视图模型并让所有其他视图模型从它继承。然后,_Layout可以使用基本视图模型和公共属性。缺点(这是主观的)是所有视图模型都必须从基础视图模型继承以保证这些公共属性始终可用。另一种方法是@Html.Action在那些常见的地方进行渲染。action 方法将为所有页面通用的部分视图创建一个单独的模型,这不会影响“主”视图的模型。在这个替代方案中,_Layout页面不需要有模型。因此所有其他视图模型不需要从任何基础视图模型继承。

I'm sure there are other reasons to use the [ChildActionOnly]attribute, but this seems like a good one to me, so I thought I'd share.

我确信使用该[ChildActionOnly]属性还有其他原因,但这对我来说似乎很好,所以我想我会分享。

回答by Joseph Wu

FYI, [ChildActionOnly] is not available in ASP.NET MVC Core. see some info here

仅供参考,[ChildActionOnly] 在 ASP.NET MVC Core 中不可用。在这里查看一些信息

回答by Hamid Nawaz

    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