我正在处理的项目在域模型中有大量的货币属性,我需要将它们格式化为
$#,###.##
用于在视图中来回传输。我对可以使用的不同方法有自己的看法。一种方法是在视图中显式格式化值,如
"Pattern 1" from Steve Michelotti
DRY principle
很快。
ASP.NET MVC in Action
第4.4.1节和
"Pattern 3"
[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
class 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));
}
... 但是我觉得我不需要显式地定义它从哪个属性映射
FromMember
之后
ResolveUsing
由于属性具有相同的名称-是否有更好的方法来定义此映射?正如我所提到的,有许多具有货币值的属性需要以这种方式进行映射。
也就是说,有没有一种方法可以通过全局定义一些规则来自动解析这些映射?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>()
... 这样我就可以最小化每种对象类型的样板文件设置量。
我还想了解一下在视图中实现自定义格式的其他策略。
ASP.NETMVC正在运行
:
一开始,我们可能想通过考试
视图,但日期时间?性质
[在模型中]将导致问题。
例如,我们需要选择一个
为它们设置格式,例如
视图将被强制执行null
无效的观点很难统一
测试,所以我们想让他们保持苗条
视图是传递给
响应流,仅限使用
是指当
ConferenceForm视图模型对象是一个
这方面的例子。上市公告
4.14所有属性都是字符串。我们会把日期安排妥当的
在此视图模型之前格式化
对象放置在视图数据中。这
方式、观点不必考虑
对象,它可以格式化
正确地提供信息。