Sử dụng ChildActionOnly trong MVC


168

Khi nào bạn sẽ sử dụng thuộc tính ChildActionOnly? Một ChildActionvà trong trường hợp nào bạn muốn hạn chế một hành động sử dụng thuộc tính này?

Câu trả lời:


161

Các ChildActionOnlythuộc tính đảm bảo rằng một phương pháp hành động có thể được gọi là chỉ như là một phương pháp trẻ từ bên trong một cái nhìn. Một phương thức hành động không cần phải sử dụng thuộc tính này như một hành động con, nhưng chúng ta có xu hướng sử dụng thuộc tính này để ngăn các phương thức hành động được gọi do yêu cầu của người dùng. Khi đã xác định một phương thức hành động, chúng ta cần tạo ra những gì sẽ được kết xuất khi hành động được gọi. Hành động của trẻ em thường được liên kết với các quan điểm một phần, mặc dù điều này không bắt buộc.

  1. [ChildActionOnly] cho phép truy cập hạn chế qua mã trong Chế độ xem

  2. Thông tin nhà nước thực hiện cho URL trang cụ thể. Ví dụ: URL trang thanh toán (chỉ thanh toán một lần) cú pháp dao cạo cho phép gọi các hành động cụ thể có điều kiện


Ví dụ sử dụng trong chế độ xem: <% Html.RenderAction ("MyChildAction", "MyContoder"); %>. Do đó, bạn không thể gọi một hành động con bằng GET và định tuyến
Erik Bergstedt

12
Mã ví dụ: @ 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." Vì vậy, bạn trực tiếp ngăn một GET cho một bộ điều khiển nhất định, nhưng chỉ từ bên trong một bộ điều khiển / hành động khác. Có khả năng: _Partial view.
Langeleppel

1
Làm cách nào để nắm bắt tốt nhất InvalidOperationExceptionkhi Phương thức được đánh dấu <ChildActionOnly>được gọi qua trình duyệt?
Bernhard Döbler

Tôi đã phải sử dụng @ Html.Action :)
chris c

125

Với thuộc tính [ChildActionOnly] được chú thích, một phương thức hành động chỉ có thể được gọi là phương thức con từ trong một khung nhìn. Đây là một ví dụ cho [ChildActionOnly]. .

có hai phương thức hành động: Index () và MyDateTime () và Lượt xem tương ứng: Index.cshtml và MyDateTime.cshtml. đây là HomeControll.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);
    } 
}

Đây là quan điểm cho 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>

Đây là chế độ xem một phần MyDateTime.cshtml .

@model DateTime

<p>
This is the child action result: @Model.ToLongTimeString()
<br />
@ViewBag.Message
</p>
 nếu bạn chạy ứng dụng và thực hiện yêu cầu này http: // localhost: 57804 / home / mydatetime
 Kết quả sẽ là Lỗi máy chủ như vậy:

nhập mô tả hình ảnh ở đây

Điều này có nghĩa là bạn không thể gọi trực tiếp chế độ xem một phần. nhưng nó có thể được gọi thông qua chế độ xem Index () như trong Index.cshtml

     @ Html.Action ("MyDateTime") // Gọi chế độ xem một phần: MyDateTime ().
 

Nếu bạn xóa [ChildActionOnly] và thực hiện cùng một yêu cầu http: // localhost: 57804 / home / mydatetime, nó cho phép bạn có được kết quả xem một phần mydatetime:
This is the child action result. 12:53:31 PM 
This is from MyDateTime()

Tôi nghĩ rằng lời giải thích này là một "Điểm dừng hoàn toàn", cảm ơn mọi người
TAHA SULTAN TEMURI

nhưng nó có thể đạt được bằng cách sử dụng NonAction, nó có gì khác biệt?
Imad

74

Bạn sẽ sử dụng nó nếu bạn đang sử dụng RenderActiontrong bất kỳ chế độ xem nào của bạn, thường để hiển thị một phần chế độ xem.

Lý do để đánh dấu nó [ChildActionOnly]là vì bạn cần công khai bộ điều khiển để bạn có thể gọi nó bằng RenderActionnhưng bạn không muốn ai đó có thể điều hướng đến một URL (ví dụ / Bộ điều khiển / Một số Chặn) và xem kết quả của điều đó hành động trực tiếp.


2
tương tự như [NonAction]. Là nó? sự khác biệt sau đó là gì?
DarthVader

10
@DarthVader - tương tự, nhưng với [NonAction] bạn sẽ không thể gọi nó là sử dụng RenderActionmột trong hai
Eric Petroelje

@EricPetroelje: Điều gì có thể mang lại lợi ích của việc đánh dấu Phương thức hành động như NonActionAttributetrong các dự án thực tế?
wuhcwdc

1
@Pankaj - Thành thật mà nói, tôi không thể nghĩ ra bất kỳ lý do thực sự tốt nào. Nếu bạn không muốn một phương thức trên bộ điều khiển được truy cập thông qua một URL, giải pháp tốt nhất sẽ chỉ là tạo phương thức privatehoặc protected. Tôi thực sự không thể nghĩ ra bất kỳ lý do chính đáng nào tại sao bạn muốn tạo ra một phương thức điều khiển publictrừ khi bạn muốn có thể gọi trực tiếp hoặc thông quaRenderAction
Eric Petroelje

@Eric: đôi khi chúng ta cần viết mã nhỏ để tính toán, vì vậy nếu đó là công khai trong bộ điều khiển thì nó có thể được truy cập bằng url, nếu bạn không muốn nó được truy cập bằng URL thì hãy đánh dấu nó là [NonAction ]
Ali Adravi


8

Đến bữa tiệc muộn một chút, nhưng ...

Các câu trả lời khác làm tốt công việc giải thích tác dụng của [ChildActionOnly]thuộc tính này. Tuy nhiên, trong hầu hết các ví dụ, tôi cứ tự hỏi tại sao tôi lại tạo một phương thức hành động mới chỉ để hiển thị một phần của chế độ xem, trong một chế độ xem khác, khi bạn có thể chỉ cần hiển thị @Html.Partial("_MyParialView")trực tiếp trong chế độ xem. Nó dường như là một lớp không cần thiết. Tuy nhiên, khi tôi điều tra, tôi thấy rằng một lợi ích là hành động trẻ em có thể tạo ra một mô hình khác và chuyển nó sang chế độ xem một phần. Mô hình cần thiết cho một phần có thể không có sẵn trong mô hình của chế độ xem trong đó chế độ xem một phần được hiển thị. Thay vì sửa đổi cấu trúc mô hình để có được các đối tượng / thuộc tính cần thiết ở đó chỉ để hiển thị chế độ xem một phần, bạn có thể gọi hành động con và yêu cầu phương thức hành động tạo mô hình cần thiết cho chế độ xem một phần.

Điều này có thể có ích, ví dụ, trong _Layout.cshtml. Nếu bạn có một vài thuộc tính chung cho tất cả các trang, một cách để thực hiện điều này là sử dụng mô hình chế độ xem cơ sở và có tất cả các mô hình chế độ xem khác được kế thừa từ nó. Sau đó, _Layoutcó thể sử dụng mô hình khung nhìn cơ sở và các thuộc tính chung. Nhược điểm (chủ quan) là tất cả các mô hình khung nhìn phải kế thừa từ mô hình khung nhìn cơ sở để đảm bảo rằng các thuộc tính chung đó luôn có sẵn. Thay thế là để kết xuất @Html.Actionở những nơi phổ biến. Phương thức hành động sẽ tạo một mô hình riêng biệt cần thiết cho chế độ xem một phần chung cho tất cả các trang, điều này sẽ không ảnh hưởng đến mô hình cho chế độ xem "chính". Trong phương án này, _Layouttrang không cần phải có mô hình. Theo sau, tất cả các mô hình khung nhìn khác không cần kế thừa từ bất kỳ mô hình khung nhìn cơ sở nào.

Tôi chắc chắn có những lý do khác để sử dụng [ChildActionOnly]thuộc tính, nhưng đây có vẻ là một lý do tốt cho tôi, vì vậy tôi nghĩ tôi muốn chia sẻ.


1
Một lợi thế khác là, nếu một cuộc gọi một phần được gói trong một cuộc gọi hành động, thì chúng ta có thể thêm một thuộc tính bộ đệm vào nó.
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 
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.