asp.net-mvc – 使用自定义格式的ASP.NET MVC ViewModel映射
我正在处理的项目在域模型中有大量的货币属性,我需要将它们格式化为$#,###.##,用于传输到视图和从视图传输.我已经对可以使用的不同方法有了一些看法.一种方法可以是在视图中显式格式化值,如 “Pattern 1” from Steve Michelotti中所示: ……但这很快就违反了DRY principle. 首选方法似乎是在DomainModel和ViewModel之间的映射期间进行格式化(根据ASP.NET MVC in Action第4.4.1和“Pattern 3”节).使用AutoMapper,这将导致一些代码如下所示: [TestFixture] public class ViewModelTests { [Test] public void DomainModelMapsToViewModel() { var domainModel = new DomainModel {CurrencyProperty = 19.95m}; var viewModel = new ViewModel(domainModel); Assert.That(viewModel.CurrencyProperty,Is.EqualTo("$19.95")); } } public class DomainModel { public decimal CurrencyProperty { get; set; } } public class ViewModel { ///<summary>Currency Property - formatted as $#,###.##</summary> public string CurrencyProperty { get; set; } ///<summary>Setup mapping between domain and view model</summary> static ViewModel() { // map dm to vm Mapper.CreateMap<DomainModel,ViewModel>() .ForMember(vm => vm.CurrencyProperty,mc => mc.AddFormatter<CurrencyFormatter>()); } /// <summary> Creates the view model from the domain model.</summary> public ViewModel(DomainModel domainModel) { Mapper.Map(domainModel,this); } public ViewModel() { } } public class CurrencyFormatter : IValueFormatter { ///<summary>Formats source value as currency</summary> public string FormatValue(ResolutionContext context) { return string.Format(CultureInfo.CurrentCulture,"{0:c}",context.SourceValue); } } 使用IValueFormatter这种方式效果很好.现在,如何将它从DomainModel映射回ViewModel?我尝试过使用自定义类CurrencyResolver:ValueResolver< string,decimal> public class CurrencyResolver : ValueResolver<string,decimal> { ///<summary>Parses source value as currency</summary> protected override decimal ResolveCore(string source) { return decimal.Parse(source,NumberStyles.Currency,CultureInfo.CurrentCulture); } } 然后将其映射为: // from vm to dm Mapper.CreateMap<ViewModel,DomainModel>() .ForMember(dm => dm.CurrencyProperty,mc => mc .ResolveUsing<CurrencyResolver>() .FromMember(vm => vm.CurrencyProperty)); 哪个会满足这个测试: ///<summary>DomainModel maps to ViewModel</summary> [Test] public void ViewModelMapsToDomainModel() { var viewModel = new ViewModel {CurrencyProperty = "$19.95"}; var domainModel = new DomainModel(); Mapper.Map(viewModel,domainModel); Assert.That(domainModel.CurrencyProperty,Is.EqualTo(19.95m)); } …但我觉得在执行ResolveUsing之后我不需要显式定义它与FromMember映射的属性,因为属性具有相同的名称 – 是否有更好的方法来定义此映射?正如我所提到的,有许多具有货币值的属性需要以这种方式映射. 话虽如此 – 有没有办法通过全局定义一些规则来自动解决这些映射? ViewModel属性已经使用DataAnnotation属性[DataType(DataType.Currency)]进行了修饰,因此我希望我可以定义一些规则: if (destinationProperty.PropertyInfo.Attributes.Has(DataType(DataType.Currency)) then Mapper.Use<CurrencyFormatter>() if (sourceProperty.PropertyInfo.Attributes.Has(DataType(DataType.Currency)) then Mapper.Use<CurrencyResolver>() …这样我就可以最小化每种对象类型的样板设置量. 我也有兴趣听到任何可以在View中完成自定义格式化的替代策略. 从ASP.NET MVC in Action:
解决方法您正在寻找自定义TypeConverter:Mapper.CreateMap<string,decimal>().ConvertUsing<MoneyToDecimalConverter>(); 然后创建转换器: public class MoneyToDecimalConverter : TypeConverter<string,decimal> { protected override decimal ConvertCore(string source) { // magic here to convert from string to decimal } } (编辑:4S站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net – 将ViewState移出页面?
- asp.net-mvc – 从视图到控制器POST信用卡数据是否安全?
- iis-7.5 – 使用虚拟目录/应用程序在IIS中托管ASP.NET 5 We
- asp.net-core – 编译netcoreapp1.0,代码包含#if!NETSTAND
- asp.net-mvc – 使用没有ORM的ASP.NET MVC
- asp.net-mvc – MVC3验证与实体框架模型/数据库首先
- asp.net-mvc – 路由是在我的区域中找到控制器,但不是视图
- asp.net – HttpWebRequest正在为404抛出异常
- asp.net-mvc – 使用ASP.Net MVC中的模型绑定器更新父/子记
- asp.net汉字转拼音和获取汉字首字母的代码
- asp.net-mvc-4 – MVC 4 DropDownListFor错误 –
- asp.net-mvc – .Net 4.5.1框架的maxRequestLeng
- asp.net-mvc-3 – 在使用Unity容器时为此对象异常
- ASP.Net中的图形(c#)
- asp.net-mvc – 删除布局将默认为_ViewStart,为什
- ASP.Net MVC cookies – 防篡改?
- asp.net – Oracle.ManagedDataAccess:TNS:无法
- 认证 – asp.net mvc 3:Page.User.IsInRole(“x
- 经典ASP和UTF-8
- asp.net fileupload控件上传文件与多文件上传