ASP.Net MVC - Модели и пользовательские элементы управления - PullRequest
0 голосов
/ 15 января 2011

У меня есть просмотр с мастер-страницей.Пользовательский элемент управления использует модель:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<BudgieMoneySite.Models.SiteUserLoginModel>" %>

Этот пользовательский элемент управления отображается на всех экранах (часть главной страницы).Если пользователь вошел в систему, он показывает определенный текст, а если пользователь не вошел в систему, он предлагает поле для входа.

Это работает нормально.

Теперь ядобавив мой первый функциональный экран.Итак, я создал новый вид ... и, ну, я сгенерировал код основного вида для меня, когда я выбрал метод контроллера, и сказал «Создать вид».

Мой контроллер имеет этот код:

        public ActionResult Transactions()
    {
        List<AccountTransactionDetails> trans = GetTransactions();
        return View(trans);
    }

    private List<AccountTransactionDetails> GetTransactions()
    {
        List<AccountTransactionDto> trans = Services.TransactionServices.GetTransactions();

        List<AccountTransactionDetails> reply = new List<AccountTransactionDetails>();

        foreach(var t in trans)
        {
            AccountTransactionDetails a = new AccountTransactionDetails();
            foreach (var line in a.Transactions)
            {
                AccountTransactionLine l = new AccountTransactionLine();
                l.Amount = line.Amount;
                l.SubCategory = line.SubCategory;
                l.SubCategoryId = line.SubCategoryId;
                a.Transactions.Add(l);
            }
            reply.Add(a);
        }


        return reply;
    }

Итак, мое представление было сгенерировано следующим образом:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<System.Collections.Generic.List<BudgieMoneySite.Models.AccountTransactionDetails>>" %>

Found <% = Model.Count ()%> Транзакции.

Все, что я сейчас хочу показать, - это количество записей, которые я буду отображать.

Когда я его запускаю, я получаю сообщение об ошибке:

"Элемент модели переданв словарь имеет тип 'System.Collections.Generic.List`1 [BudgieMoneySite.Models.AccountTransactionDetails]', но для этого словаря требуется элемент модели типа 'BudgieMoneySite.Models.SiteUserLoginModel'. "

Itпохоже, что пользовательский элемент управления отображается в первую очередь, и поскольку модель из контроллера - это мой список <>, он ломается!

Что я делаю не так?

Ответы [ 2 ]

1 голос
/ 15 января 2011

LoginModel должен быть установлен не как модель для страницы, а только для частичного просмотра.Вы можете использовать RenderAction для отображения частичного представления с моделью, которая не связана с моделью для страницы.Вот как я реализовал элемент управления состоянием входа, который отображается на главной странице.

Частичное представление (Views / Auth / LoginStatus.ascx):

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IUserProfile>" %>

<%    if (Request.IsAuthenticated && Model != null) { %>
    Welcome <b><%= Model.DisplayName %></b>!
    [ <%= Html.ActionLink("Log Off", "LogOff", "Auth") %> ]
<%
}
else {
%> 
    [ <%= Html.ActionLink("Log On", "Login", "Auth") %> ]
<%
} 
%>

На главной странице, котораяне имеет строго типизированной модели:

<% Html.RenderAction("LoginStatus", "Auth"); %>

и в контроллере (AuthController)

    public ActionResult LoginStatus()
    {
        TProfile p = null;
        if (User.Identity.IsAuthenticated)
        {
            p = Data.Profiles.Get(ulong.Parse(User.Identity.Name));
        }
        return View(p);
    }
1 голос
/ 15 января 2011

Дело не в том, что оно отображается «первым» как таковое, а в том, что все представления принимают модель, которую передает контроллер, если не указано иное.

Чтобы решить эту проблему, вы можете либо создать базовый класс, от которого унаследуются все ваши модели представлений, определяя вещи, которые нужны Master и его частичным представлениям (а затем вы передадите соответствующее свойство в одну из перегрузок RenderPartial) или вы можете использовать нетипизированную сумку ViewData, чтобы сделать нечто подобное.

* РЕДАКТИРОВАТЬ * Так что я понял, что отвечаю на твой вопрос как заданный, а не так, как я бы решил. Вышеуказанный ответ верен, если вы хотите обрабатывать вещи модели на своей главной странице, вам нужно либо вставить их в словарь ViewData (например, ViewData ["myData"] = mydata;) Или вам нужно создать базовый класс для всех ваших модели для наследования.

Тем не менее, в большинстве случаев (особенно что-то вроде profiel, которое вы привели в качестве примера) я тоже не делаю. В большинстве подобных случаев я использую вместо этого действие рендеринга, которое требует частичного просмотра из другого контроллера. Затем этот другой контроллер может подавать свои частичные данные в соответствии с необходимостью. Некоторые люди считают это нарушением MVC, я думаю, что это хороший способ составить представления и фактически сохранить ваши логические структуры нетронутыми, вместо того, чтобы запятнать воду, требуя от контроллера знать, что нужно главной странице, даже когда ему нечего делать. / работа этого контроллера. Обычное решение этой проблемы - также иметь базовый контроллер или использовать фильтры действий, но я считаю, что это будет просто еще больше, что вы должны поддерживать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...