天道酬勤,学无止境

In ASP.NET MVC3 how do you stay DRY with very similar but slightly different viewmodels?

In building an app, we created a generic object model to store some values, the viewmodel looks a bit like this at the moment:

public class FooViewModel {
    public int ID { get; set; }

    public byte FooType { get; set; }

    [Required]
    [Display(Name = "Bar Name")]
    public string Name { get; set; }

    [Required]
    public string Email { get; set; }

    //etc, etc
}

The problem is: depending on the FooType, we want to have the Display Name to be different and the Email is not required for type 1 and 2, but is required for type 3 and 4.

We tried seperating out the properties that differ per type in to classes that inherit from this one, but the validation does a fallback on what is specified in the base type, so that didn't work.

Currently, the only option seems to be to create a viewmodel for each FooType (and also seperate controllers and view), which leads to a lot of code duplication.

What are other ways to keep this DRY?

评论

To benefit a validation context (e.g. validating objects in different contexts), I strongly recommend using FluentValidation library.

You could implement a custom RequiredIf validation attribute, or you could implement IValidatableObject.

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • MVC布局VS MVC母版页(MVC Layout VS MVC Master Page)
    问题 我开始学习MVC4。 我遇到了两种基于Razor模板或母版页创建视图的可能性。 我想了解两者之间的实际差异。 现在,我可以看到,如果我使用母版页创建视图,则可以覆盖多个部分。 例如,如果我的主人定义了“左列”占位符和“主体”占位符,我不仅可以定义特定视图的主体,而且还可以渲染“左列”部分中的内容,例如显示控件。绑定到页面所在的上下文(从搜索框到股票报价查看器)。 同样,不能通过使用Razor模板来定义母版页,Razor模板比其他语法冗长得多(部分错误:有人设法破解了这方面)。 使用Razor布局,我只能定义页面的一个连续块,该块可以被特定的View覆盖,并且我应该使用多个布局(破坏DRY),以便在页面的其他部分进行少量更改。 我以前的说法是正确的,还是我遗漏了一些东西? 显然,我可以利用jQuery来呈现页面任何部分的内容,但这是另一回事 回答1 您可以将部分与Razor一起使用。 斯科特·古(Scott Gu)在这里发表了关于他们的博客:http://weblogs.asp.net/scottgu/archive/2010/12/30/asp-net-mvc-3-layouts-and-sections-with-razor.aspx 在布局中,您可以根据需要定义任意多个部分: <div id="leftMenu"> @RenderSection("LeftMenu"
  • ViewBag,ViewData和TempData(ViewBag, ViewData and TempData)
    问题 任何人都可以解释,何时使用 临时数据 ViewBag ViewData 我有一个要求,我需要在一个控制器1中设置一个值,该控制器将重定向到控制器2,而控制器2将呈现视图。 我尝试使用ViewBag,当我到达第二个控制器时,该值会丢失。 我可以知道何时使用以及优缺点吗? 谢谢 回答1 1)临时数据 允许您存储将保留重定向的数据。 在内部,它使用会话作为后备存储,在进行重定向后,数据将自动逐出。 模式如下: public ActionResult Foo() { // store something into the tempdata that will be available during a single redirect TempData["foo"] = "bar"; // you should always redirect if you store something into TempData to // a controller action that will consume this data return RedirectToAction("bar"); } public ActionResult Bar() { var foo = TempData["foo"]; ... } 2)ViewBag,ViewData 允许您将数据存储在控制器操作中
  • MVC3: make checkbox required via jQuery validate?
    I want my "Agree To Terms" checkbox to be mandatory using jQuery validate, in an MVC3 project. I currently get server/client DRY/SPOT validation from "MS data annotation attributes" + "MS MVC3 unobtrusive jQuery validation". Here's a stand-alone test (plain HTML generated by MVC3). Why doesn't it work, please? When run, validation ensures the "Contact Name" field is filled, but doesn't care about the state of the checkbox. <!DOCTYPE html> <html> <head> <title>RequiredCheckbox</title> <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
  • 在jquery中使用AJAX Post从正确类型的MVC3视图传递模型的正确方法(Proper way to use AJAX Post in jquery to pass model from strongly typed MVC3 view)
    问题 我是Web程序员的新手,所以如果我的某些“行话”不正确,请原谅我。 我有一个使用MVC3框架的ASP.NET项目。 我正在管理员视图上,管理员将在其中修改设备列表。 功能之一是“更新”按钮,在将帖子发送到MVC控制器后,我想使用jquery动态编辑网页上的条目。 我认为这种方法在单个管理员设置中是“安全的”,在这种情况下,网页与数据库不同步的担忧降至最低。 我创建了一个强类型化的视图,希望使用AJAX发布将模型数据传递给MVC控件。 在下面的文章中,我发现了与我正在做的事情类似的事情:导致空参数的JQuery Ajax和ASP.NET MVC3 我将使用以上文章中的代码示例。 模型: public class AddressInfo { public string Address1 { get; set; } public string Address2 { get; set; } public string City { get; set; } public string State { get; set; } public string ZipCode { get; set; } public string Country { get; set; } } 控制器: public class HomeController : Controller { public
  • Problem with MVC3 AllowHtml attribute
    I have a web app based on MVC3 (no beta or release candidate, RTM/RTW version) that has an action that accepts XML files for processing. Of course, this seems evil to MVC because of possible attacks, so it doesn't allow it. Well, I try to put either AllowHtml on the model object as such: public class XMLModel { [AllowHtml] public string msg { get; set; } } Or I set ValidateInput to false on my action method such as this: [ValidateInput(false)] public ActionResult AddCDR(XMLModel model) { } The reason for having a "strongly" typed model in the first place was that I originally tried to have a
  • 使用 MSpec(BDD 指南)为 ASP.NET MVC 控制器操作 DRY-ing 非常相似的规范(DRY-ing very similar specs for ASP.NET MVC controller action with MSpec (BDD guidelines))
    问题 对于两个非常相似的控制器操作,我有两个非常相似的规范:VoteUp(int id) 和 VoteDown(int id)。 这些方法允许用户对帖子投赞成票或反对票; 有点像 StackOverflow 问题的投票赞成/反对功能。 规格是: 投票反对: [Subject(typeof(SomeController))] public class When_user_clicks_the_vote_down_button_on_a_post : SomeControllerContext { Establish context = () => { post = PostFakes.VanillaPost(); post.Votes = 10; session.Setup(s => s.Single(Moq.It.IsAny<Expression<Func<Post, bool>>>())).Returns(post); session.Setup(s => s.CommitChanges()); }; Because of = () => result = controller.VoteDown(1); It should_decrement_the_votes_of_the_post_by_1 = () => suggestion.Votes.ShouldEqual(9)
  • 通过JSON将对象数组发布到ASP.Net MVC3(Post an Array of Objects via JSON to ASP.Net MVC3)
    问题 我正在寻找一种通过JSON将对象数组发布到MVC3的解决方案。 我正在处理的示例代码为:http://weblogs.asp.net/scottgu/archive/2010/07/27/introducing-asp-net-mvc-3-preview-1.aspx JS: var data = { ItemList: [ {Str: 'hi', Enabled: true} ], X: 1, Y: 2 }; $.ajax({ url: '/list/save', data: JSON.stringify(data), success: success, error: error, type: 'POST', contentType: 'application/json, charset=utf-8', dataType: 'json' }); ListViewModel.cs: public class ListViewModel { public List<ItemViewModel> ItemList { get; set; } public float X { get; set; } public float Y { get; set; } } ItemViewModel.cs: public class ItemViewModel { public string
  • 随机缓慢的页面加载(Randomly slow page loading)
    问题 解释问题的真正含义并不容易,但我尝试;-)。 这是一些数据: 带有 IIS7(不是 RC2)的 Microsoft 服务器 3GB 内存只有这个应用程序在这台服务器上 SQL 2008 速成版存储库模式简单注射器 MVCSitemapProvider 好的,现在的问题。 这不是启动,因为站点在 2 秒内加载。 在应用程序池回收之后。 启动后,页面加载时间为 200 毫秒或更短(或更短),但有时(我不能说何时,因为它是随机的,而且不是在回收后)它们需要长达 2 分钟或更长时间。 我试图瞥一眼找到问题所在。 它显示如下内容: ASP.NET 开始请求:121456ms(这是随机的) 过滤器:2ms 控制器:26ms 观看次数:298 毫秒 ASP.NET 结束请求:0ms 这就像一个请求堆叠,我不知道。 编辑: 所以我已经删除了整个 MVC SiteMap Provider 但幻影性能问题仍然存在。 然后我检查了 IIS 配置并注意到 AppPool 是一个 NetworkService 而不是 ApplicationPoolIdentity(其他 MVC 解决方案在 ApplicationPoolIdentity 上运行),现在它看起来比以前更快(页面加载 < 50 毫秒)! 如果问题仍然存在,我会写在这个线程中。 回答1 我在 MVC3 项目上遇到了一个非常相似的问题
  • In ASP.NET MVC3, how should one render multiple PartialViews backed by multiple Models?
    In MVC3 Razor, how do you create a page with multiple forms, so that each form is a partial view rendered with its own model? We have been trying various forms of calling Html.RenderPartial(), passing in the partialview name as well as an instance of our models that we're accessing through the ViewBag, but every method we've tried seems to have serious issues, and so we must have a fundamental misunderstanding of how this is supposed to operate in an ideal world. We have found some SO responses on similar topics (like this one) recommending a "super model" that contains references to each of
  • ASP.NET MVC 4 + Ninject MVC 3 =没有为此对象定义无参数构造函数(ASP.NET MVC 4 + Ninject MVC 3 = No parameterless constructor defined for this object)
    问题 更新-请查看我的答案以获得此问题的解决方案的链接和说明 在开始之前,我知道这是一个非常常见的问题,我已经将Ninject用于很多没有问题的卫星,但是现在出现了,我无法解决。 另外,不,到目前为止,Google和SO上的结果都没有对我有所帮助。 因此,请考虑以下代码,这些代码在Windows Server 2008 R2上来自Visual Studio 2012的非常非常非常简单的原型ASP.NET MVC 4项目上运行: public class DefaultController : Controller { private IGroupPrincipalRepository GroupPrincipalRepository { get; set; } [Inject] public DefaultController( IGroupPrincipalRepository groupPrincipalRepository) { this.GroupPrincipalRepository = groupPrincipalRepository; } } 这是NinjectWebCommon.cs RegisterServices方法: kernel.Bind(typeof(IGroupPrincipalRepository)).ToConstructor( c => new
  • ASP.NET Core中使用令牌桶限流
    在限流时一般会限制每秒或每分钟的请求数,简单点一般会采用计数器算法,这种算法实现相对简单,也很高效,但是无法应对瞬时的突发流量。比如限流每秒100次请求,绝大多数的时间里都不会超过这个数,但是偶尔某一秒钟会达到120次请求,接着很快又会恢复正常,假设这种突发的流量不会对系统稳定性带来实质性的影响,则可以在一定程度上允许这种瞬时的突发流量,从而为用户带来更好的可用性体验。这就是令牌桶算法的用武之地。该算法的基本原理是:有一个令牌桶,容量是X,每Y单位时间会向桶中放入Z个令牌,如果桶中的令牌数超过X,则丢弃令牌;请求要想通过首先需要从令牌桶中获取一个令牌,获取不到令牌则拒绝请求。可以看出对于令牌桶算法X、Y、Z这几个数的设定特别重要,Z应该略大于绝大数时候的Y单位时间内的请求数,系统会长期处于这个状态,X可以是系统允许承载的瞬时最大请求数,系统不能长时间处于这个状态。这里介绍一个ASP.NET Core的中间件来满足令牌桶限流需求:FireflySoft.RateLimit.AspNetCore。使用步骤如下:1、安装Nuget包有多种安装方式,选择自己喜欢的就行了。包管理器命令:Install-Package FireflySoft.RateLimit.AspNetCore或者.NET命令:dotnet add package FireflySoft.RateLimit
  • DRY-ing very similar specs for ASP.NET MVC controller action with MSpec (BDD guidelines)
    I have two very similar specs for two very similar controller actions: VoteUp(int id) and VoteDown(int id). These methods allow a user to vote a post up or down; kinda like the vote up/down functionality for StackOverflow questions. The specs are: VoteDown: [Subject(typeof(SomeController))] public class When_user_clicks_the_vote_down_button_on_a_post : SomeControllerContext { Establish context = () => { post = PostFakes.VanillaPost(); post.Votes = 10; session.Setup(s => s.Single(Moq.It.IsAny<Expression<Func<Post, bool>>>())).Returns(post); session.Setup(s => s.CommitChanges()); }; Because of =
  • MVC3和实体框架(MVC3 and Entity Framework)
    问题 我的问题很简单:将.edmx文件放在MVC3项目的Web应用程序的模型文件夹中是否是一个好习惯? 回答1 我的答案很简单,不要用数据访问逻辑和数据建模弄乱表示层(整个MVC应用程序)。 从下到上,您的Visual Studio解决方案中至少有4个项目: 1-ProjectName.Interfaces(类库,实体的接口); 2-ProjectName.DAL(类库,使用了唯一一个甚至都知道EF的类,POCO实体使用另一个文件来实现项目1的接口,在该文件中,您可以使用部分类重新声明相同的对象...); 3-ProjectName.BL(类库,业务逻辑,引用上面1和2的两个项目); 4-ProjectName.Web(ASP.NET MVC应用程序,表示层,引用两个项目1和3,但不引用2); 当然,这是为了简化事情,根据我的经验,这是一个可靠的设计,对于很小的项目来说有点过分了,但从长远来看会有所收获。 在我看来,MVC的M,不是模型,不是数据模型,不是EF,不是绑定到特定数据库引擎的ORM。 这个答案当然是主观的,并且基于我的个人经验;-) 回答2 我在这里完全同意Davide的观点,我只是想补充一点,您还应该考虑使用POCO模板来生成poco对象,而不是将实体框架对象返回到另一层,因为这将对实体框架产生依赖性。 在某些不可避免的情况下,如果您不将其放入单独的项目中
  • System.Runtime.Caching.MemoryCache与HttpRuntime.Cache-有什么区别吗?(System.Runtime.Caching.MemoryCache vs HttpRuntime.Cache - are there any differences?)
    问题 我想知道MemoryCache和HttpRuntime.Cache之间是否有任何区别,在ASP.NET MVC项目中首选哪一个? 据我了解,两者都是线程安全的,乍一看API几乎是相同的,那么使用哪个有什么区别? 回答1 HttpRuntime.Cache获取当前应用程序的缓存。 MemoryCache类类似于ASP.NET Cache类。 MemoryCache类具有许多用于访问缓存的属性和方法,如果您使用过ASP.NET Cache类,则这些属性和方法将是您熟悉的。 HttpRuntime.Cache和MemoryCache之间的主要区别在于,后者已更改为可以由非ASP.NET应用程序的.NET Framework应用程序使用。 有关其他阅读: 贾斯汀·马修(Justin Mathew)博客-.Net 4.0中的缓存 Jon Davis博客-.NET中简单缓存的四种方法 更新 : 根据用户的反馈,有时乔恩·戴维斯(Jon davis)博客不起作用,因此我将整篇文章都放在图片中,请注意。 注意:如果不清楚,请单击图像,然后将其在浏览器中打开,然后再次单击以进行缩放:) 回答2 这是乔恩·戴维斯(Jon Davis)的文章。 为了保持可读性,我删去了现在过时的EntLib部分,简介和结论。 ASP.NET缓存 ASP.NET或System.Web.dll程序集确实具有缓存机制。
  • 每次用户访问网站时如何加载最新的 javascript 文件 [重复](how to load the latest javascript files every time the user visits the website [duplicate])
    问题 这个问题在这里已经有了答案: 8 年前关闭。 可能的重复: 如何在浏览器中强制刷新 javascript 文件? 我在基于 ASP.NET MVC 和 javascript 文件中的应用程序包含在 .csHtml 文件中。 我需要这样做,以便用户不必执行 [Ctrl+F5] 或手动清除缓存,并且每次在浏览器中加载最新版本的 javascript 文件。 如果可以提供一些示例,我将不胜感激。 建议的主要技术是在包含文件时使用虚拟参数。 每次修改js文件时,我也不会手动更改参数。 如果这可以自动完成,需要一些示例。 编辑 1:请使用 ASP.NET MVC 预期提供解决方案。 回答1 您想使用捆绑和缩小。 根据您的 MVC 版本,实现略有不同。 在最新版本中,默认使用它。 Bundling 和 Minification 会将您的所有脚本(和样式表)合并并缩小到一个文件(或多个,取决于您的使用方式),并使用唯一的参数为它们提供服务。 每当该特定包中的文件发生更改(因此用户需要下载新文件)时,参数都会自动更改。 对于 MVC3,您需要安装 Microsoft Web Optimization。 然后在你的 global.ascx 中,你会做这样的事情并从Application_Start调用它: private static void SetupBundling() { var
  • 从 Asp.net MVC2 迁移到 MVC4(Migrating from Asp.net MVC2 to MVC4)
    问题 我想将 MVC2 网站转换为 MVC4。 我知道有一些工具可以帮助从 MV2 转换为 MVC3,但我找不到从 MVC2 转换为 MVC4 所需的任何工具或步骤。 请指点我一些文章/博客,它可以为我提供更多信息来帮助我完成这个过程。 回答1 看起来现在有一个解决方案发布到一个类似的问题,表明存在两个包可以从 MVC 2 迁移到 MVC 3,然后从 MVC 3 迁移到 MVC 4。 根据我最近进行相同升级的经验,您需要以下内容: 确保您已将解决方案从 VS2008 升级到 VS2010 ASP.NET MVC 3 Application Upgrader - 用于升级 MVC2 -> MVC3 的独立包 UpgradeMvc3ToMvc4 - 用于从 MVC3 -> MVC4 升级的 nuget 包 最近使用了这两种方法后,我可以为它们担保,因为它们对我来说效果很好。 回答2 不幸的是,没有从 MVC 2 到 MVC 4 的直接路径。需要完成到 MVC 3 的中间步骤。 MVC 2 到 MVC 3 然后 MVC 3 到 MVC 4 回答3 发行说明中有专门用于此的部分。 回答4 就我个人而言,我发现转换通常会有小故障和问题。 我更喜欢直接走这条路并创建一个新的 MVC 项目,然后将所有控制器、视图、内容等移动到新项目中。 确保添加您可能正在使用的任何包(但我怀疑您是否在 MVC2
  • 如何在不同的分辨率/屏幕上提供相同的应用程序(How to go about serving the same app on different resolutions/screens)
    问题 场景:您需要在不同的屏幕上显示相同的应用程序 - 假设一个标准的 15''-17'' 一个便携式 10'' 和一个移动 4'',可能在不同的分辨率下工作。 问题:您是否尝试使用根据可用空间重新排列的流动布局,还是滚动 N(每个范围一个)单独的 UI 层,针对每个特定支持的分辨率/屏幕尺寸进行优化。 此类问题的行业标准是什么? 当屏幕以一种或另一种方式调整大小时,提出将屏幕划分为优先区域的非常巧妙的布局是否有意义? 我们都知道 iPhone 应用程序(或任何其他掌上设备)不可能像桌面版本一样,所以我假设在这种情况下(4 英寸或更少)你被迫滚动不同的用户界面,但有没有中间地面(假设在 13'' - 7'' 屏幕之间,后者需要手指作为主要输入)在那里进行液体布局有意义吗? 回答1 您似乎已经决定移动设备需要一个单独的 UI,我支持这一点。 用户与这些设备交互的方式是如此不同,您需要以特定的方式来考虑它们。 对于其他屏幕尺寸,我认为需要从用户的角度来处理它们。 如果用户以不同的方式与屏幕交互,那么您需要单独的界面。 但是,根据我的经验,用户倾向于将大约 10" 以上的屏幕视为同一事物的更大或更小的版本,因此您应该以相同的方式对待您的 UI。不要为较小的屏幕大幅更改它。相反,您需要找到一种方法让它以这样的方式增长或缩小,以便用户觉得他们有更多的工作空间。使用相同的旧 UI。
  • 动态扩展应用程序的功能?(Dynamically extending features of an application?)
    问题 最近,我在使用ASP.NET MVC3 / 4时遇到了一种开发可插拔应用程序模块的方法,我喜欢这种方法的简便性。 目前,我的应用程序结构如下: 因此,任何想要为我的应用程序开发扩展的人,都可以遵循上述教程中的方法,并创建一个保留在Areas文件夹中的扩展。 我认为添加新Areas (作为新项目创建)时,将创建.pdb文件并将其放置在bin目录中。 我的问题是这样的: 如何将Areas分配为可插拔模块? 如何更改以下代码,以便当有人将新的Area放入bin文件夹时,应用程序会自动将其拾取并创建链接? 插件作者应该怎么做才能做到这一点? 在_Layout.cshtml (全局共享布局)中,我执行以下操作来构建链接: <ul> <li>@Html.ActionLink("Area1", "Index", "Area1", new { Area = "Area1" }, null)</li> <li>@Html.ActionLink("Area2", "Index", "Area2", new { Area = "Area2" }, null)</li> <li>@Html.ActionLink("Area3", "Index", "Area3", new { Area = "Area3" }, null)</li> </ul> 为简单起见,假设区域名称是唯一的。
  • Asp.Net MVC3: Set custom IServiceProvider in ValidationContext so validators can resolve services
    Update 18th December 2012 Since this question seems to be getting quite a few views, I should point out that the accepted answer is not the solution I used, but it does provide the links and resources to build a solution, but, to my mind, not the ideal solution. My answer contains replacements for standard parts of the MVC framework; and you should only use those if you are comfortable checking that they still work for future versions (some private code was ripped out of the official sources, because there wasn't enough extensibility in the base classes). I can confirm, however, that these two
  • 在部分视图中使用分页,asp.net mvc(Using paging in partial view, asp.net mvc)
    问题 如果有人可以提供以下建议,我将不胜感激:在我看来,我显示了项目列表: @model PagedList.IPagedList<Items> @using PagedList.Mvc; @foreach (var item in Model) {//displaying data} 我的寻呼机看起来像这样: @Html.PagedListPager(Model, page => Url.Action("Index", new { humanID = ViewBag.HumanID, page = page }), new PagedListRenderOptions { LinkToFirstPageFormat = "<<", LinkToPreviousPageFormat = "prev", LinkToNextPageFormat = "next", LinkToLastPageFormat = ">>", }) 问题是,当我单击下一页时,它将返回空白,而没有_Layout 。 我不想一直重新加载_Layout。 有没有一种方法可以将Ajax.ActionLink用于寻呼机? 这样我就可以在局部视图中使用UpdateTargedId吗? 回答1 您不能使用Ajax.ActionLink,但可以对链接进行AJAX。 将寻呼机放在<div> : <div id=