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

发布于 2024-09-24 18:43:07 字数 1097 浏览 5 评论 0原文

我知道在视图中使用数据库是一种不好的做法。但是,我还传递了 User 对象,我想知道如何使其易于使用。

我喜欢它在 Ruby On Rails 中的工作方式。您只需在 before_filter 中创建一个 @instance_variable 并从控制器和视图中调用它即可。

但您无法在 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 的东西。我怎样才能自动初始化它?

谢谢

I know it's a bad practice to use database in the view. However, I'm also passing the User object and I wonder how I can make it easy to use.

I love the way it works in Ruby On Rails. You just create an @instance_variable in before_filter and call it from the controllers and from the views.

You can't do this in ASP.NET MVC though. So I created a class with all the data I need to pass to the view (DataContext and User):

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

In controller's Initialize method I get all the data:

public XData X;

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

    X = new XData();

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

Works great: I can get the database object from the view like this:

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

In order to pass the data to the view, I have to do the following:

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

The thing I don't like here is that I always have to write the X = X thing. How can I initialize that automatically?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

别挽留 2024-10-01 18:43:07

我见过类似的问题,其中许多控制器返回类似的模型,仅进行一些自定义。在这种情况下,创建一个其他模型派生自的抽象基本模型,以及一个返回您需要的特定模型的函数,其中基本 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 或类似的东西提供给每个控制器,理想情况下通过依赖注入。

I've seen a similar problem where a lot of controllers return a similar model with only a few customizations. In this case, create an abstract base model that other models derive from, and a function that returns the particular model you need with the base X = X and so forth already set.

For example, consider this:

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;
    }
}

If you want to share MyBaseModel and GetModel among many controllers, extract it out to a ModelProvider or something similar that is supplied to each controller, ideally through dependency injection.

霞映澄塘 2024-10-01 18:43:07

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

You could place X in ViewData and write an HtmlHelper extension method to access X or override the View method of the controller and add a little reflection logic that maps every instance property of the controller to properties with matching names of your model (I guess Automapper could help here...)

清眉祭 2024-10-01 18:43:07

我认为您需要首先将视图设置为强类型:

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

I think you'll need to start by making your view strongly typed:

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

and in your controller:

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

which allows you to access the object in your view like so:

<%: Model.User.UserName %>
<%: Model.Message %>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文