Использование ChildActionOnly в MVC

Когда бы вы использовали атрибут ChildActionOnly? Что такое ChildAction и при каких обстоятельствах вы хотели бы ограничить действие, используя этот атрибут?

6 ответов

Решение

ChildActionOnly Атрибут гарантирует, что метод действия может быть вызван только как дочерний метод из представления. Метод действия не обязательно должен иметь этот атрибут для использования в качестве дочернего действия, но мы склонны использовать этот атрибут для предотвращения вызова методов действия в результате запроса пользователя. Определив метод действия, нам нужно создать то, что будет отображаться при вызове действия. Дочерние действия обычно связаны с частичными представлениями, хотя это не является обязательным.

  1. [ChildActionOnly], разрешающий ограниченный доступ с помощью кода в представлении

  2. Реализация информации о состоянии для определенного URL страницы. Пример: URL страницы оплаты (оплата только один раз) синтаксис бритвы позволяет назвать определенные действия условными

С аннотированным атрибутом [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>
 если вы запустите приложение и выполните этот запрос 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 в тех местах общего пользования. Метод действия создаст отдельную модель, необходимую для частичного представления, общего для всех страниц, что не повлияет на модель для "основного" представления. В этой альтернативе _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 
Другие вопросы по тегам