在MVC中使用ChildActionOnly

时间:2012-04-20 21:25:24

标签: c# asp.net-mvc

您何时使用属性ChildActionOnly?什么是ChildAction以及您希望在什么情况下使用此属性限制操作?

6 个答案:

答案 0 :(得分:153)

ChildActionOnly属性确保只能将一个操作方法作为子方法调用 从一个角度来看。动作方法不需要将此属性用作子动作,但是 我们倾向于使用此属性来防止因用户而调用操作方法 请求。 定义了一个动作方法后,我们需要创建动作时要呈现的内容 调用。儿童行为通常与部分观点相关联,但这不是强制性的。

  1. [ChildActionOnly]允许通过View

  2. 中的代码进行限制访问
  3. 特定网页网址的状态信息实施。 示例:付款页面网址(仅支付一次) razor语法允许调用特定的操作条件

答案 1 :(得分:116)

如果注释了 [ChildActionOnly] 属性,则只能从视图中调用操作方法作为子方法。以下是 [ChildActionOnly]的示例。

有两种操作方法:Index()和MyDateTime()以及相应的Views: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>
 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

这意味着您无法直接调用局部视图。但它可以通过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()

答案 2 :(得分:71)

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

使用[ChildActionOnly]对其进行标记的原因是您需要将控制器方法公开,以便您可以使用RenderAction进行调用,但是您不希望某人能够导航到一个URL(例如/ Controller / SomeChildAction)并直接查看该操作的结果。

答案 3 :(得分:8)

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

答案 4 :(得分:6)

派对有点晚了,但是......

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

这可以派上用场,例如_Layout.cshtml。如果您拥有所有页面共有的一些属性,则实现此目的的一种方法是使用基本视图模型并使所有其他视图模型从中继承。然后,_Layout可以使用基本视图模型和公共属性。缺点(主观)是所有视图模型都必须从基本视图模型继承,以保证这些公共属性始终可用。另一种方法是在这些常见的地方呈现@Html.Action。动作方法将为所有页面共有的局部视图创建一个单独的模型,这不会影响&#34; main&#34;视图。在此替代方案中,_Layout页面无需具有模型。因此,所有其他视图模型都不需要从任何基本视图模型继承。

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

答案 5 :(得分: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