2

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

我喜欢它在 Ruby On Rails 中的工作方式。您只需创建一个@instance_variableinbefore_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东西。我怎样才能自动初始化它?

谢谢

4

3 回答 3

1

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

于 2010-09-25T19:47:48.107 回答
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;
    }
}

如果您想在多个控制器之间共享MyBaseModel和共享GetModel,请将其提取到ModelProvider提供给每个控制器的一个或类似的东西,最好是通过依赖注入。

于 2010-09-25T20:27:03.487 回答
-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 %>
于 2010-09-25T20:22:03.497 回答