上記のコメントで述べたように、リフレクションを使用して同様のことを行いました。その一部は無視できます。たとえば、辞書はおそらく必要ありません。これは、カスタムの翻訳可能なメッセージを提供する方法にすぎないためです。
サーバー側コード:
private static Dictionary<string, ILocalisationToken> _requiredValidationDictionary;
private static Dictionary<string, ILocalisationToken> RequiredValidationDictionary(UserBase model)
{
if (_requiredValidationDictionary != null)
return _requiredValidationDictionary;
_requiredValidationDictionary = new Dictionary<string, ILocalisationToken>
{
{ model.GetPropertyName(m => m.Publication), ErrorMessageToken.PublicationRequired},
{ model.GetPropertyName(m => m.Company), ErrorMessageToken.CompanyRequired},
{ model.GetPropertyName(m => m.JobTitle), ErrorMessageToken.JobTitleRequired},
{ model.GetPropertyName(m => m.KnownAs), ErrorMessageToken.KnownAsRequired},
{ model.GetPropertyName(m => m.TelephoneNumber), ErrorMessageToken.TelephoneNoRequired},
{ model.GetPropertyName(m => m.Address), ErrorMessageToken.AddressRequired},
{ model.GetPropertyName(m => m.PostCode), ErrorMessageToken.PostCodeRequired},
{ model.GetPropertyName(m => m.Country), ErrorMessageToken.CountryRequired}
};
return _requiredValidationDictionary;
}
internal static void SetCustomRequiredFields(List<string> requiredFields, UserBase model, ITranslationEngine translationEngine)
{
if (requiredFields == null || requiredFields.Count <= 0) return;
var tokenDictionary = RequiredValidationDictionary(model);
//Loop through requiredFields and add Display text dependant on which field it is.
foreach (var requiredField in requiredFields.Select(x => x.Trim()))
{
ILocalisationToken token;
if (!tokenDictionary.TryGetValue(requiredField, out token))
token = LocalisationToken.GetFromString(string.Format("{0} required", requiredField));
//add to the model.
model.RequiredFields.Add(new RequiredField
{
FieldName = requiredField,
ValidationMessage = translationEngine.ByToken(token)
});
}
}
internal static void CheckForRequiredField<T>(ModelStateDictionary modelState, T fieldValue, string fieldName, IList<string> requiredFields, Dictionary<string, ILocalisationToken> tokenDictionary)
{
ILocalisationToken token;
if (!tokenDictionary.TryGetValue(fieldName, out token))
token = LocalisationToken.GetFromString(string.Format("{0} required", fieldName));
if (requiredFields.Contains(fieldName) && (Equals(fieldValue, default(T)) || string.IsNullOrEmpty(fieldValue.ToString())))
modelState.AddModelError(fieldName, token.Translate());
}
internal static void CheckForModelErrorForCustomRequiredFields(UserBase model, Paladin3DataAccessLayer client, ICache cache, ModelStateDictionary modelState)
{
var requiredFields = Common.CommaSeparatedStringToList (client.GetSettingValue(Constants.SettingNames.RequiredRegistrationFields, cache: cache, defaultValue: String.Empty, region: null)).Select(x => x.Trim()).ToList();
var tokenDictionary = RequiredValidationDictionary(model);
foreach (var property in typeof(UserBase) .GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
{
CheckForRequiredField(modelState, property.GetValue(model, null), property.Name, requiredFields, tokenDictionary);
}
}
モデルには、List<RequiredField>
基本的に 2 つの文字列を持つクラスである があります。1 つはフィールド名用で、もう 1 つはエラー メッセージ用です。
モデルをビューに渡したら、サーバー側のチェックを行う場合は、ページに検証を追加するために少し jQuery が必要です。
クライアント側コード:
$("#YOURFORM").validate();
for (var x = 0; x < requiredFields.length; x++) {
var $field = $('#' + requiredFields[x].FieldName.trim());
if ($field.length > 0) {
$field.rules("add", {
required: true,
messages: {
required: "" + requiredFields[x].ValidationMessage
//required: "Required Input"
}
});
$field.parent().addClass("formRequired"); //Add a class so that the user knows its a required field before they submit
}
}
これのいずれかが非常に明確でない場合はお詫び申し上げます。ご不明な点がございましたら、お気軽にお問い合わせください。説明できるよう最善を尽くします。