У меня есть приложение MVC3, я использую EF4.1 Code First и POCO классы.
Мой вопрос состоит в том, чтобы избавиться от жестко запрограммированных «PropertyNames» в моем классе POCO, а также предварительно исправить его с соответствующими значениями в ModelState, чтобы сообщение проверки появилось правильно.
В моем классе POCO есть метод, который выглядит следующим образом.
Вы заметите, что я также использую код «DataAnnotations.Validator» для повторного использования проверки аннотаций данных.
public class TaxCode : ModelBusinessObjectBase
{
//...
[Required]
[DataType(DataType.Date)]
[DisplayName("Effective Date")]
public DateTime EffectiveDate
{
get { return _effectiveDate; }
set { _effectiveDate = value; }
}
[Required]
[DataType(DataType.Date)]
[DisplayName("Expiry Date")]
public DateTime ExpiryDate
{
get { return _expiryDate; }
set { _expiryDate = value; }
}
//...
public override IEnumerable<ValidationResult> GetValidationResults()
{
//---- data annotation validation ----
ValidationContext validationContext = new ValidationContext(this, null, null);
IList<ValidationResult> dataAnnotationValidationResults = new List<ValidationResult>();
bool isValid = Validator.TryValidateObject(this, validationContext, dataAnnotationValidationResults, true);
foreach (ValidationResult dataAnnotationValidationResult in dataAnnotationValidationResults)
yield return new ValidationResult(dataAnnotationValidationResult.ErrorMessage, dataAnnotationValidationResult.MemberNames);
//---- custom business rule validation ----
// expiry date must be greater than effective date
if (ExpiryDate <= EffectiveDate)
{
yield return new ValidationResult("Expiry Date must be after Effective Date", new [] {"EffectiveDate", "ExpiryDate"});
}
yield break;
}
В моем слое обслуживания я в конце концов назову что-то вроде этого:
public bool TryValidate(TaxCode domainObject)
{
if (!domainObject.IsValid)
{
_validationDictionary.AddValidationResults(domainObject.GetValidationResults());
isValid = false;
}
return isValid;
}
И используя «ModelStateWrapper», код делает это:
public virtual void AddValidationResults(IEnumerable<ValidationResult> validationResults)
{
foreach (ValidationResult validationResult in validationResults)
{
_modelState.AddModelError(validationResult.MemberNames.First(), validationResult.ErrorMessage);
}
}
Моя модель просмотра такова:
public class TaxCodeViewModel : IPersistantBusinessObjectViewModel<TaxCode>
{
public TaxCodeViewModel()
{
}
public TaxCodeViewModel(TaxCode domainObj)
{
this.BusinessObject = domainObj;
}
}
И мой взгляд выглядит примерно так:
<%@ Control Language="C#" AutoEventWireup="true" Inherits="System.Web.Mvc.ViewUserControl<TaxCodeViewModel>" %>
//...
<% using (Html.BeginForm()) {%>
<%:Html.ValidationSummary(false, "Unable to save. Please correct the errors and try again.")%>
//...
<div class="editor-label">
<%:Html.LabelFor(model => model.BusinessObject.EffectiveDate)%>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.BusinessObject.EffectiveDate)%>
<%: Html.ValidationMessageFor(model => model.BusinessObject.EffectiveDate)%>
</div>
<br />
<div class="editor-label">
<%: Html.LabelFor(model => model.BusinessObject.ExpiryDate)%>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.BusinessObject.ExpiryDate)%>
<%: Html.ValidationMessageFor(model => model.BusinessObject.ExpiryDate)%>
</div>
<br />
//...
Мой вопрос:
Как избежать использования жестко закодированных строк с именами свойств «Дата истечения срока действия»?
Из-за ViewModel ожидает, что ключ ModelState будет "BusinessObject.ExpiryDate". Как мне сделать так, чтобы мои свойства соответствовали? Как добавить префикс или удалить автоматически добавленный префикс?
Обратите внимание, что в настоящее время я использую validationResult.MemberNames.First ()).
В моем случае я хочу только одно сообщение в сводке проверки, но я бы хотел выделить ОБА свойства. то есть только одно сообщение для «.validation-summary-errors», но оба поля выделены для элементов «.input-validation-error» и «.field-validation-error» в DOM.
Спасибо,