내가 작업중인 프로젝트에는 도메인 모델에 많은 통화 속성이 있으며보기와주고 받기 위해이 형식을 $#,###.##
으로 필요로합니다. 나는 사용할 수있는 다른 접근 방식에 대한 견해를 가지고있었습니다.ASP.NET MVC 사용자 지정 서식이있는 ViewModel 매핑
... 그러나 이것은 매우 빠르게 DRY principle을 위반 시작 : 한 가지 방법은 "Pattern 1" from Steve Michelotti 같이 뷰 내에서 명시 적으로 값을 포맷 할 수 있습니다.
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로 다시 매핑하는 방법은 무엇입니까? 나는 정의 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);
}
}
를 사용하여 시도 그리고 그것을 매핑했습니다
///<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));
}
...하지만 난 그 기분이 테스트를 만족
// from vm to dm
Mapper.CreateMap<ViewModel, DomainModel>()
.ForMember(dm => dm.CurrencyProperty,
mc => mc
.ResolveUsing<CurrencyResolver>()
.FromMember(vm => vm.CurrencyProperty));
속성이 동일한 이름을 가지고 있기 때문에
ResolveUsing
을 수행 한 후
FromMember
으로 매핑되는 속성을 명시 적으로 정의 할 필요가 없습니다. 이 매핑을 정의하는 방법은? 앞에서 언급했듯이이 방식으로 매핑해야하는 통화 값이있는 속성이 많이 있습니다.
그런데 - 전 세계적으로 일부 규칙을 정의하여 이러한 매핑을 자동으로 해결할 수있는 방법이 있습니까? 뷰 모델 속성이 이미 DataAnnotation
로 장식되어 검증을위한 [DataType(DataType.Currency)]
속성, 그래서 내가 않는 몇 가지 규칙을 정의 할 수 있다고 기대했다 : I는 각 보일러 설치의 양을 최소화 할 수 있도록 ...
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.NET MVC in Action에서
:
는 처음에 우리는 바로 보기에이 간단한 객체하지만, 날짜 시간을 통과 유혹 할 수 있는가? 모델에서 [ ] 속성을 사용하면 문제가 발생할 수 있습니다. 예를 들어 ToShortDateString() 또는 ToString()과 같이 형식을 선택해야합니다. 보기는 속성이 일 때 화면이 계속 날아 오지 않도록 확인하기 위해 강제로 null이됩니다. 조회수는 단위로하기가 어려우므로 최대한 얇게 유지해야합니다. . 보기의 결과는 응답 스트림으로 전달되는 문자열이므로 개의 문자열 전용 인 객체 만 사용합니다. 그 은, ToString()이 호출 될 때 결코 실패하지 않는 객체입니다. ConferenceForm 뷰 모델 개체는 입니다. 4.14를 나열하면 모든 속성이 문자열임을 알 수 있습니다. 이보기 모델 개체가보기 데이터에 배치되기 전에 우리는 적절하게 날짜를 으로 지정합니다. 이 방법,보기는 개체를 고려할 필요가 없으며 정보를 올바르게 형식화 할 수 있습니다.
<% = string.Format ("{0 : c}", Model.CurrencyProperty) %> 어쩌면 난 그냥 익숙해 져있을거야 ... –