Доступ к объекту базы данных (и другим важным данным) в представлении - PullRequest
2 голосов
/ 25 сентября 2010

Я знаю, что это плохая практика - использовать базу данных в представлении.Тем не менее, я также передаю объект User, и мне интересно, как я могу упростить его использование.

Мне нравится, как он работает в Ruby On Rails.Вы просто создаете @instance_variable в before_filter и вызываете его из контроллеров и из представлений.

Вы не можете сделать это в ASP.NET MVC, хотя.Поэтому я создал класс со всеми данными, которые мне нужно передать в представление (DataContext и User):

public class XData
{
    public DBDataContext DB { get; set; }
    public User User { get; set; }
}

В методе Initialize контроллера я получаю все данные:

public XData X;

protected override void Initialize(RequestContext requestContext)
{
    base.Initialize(requestContext);

    X = new XData();

    X.DB = ...;
    X.User = ....;
}

Прекрасно работает: я могу получить объект базы данных из вида следующим образом:

<%= Model.X.DB.Users.First().Name %>

Чтобы передать данные в представление, мне нужно сделать следующее:

    public ActionResult Foo()
    {
        return View(new FooModel
                        {
                            X = X,
                            HelloMessage = "Hello world!"
                        });
    }

Мне здесь не нравится то, что мне всегда приходится писать X = X.Как я могу инициализировать это автоматически?

Спасибо

Ответы [ 3 ]

1 голос
/ 26 сентября 2010

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

Например, рассмотрим следующее:

public abstract class MyBaseModel
{
    public User User { get; set; }
}

public class FooModel : MyBaseModel
{
    public string FooMessage { get; set; }
}

public class BarModel : MyBaseModel
{
    public string BarMessage { get; set; }
}

public class MyController : Controller
{
    public ActionResult Foo()
    {
        var model = this.GetModel<FooModel>();

        // Set the properties on FooModel.
        model.FooMessage = "Hello world!"

        return View(model);
    }

    public ActionResult Bar()
    {
        var model = this.GetModel<BarModel>();

        // Set the properties on BarModel.
        model.BarMessage = "Hello world 2!"

        return View(model);
    }

    protected T GetModel<T>() where T : MyBaseModel, new()
    {
        T model = new T();

        // Set the properties on MyBaseModel.
        model.User = ...;

        return model;
    }
}

Если вы хотите разделить MyBaseModel и GetModel среди многих контроллеров, извлеките их в ModelProvider или что-то подобное, которое подается на каждый контроллер, в идеале через внедрение зависимостей.

1 голос
/ 25 сентября 2010

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

0 голосов
/ 26 сентября 2010

Я думаю, вам нужно начать с того, чтобы ваш взгляд был строго напечатан:

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

и в вашем контроллере:

 public ActionResult Foo()
    {
        var X = new XData();
        X.User = ....;
        X.SomeProperty = ...;
        X.Message = "Hello world!";
        return View(X);
    }

, который позволяет вам получить доступ к объекту в вашем представлении следующим образом:

<%: Model.User.UserName %>
<%: Model.Message %>
...