在 MVC 中使用 ChildActionOnly

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

108051 次浏览

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

使用 [ChildActionOnly]标记它的原因是你需要控制器方法是公共的,这样你就可以用 RenderAction调用它,但是你不希望有人能够导航到一个 URL (例如/Controller/Some ChildAction)并直接看到那个操作的结果。

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

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

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

在带有 [儿童专用]属性注释的情况下,操作方法只能作为子方法从视图中调用。下面是 [儿童专用]。的一个示例。

有两个操作方法: 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>

这是 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.cshtml 中一样通过 Index ()视图调用它

@ Html. Action (“ MyDateTime”)//调用部分视图: 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()

有点晚了,但是..。

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

这可以派上用场,例如,在 _Layout.cshtml中。如果所有页面都有一些共同的属性,那么实现这一点的一种方法是使用基视图模型,并让所有其他视图模型从中继承。然后,_Layout可以使用基本视图模型和公共属性。缺点(这是主观的)是,所有视图模型都必须从基视图模型继承,以保证这些公共属性始终可用。另一种方法是在这些公共位置呈现 @Html.Action。Action 方法将为所有页面共有的部分视图创建一个单独的模型,这不会影响“ main”视图的模型。在这种情况下,_Layout页面不需要有一个模型。因此,所有其他视图模型都不需要从任何基本视图模型继承。

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

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

    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