【问题标题】:asp.net MVC - complex example?asp.net MVC - 复杂的例子?
【发布时间】:2025-12-27 16:00:06
【问题描述】:

我们正在评估 asp.net MVC,并正在寻找除 NerdDinner 之外更复杂的示例。

具体来说,在一个更复杂的网络应用中,我可能有一个导航栏(包括主导航、一个搜索框和一个登录状态显示)、一个主要内容区域、一个子内容区域(包括相关内容)和页脚。在 MVC 中,控制器返回一个 ViewModel(如果我想将我的控制器与我的 View 分离,则不是一个 View)——我的 ViewModel 是否必须具有涵盖我所在的“页面”的各个方面的属性打算渲染为输出?

如果不清楚,我可以重新提出我的问题。

顺便说一句 - 我知道这个网站是使用 MVC 构建的。我正在寻找可下载的示例。

提前致谢。

【问题讨论】:

  • *.com 是在 ASP .NET MVC 中构建的
  • 谢谢大卫,我知道。当我说“示例”时,我在寻找可下载的示例,而不仅仅是使用 MVC 的复杂(ish)网站的名称。
  • 然后阅读以下内容:dotnetslackers.com/projects/… 这是一个旨在剖析 Stack Overflow 以供公众使用的项目。
  • @Dan - 如果您将该评论作为答案,您将获得 +1 :)
  • 不,这更像是大卫评论的延续,而不是本身的答案。 :)

标签: asp.net-mvc views


【解决方案1】:

看看CodeCampServer

编辑:关于您对视图模型的查询,这不是完美的答案,但我想我会提请注意 AutoMapper(由 CodeCampServer 使用),它可以帮助模型和视图模型之间的自动映射数据,这是一个实时节省。还值得考虑输入构建器的概念(MVCContrib 提供了一些,ASP.NET MVC 2 提供了一些),它还可以通过全面封装通用功能来减少您必须传递到视图中的数据量。

这里有一个关于 ASP.NET MVC 2 的精彩视频:http://channel9.msdn.com/posts/Glucose/Hanselminutes-on-9-ASPNET-MVC-2-Preview-1-with-Phil-Haack-and-Virtual-Scott/

【讨论】:

  • +1 他们最近也努力改进 codeCampServer。很高兴看到它处于活动状态。它是 Manning 的 Mvc in Action 一书的代码伴侣。
  • 一定要给我打电话,但你能解释一下我是如何获取 CodeCampServer 应用程序的源代码的吗?没有下载标签!
  • 您需要使用像 TortoiseSVN (www.tortoisesvn.org) 这样的 Subversion 客户端来下载代码 - 详细信息在“源”选项卡上。
  • 我想编辑您的答案,但我认为最好告诉您为 CodeCampServer 提供的链接已更改为此处:codecampserver.codeplex.com
【解决方案2】:

来吧:

<% Html.RenderAction<LayoutController>(c => c.SearchBox()); %>
<% Html.RenderAction<LayoutController>(c => c.NavBox(Model)); %>

将它们放在您的母版页或侧边栏小部件的特定视图中,并将它们的逻辑从您正在处理的控制器/视图模型中抽象出来。他们甚至可以读取当前的 RouteData (url/action) 和 ControllerContext (parameters/models),因为您正在处理这些对象中的环境值 - 并执行完整的 ActionMethod 请求!

I blogged about this little known secret here。我还在博客中介绍了它的位置,即ASP.NET 1.0 MVC Futures assembly,它是来自 Microsoft 的独立插件。

Steve Sanderson 实际上在我称为Pro ASP.NET MVC 的一本书中给出了复杂逻辑和应用程序构建的示例(我知道这是无耻的插件,但这是您在问题中寻找的内容),他实际上使用了 RenderAction!我什至在读这本书之前就发表了博文,所以我很高兴我们在同一页上。

实际上,ASP.NET MVC 团队开发了许多扩展和功能,这些扩展和功能被排除在 ASP.NET MVC 1.0 项目之外——其中大部分使复杂的项目更易于管理。这就是为什么更复杂的示例(上面大多数人的答案中列出)必须使用某种类型的自定义 ViewEngine,或者使用基本控制器和自定义控制器进行一些大环跳跃。我查看了上面列出的几乎所有开源版本。

但归根结底不是看一个复杂的例子,而是知道实现你想要的复杂逻辑的方法——比如你的导航栏,当你只有一个控制器中的 ViewModel 来处理.将导航栏绑定到每个 ViewModel 很快就会很累。

因此,其中的一个示例是 Html.RenderAction() 扩展(正如我开始的那样),它允许您将更复杂/抽象的逻辑从视图模型/控制器中移出(这甚至不是您关心的问题) ,并将其放在它所属的控制器动作中。

这个小宝贝为我保存了 MVC,尤其是在我目前正在从事的大型企业项目中。

您可以将您的视图模型传递给 RenderAction,或者只渲染任何像页脚或页眉区域 - 并让逻辑包含在您可以触发和忘记的那些操作中(编写 RenderAction,然后忘记任何关心它对页眉或页脚的作用)

【讨论】:

  • 这并不是一个鲜为人知的秘密 ;)
【解决方案3】:

欢迎关注good.codeplex.com

上面有很多你想要的东西,但还有工作要做!但是,在您查看之后,我很乐意在此处或在 codeplex 上提出有关它的问题。

这是 mygoodpoints.org 当前正在运行的内容。

【讨论】:

  • 旁白:如果您有一些 JS 在您单击水泵时为水泵设置动画效果,那就太好了。 :) 否则,绝对是一个很棒的网站!
【解决方案4】:

我的 ViewModel 是否必须有 涵盖每一个属性 我的目标是“页面”的方面 渲染为输出?

是的。 RenderAction 还有另一种选择,但除此之外,ViewModel 通常通常很大,您必须找到一种好的方法来填充它。我承认这听起来像是一个麻烦点。

【讨论】:

    【解决方案5】:

    AtomSite是一个使用ASP.NET MVC编写的博客引擎

    【讨论】:

    • 这个网站是用asp.net MVC写的吗?这似乎有点“不标准”。
    【解决方案6】:

    据我所知,Controller 直接返回一个 View,并且可以使用 ViewData 或 Context 将数据传递给 View。

    前者只是各种数据位的松散包,而后者是特定类型。

    ViewModel 将作为 Context 传递给 View(并且 View 的标记将被强类型化为它期望的 ViewModel 类型)。

    这是我的 2c 价值 :) 希望有所帮助 - 抱歉,我无法提供任何可下载的示例。

    【讨论】:

      【解决方案7】:

      要自动将数据传递给所有视图,您可以创建自己的控制器类并使用它:

      例子

          public class MyController : Controller
      
      {
          private User _CurrentUser;
      
          public User CurrentUser
          {
              get
              {
                  if (_CurrentUser == null)
                      _CurrentUser = (User)Session["CurrentUser"];
                  return _CurrentUser;
              }
              set
              {
                  _CurrentUser = value;
                  Session["CurrentUser"] = _CurrentUser;
              }
          }
      
          /// <summary>
          /// Use this override to pass data to all views automatically
          /// </summary>
          /// <param name="context"></param>
          protected override void OnActionExecuted(ActionExecutedContext context) 
          {
              base.OnActionExecuted(context);
      
              if (context.Result is ViewResult) 
              {
                  ViewData["CurrentUser"] = CurrentUser;
              }
          }
          }
      

      【讨论】:

      • 但这会很快捆绑上 100 多个页面和数十个“可能的”侧边栏和导航栏小部件。你应该检查 Html.RenderAction 来处理很多这样的事情(bing it)。