asp.net mvc - обновление / передача объектов без связи между контроллером и представлением - PullRequest
1 голос
/ 30 января 2011

По сути, у меня есть класс сущности (Article), и одна статья может принадлежать к n категориям. Здесь можно ожидать поле для категорий (скажем, ICollection), но база данных построена не так, и я не могу изменить модель Entity Framework.

Когда категория выбирается в представлении, пользователь должен выбрать свойство (список строк от 1 до 10. Это будет выглядеть так:

 Category         Option
===============================
[x] Category 1   |---------|v|
[x] Category 2   |---------|v|
[x] Category 3   |---------|v|
[x] Category 4   |---------|v|

[x] - checkbox
|---|v| - dropdown list

Однако я думаю, что, возможно, я мог бы создать ViewModel для этого конкретного случая. Я думал что-то вроде

namespace Models.ViewModels
{
    public class ArticleViewModel
    {
        public Article Article { get; set; }
        public ICollection<Category> Categories { get; set; }

        public ArticleViewModel()
        {
            Categories = new List<Category>();
        }
    }
}

Однако, когда я отправляю форму в контроллер, ArticleViewModel и все его внутренние компоненты равны нулю. Я не уверен почему.

Само представление довольно простое, оно будет иметь две отдельные формы: одну для изменения сведений о статье и одну для назначения категорий статье.

Как новичку в asp.net mvc, мне немного трудно обдумать эту проблему.

Какой подход вы бы порекомендовали?

Обновление: добавлен код для представления.

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Models.ViewModels.ArticleViewModel>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Modify article: <%= Model.Article.Title %>
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <% using (Html.BeginForm()) {%>
        <%= Html.ValidationSummary(true) %>

        <fieldset>
            <legend>Properties</legend>

            <div class="property">
                <span>
                    <%= Html.LabelFor(model => Model.Article.Title) %>

                    <%= Html.TextBoxFor(model => Model.Article.Title) %>
                    <%= Html.ValidationMessageFor(model => Model.Article.Title) %>
                </span>
            </div>

            <div class="property">
                <span>
                    <%= Html.LabelFor(model => Model.Article.Type) %>

                    <%= Html.TextBoxFor(model => Model.Article.Type) %>
                    <%= Html.ValidationMessageFor(model => Model.Article.Type) %>
                </span>
            </div>

            [continued...]
            <div>
                <%= Html.HiddenFor(model => Model.Article.Id) %>
                <input type="submit" value="Save" />
            </div>
        </fieldset>
    <% } %>
</asp:Content>

Маршрутизация выглядит так:

routes.MapRoute(
    "Articles",
    "Articles/{action}/{id}",
    new { controller = "Articles", action = "Edit" }
);

Ответы [ 2 ]

2 голосов
/ 30 января 2011

Весь смысл MVC в том, что ваш вид отделен от вашей модели. Не имеет значения, как выглядят ваши EF-сущности.

Создайте свой вид и просмотрите классы моделей так, как вы хотите. Не думай о своей структуре БД. Если вам нужна коллекция категорий, то создайте ее. Этот код должен представлять «домен» пользовательского интерфейса.

В контроллере сопоставьте модель вашего вида с EF и наоборот. Ответственность за понимание кода доступа к данным (или кода уровня обслуживания) и просмотра кода лежит на контроллерах.

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

Если вы тратите много времени на копирование данных из сущностей EF в модели, возможно, вы захотите взглянуть на эту замечательную библиотеку: AutoMapper

0 голосов
/ 30 января 2011

Когда вы настроите свой вид таким образом, у каждого из этих полей будет одинаковый атрибут name, и я не думаю, что MVC будет знать, как правильно сопоставить его с одним элементом.Как выглядит ваше [HttpPost] действие?Если что-то вроде:

[HttpPost]
public ActionResult Edit( ArticleViewModel model )
{
  ..
}

, то я сомневаюсь, что он будет отображаться правильно.Возможно, вы могли бы попытаться принять List<ArticleViewModel>, но я не думаю, что это будет работать правильно без CustomModelBinder.

То, что сказал @Jakub, правильно: разделите ваше мышление и спроектируйте вашу ViewModel в наиболее логичнойпуть для просмотра;позже вы можете беспокоиться о том, чтобы отобразить его обратно на уровень сервиса.Это, конечно, смена парадигмы, но она того стоит.=)

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