在View中访问数据库对象(和其他重要数据)

时间:2010-09-25 19:35:23

标签: ruby-on-rails asp.net-mvc database viewdata

我知道在视图中使用数据库是一种不好的做法。但是,我也传递了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 个答案:

答案 0 :(得分:1)

您可以在ViewData中放置X并编写HtmlHelper扩展方法来访问X 覆盖控制器的View方法,并添加一些反映逻辑,将控制器的每个实例属性映射到属性匹配模型的名称(我猜Automapper可以帮助...)

答案 1 :(得分:1)

我见过一个类似的问题,很多控制器返回类似的模型只有少量自定义。在这种情况下,创建一个其他模型派生自的抽象基础模型,以及一个函数,它返回您需要的基础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;
    }
}

如果要在许多控制器中共享MyBaseModelGetModel,请将其提取到ModelProvider或类似的提供给每个控制器的东西,最好通过依赖注入。

答案 2 :(得分:-1)

我认为您需要首先强调您的观点:

<%@ 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 %>