【问题标题】:Is making a BaseViewData class a property of a BaseController class a bad idea?将 BaseViewData 类作为 BaseController 类的属性是个坏主意吗?
【发布时间】:2010-02-02 22:48:21
【问题描述】:

我项目中的每个控制器类都派生自一个基本控制器类,恰当地命名为 BaseController。

所有视图数据都包含在一个名为 BaseViewData 的类中(将来可能成为更具体的视图数据类的基本控制器)。

我在 BaseController 上创建了一个 BaseViewData 属性,因为每个控制器都需要访问强类型基础视图数据中的数据(并且 BaseController 做了一些工作来预填充一些 BaseViewData 属性)。

我这样做是因为:

  1. 如果我更改了属性,我 会得到编译时错误 检查以解决更多损坏的代码 迅速地。

  2. 练习 DRY,我已经 设法整合了很多代码 以前分散的 贯穿每个控制器。

但是,这是我第一次尝试这样做。所以我可能会忽略一个准备抬起丑陋脑袋的问题。所以:

让 BaseViewData 类成为 BaseController 类的属性是个坏主意吗?如果是,为什么?

更新 1:

我的 BaseController 看起来像(还有更多,但这应该能说明问题):

public class BaseController
{
  public string Language {get; set;}
  public string Locale {get; set;}
  public BaseViewData Data {get; set;}

  protected override void OnActionExecuting(ActionExecutingContext filterContext)
  {
    var l = (RouteData.Values["language"] != null) ? RouteData.Values["language"].ToString() : "en";
    if (l.ToLower().Contains("en"))
    {
      l = "en";
    }
    else
     l = "ja";

    Data.Language = l;
  }
}

我的 BaseViewData 看起来像这样(同样,还有更多...):

public class BaseViewData
{
  public string Language {get;set;}
  public string Locale {get;set;}
  public bool IsOwner {get;set;}
  public string Menu1 {get;set;}
  public string Menu2 {get;set;}
  public string Menu3 {get;set;}

  public IPagedList<TYPE> ListOfTYPE {get;set;}
  etc...
}

【问题讨论】:

  • 有趣的想法。我可能会自己使用 IViewData 和 BaseController。我认为我的 IViewData 只是一个共享 DTO,没有以下功能:UserId、UserName 和 IsLoggedIn 之类的......我很想看看你的 BaseViewData 中有什么。

标签: c# asp.net-mvc controller viewdata


【解决方案1】:

您的想法的菜单组件可能不是必需的,使用 ASP.NET MVC 2 Beta,您现在可以使用 Http.RenderAction 直接从视图调用控制器操作(例如从存储库并返回部分视图。

查看Haacked更多信息...

此外,对于语言/区域设置等更简单的内容,如果您使用 ASP.NET 配置文件提供程序(可通过控制器和视图访问),则可能不需要这样做。

【讨论】:

  • 您是否有以这种方式使用 Profile Provider 的基于 ASP.NET MVC 的网站的示例?
  • 我挖掘了能够通过 RenderAction 直接调用动作的想法......嗯......
  • 我认为 ASP.NET MVC 2 可能会导致对我的应用程序进行重大重写......但从长远来看可能是值得的。
  • 在使用 Profile Provider 方面,有很多关于如何使用它的 MSDN 文档,但是您无法直接在控制器中访问强类型 Profile.[property name]。但是,我创建了一个 ProfileCommon : ProfileBase,默认 asp.net 配置文件提供程序可以使用它,并允许在控制器中进行强类型访问。我还构建了我的控制器以从 BaseController 继承,我在其中使用 ProfileBase.Create(username) 作为 ProfileCommon 检索配置文件。我在 stackoverflow 上找到了这些说明...
  • 不幸的是,VS2010 没有附带 MVC 2 Beta,它附带了 MVC 2 Preview 2.... :( 所以它没有 Html.RenderAction 方法
【解决方案2】:

对于我曾经在 ASP.NET MVC 中工作过的唯一网站,这正是我们所做的。这样做的好处还在于,我们能够在 BaseViewData 类中保存母版页所需的值。因为每个 View 都有一个派生 BaseViewData 的实例,所以我们可以安全地使用 Master Page 中 BaseViewData 中的数据。

【讨论】:

  • 这正是我正在做的。效果很好,只是希望我不准备养怪物。 :D
【解决方案3】:

恕我直言,你正在创造一个怪物。

随着您的应用程序的发展,越来越多的功能和全局屏幕将融入基本视图模型中。不可避免的是像 .aspx.cs 文件这样的神代码隐藏类,MVC 试图避免。

最好使用 MVC2 的 RenderAction 或 MVC Contrib 中的 SubController 之类的东西,即使这意味着稍微打破 MVC 模式。

看看像 CNN 甚至 Stackoverflow.com 这样的网站,你会在不知不觉中找到十几种方法。

【讨论】:

  • 这是您能想到的唯一问题吗?这也是我最关心的问题,在开发过程中我会一直放在首位。我是这个应用的唯一开发者,所以不用担心别人在我不知情的情况下提前添加东西。
  • 而且,实际上,即使它确实变得有点胖——那有什么害处?传递大型强类型视图数据对象(即使许多属性为空?)是否会对性能产生某种影响?只是好奇...谢谢。
  • 您将违反单一职责原则。你的基础视图模型最终会负责很多事情。
  • 好点。如果它要做的只是在属性中保存一些数据怎么办?其他类将完成创建要保存在 BaseViewData 中的数据的“工作”?
猜你喜欢
  • 1970-01-01
  • 2016-12-08
  • 1970-01-01
  • 2012-08-22
  • 2020-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多