Производная модель от другой модели - PullRequest
1 голос
/ 25 января 2011

В моем проекте ASP.Net MVC 3 я хотел бы иметь объект модели базового класса, который обладает определенными свойствами, которые я затем буду использовать во всех других моделях моего приложения (или, по крайней мере, в большинстве из них).Таким образом, представления, использующие эти производные модели, также будут иметь свойства модели базового класса.

Можно установить свойства модели базового класса, скажем, контроллера базового класса, а затем каким-то образом мне нужно заполнить производные модели теми же данными.Любые предложения о том, как лучше всего это сделать?

Или мне стоит каким-то образом заняться созданием собственного DefaultModelBinder?Я немного сбит с толку относительно моих вариантов здесь.Как будто ты не мог сказать.:)

Пример кода

Базовая модель

public class ElkModel
{
    public bool IsAdministrator { get; set; }
}

Производная модель

public class UserModel : ElkModel
{
    [HiddenInput]
    public int User_ID { get; set; }

    // Other properties specific to this model
}

То есть в базовом контроллере

private BaseModel baseModel;

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
    baseModel = new baseModel();
    baseModel.MyProperty = "test";

    base.OnActionExecuting(filterContext);
}

И в производном методе действия контроллера

public ActionResult Index()
{
    // Derives from the base model in the base controller
    UserModel model = new UserModel();

    // model.IsAdministrator where IsAdministrator is a property of the base Model not UserModel

    return View(model);
}

Ответы [ 2 ]

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

Если вам нужны эти «общие данные» во всех представлениях, я бы не стал использовать наследование.Я бы выбрал метод расширения.

Что-то вроде:

public static CommonData GetCommonData(this HtmlHelper htmlhelper)
        {
            // do your magic here
        }

В вашем представлении вы можете просто вызвать:

@Html.GetCommonData()...

Таким образом, выДержите ваши модели в чистоте.

Наследование может быть правильным подходом, если эти Общие данные действительно хорошо "вписываются" в ваши классы Модели.

Было бы полезно, если бы вы предоставили несколько примеров;1013 *

** РЕДАКТИРОВАНИЕ **

Я бы оставил вашу BaseModel как свойство в Controller и заполнил бы его в OnActionExecuting, как вы предлагаете.

Но я бы использовал ExtensionMethods вКонтроллер и Html помощник для доступа к данным.Если вы используете наследование, вы без необходимости усложняете ситуацию.

Дайте мне знать, если вам нужны примеры методов расширения.

Этот подход СУХОЙ.Вы не дублируете код.

** РЕДАКТИРОВАНИЕ 2 **

Вот как должен выглядеть ваш метод расширения: (вне моей головы, поэтому он может не скомпилироваться)

public static class ExtensionHelpers
{
    public static BaseModel GetCommonData(this HtmlHelper htmlhelper)
    {
        YourController HtmlHelper = htmlhelper.ViewContext.Controller as YourController;
        if (controller != null)
        {
            return HtmlHelper.BaseModel;
        }
        return null;
}

Убедитесь, что Controller является производным от класса Controller, в который вы добавляете свойство BaseModel.Я назвал это 'YourController' выше.

Тогда вам следует идти; -)

Edit 3

Просто напоминание о том, что пространство имен должно быть известно, если выхочу использовать методы расширения в представлении.Лучший способ добиться этого - включить пространство имен в Web.Config в папку Views.

  <system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
        <add namespace="Yournamespace" /> <- LOOK HERE
      </namespaces>
    </pages>
  </system.web.webPages.razor>
1 голос
/ 25 января 2011

Немного зависит от того, говорите ли вы о входящей модели или исходящей модели (то есть обслуживаемая модель представления или параметр модели, публикуемый формой).

В первом случае это довольно легко сделать, как вы предложили; через базовый контроллер, который заполняет модель с общей информацией до или после выполнения действия (переопределяя OnActionExecuting или OnActionExecuted). Вы также можете использовать ActionFilter, который может быть более гибким, поскольку он не требует от вас следовать одной цепочке наследования для всех ваших контроллеров. Я склонен рекомендовать последний подход именно по этой причине.

На стороне публикации формы вам может потребоваться создать собственное средство связывания моделей, но только если у вас есть причины, по которым вы хотите, чтобы одно действие выполнялось более чем в одном типе модели, и, честно говоря, это может стать проблематичным. В этом случае вам нужно, чтобы фактическое имя типа было помещено в скрытую форму elemetn или что-то в этом роде, чтобы связыватель вашей модели мог определить, какую модель создать. Я бы рекомендовал против такого подхода, если у вас нет веских причин для этого.

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