我有一個MVC3應用程序,我使用EF4.1 Code First和POCO Classes。如何獲取ModelState鍵/模型屬性名稱以匹配?
我的問題涉及在我的POCO類中刪除硬編碼的「PropertyNames」,並且在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」只有一個消息,但是爲DOM中的「.input-validation-error」和「.field-validation-error」元素突出顯示了這兩個字段。
謝謝你,在屬性
感謝您的信息...我喜歡突出顯示的解決方案。我將不得不看看「CompareAttribute」,看看我能否得到這個工作。 – Raymond 2011-07-07 17:08:32
我可以建議不同的解決方案來突出顯示,因爲我的驗證是在服務器端使用ajax調用執行的,所返回的JSON結果包含有關無效HTML元素和驗證消息的信息。我可以設置突出顯示使用jQuery。 – 2011-07-07 19:12:09