你什么时候使用这个属性ChildActionOnly
?什么是 aChildAction
以及在什么情况下您希望使用此属性限制操作?
6 回答
该ChildActionOnly
属性确保动作方法只能作为视图中的子方法调用。动作方法不需要具有此属性才能用作子动作,但我们倾向于使用此属性来防止动作方法因用户请求而被调用。定义了动作方法后,我们需要创建在调用动作时将呈现的内容。子动作通常与部分视图相关联,尽管这不是强制性的。
[ChildActionOnly] 允许通过 View 中的代码进行受限访问
特定页面 URL 的状态信息实现。示例:支付页面 URL(只支付一次)剃刀语法允许有条件地调用特定操作
使用 注释的[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);
}
}
这是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() 视图调用它,就像在 Index.cshtml 中一样
@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()
如果您RenderAction
在任何视图中使用它,通常会使用它,通常用于渲染局部视图。
标记它的原因[ChildActionOnly]
是您需要将控制器方法公开,以便您可以使用它来调用它,RenderAction
但您不希望有人能够导航到 URL(例如 /Controller/SomeChildAction)并查看结果直接行动。
仅供参考,[ChildActionOnly] 在 ASP.NET MVC Core 中不可用。在这里查看一些信息
派对有点晚了,但是...
其他答案很好地解释了[ChildActionOnly]
属性的影响。但是,在大多数示例中,我一直在问自己,当您可以直接在视图中进行渲染时,为什么要创建一个新的操作方法只是为了在另一个视图中渲染部分@Html.Partial("_MyParialView")
视图。这似乎是一个不必要的层。但是,正如我调查的那样,我发现一个好处是子动作可以创建不同的模型并将其传递给局部视图。局部视图所需的模型在渲染局部视图的视图模型中可能不可用。您可以调用子动作并让动作方法负责创建局部视图所需的模型,而不是修改模型结构以获得必要的对象/属性。
这可以派上用场,例如,在_Layout.cshtml
. 如果您有一些所有页面共有的属性,实现此目的的一种方法是使用基本视图模型并让所有其他视图模型从它继承。然后,_Layout
可以使用基本视图模型和通用属性。不利的一面(这是主观的)是所有视图模型都必须从基本视图模型继承,以保证这些通用属性始终可用。@Html.Action
另一种方法是在那些常见的地方进行渲染。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