我正在使用Umbraco 7.2.4()制作一个多语言网站。Net MVC 4.5)。我在主节点下嵌套了每种语言的页面,具有各自的文化:
- 主页(语言选择)
- nl-BE
- 某些页面
- 其他页面
- 我的表单页
- fr-BE
- 某些页面
- 其他页面
- 我的表单页
- nl-BE
表单模型用验证属性装饰,我需要为每种语言翻译这些属性。我发现了一个Github项目,Umbraco Validation Attributes,它扩展了装饰属性,从Umbraco字典项中检索验证消息。它可以很好地处理页面内容,但不能处理验证消息。
问题- 降落在nl-BE/form
- 字段标签以荷兰语(nl-BE)显示
- 提交无效表单
- 验证消息以荷兰语(nl-BE文化)显示
- 浏览到fr-BE/格式
- 字段标签以法语(fr-BE)显示
- 提交无效表单
- 预期行为是:验证消息以法语(fr-BE文化)显示
- 实际行为是:消息仍然以荷兰语显示(data- value -required属性在页面源中是荷兰语)
调查至今
这不是浏览器缓存问题,它可以在不同的浏览器,甚至不同的计算机上重现:无论是谁第一次生成表单都会锁定验证消息文化。更改验证消息语言的唯一方法是回收应用程序池。
我怀疑Umbraco验证辅助类是这里的问题,但我没有想法,所以任何见解都是赞赏的。
源代码模型public class MyFormViewModel : RenderModel
{
public class PersonalDetails
{
[UmbracoDisplayName("FORMS_FIRST_NAME")]
[UmbracoRequired("FORMS_FIELD_REQUIRED_ERROR")]
public String FirstName { get; set; }
}
}
视图@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
var model = new MyFormViewModel();
using (Html.BeginUmbracoForm<MyFormController>("SubmitMyForm", null, new {id = "my-form"}))
{
<h3>@LanguageHelper.GetDictionaryItem("FORMS_HEADER_PERSONAL_DETAILS")</h3>
<div class="field-wrapper">
@Html.LabelFor(m => model.PersonalDetails.FirstName)
<div class="input-wrapper">
@Html.TextBoxFor(m => model.PersonalDetails.FirstName)
@Html.ValidationMessageFor(m => model.PersonalDetails.FirstName)
</div>
</div>
注意:我已经使用了本地MVC Html。BeginForm方法,结果相同。
控制器public ActionResult SubmitFranchiseApplication(FranchiseFormViewModel viewModel)
{
if (!ModelState.IsValid)
{
TempData["Message"] = LanguageHelper.GetDictionaryItem("FORMS_VALIDATION_FAILED_MESSAGE");
foreach (ModelState modelState in ViewData.ModelState.Values)
{
foreach (ModelError error in modelState.Errors)
{
TempData["Message"] += "<br/>" + error.ErrorMessage;
}
}
return RedirectToCurrentUmbracoPage();
}
}
LanguageHelper
public class LanguageHelper
{
public static string CurrentCulture
{
get
{
return UmbracoContext.Current.PublishedContentRequest.Culture.ToString();
// I also tried using the thread culture
return System.Threading.Thread.CurrentThread.CurrentCulture.ToString();
}
}
public static string GetDictionaryItem(string key)
{
var value = library.GetDictionaryItem(key);
return string.IsNullOrEmpty(value) ? key : value;
}
}
所以我终于找到了一个解决方法。为了将我的应用简化为最简单的形式并进行调试,我最终重新创建了"umbracrequired"装饰属性。当ErrorMessage在构造函数中而不是在GetValidationRules方法中设置时,就会出现这个问题。似乎MVC正在缓存构造函数的结果,而不是每次加载表单时再次调用它。为ErrorMessage添加一个动态属性到umbracrequired类也可以。
下面是我的自定义类最后的样子。
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter,
AllowMultiple = false)]
internal class LocalisedRequiredAttribute : RequiredAttribute, IClientValidatable
{
private string _dictionaryKey;
public LocalisedRequiredAttribute(string dictionaryKey)
{
_dictionaryKey = dictionaryKey;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(
ModelMetadata metadata, ControllerContext context)
{
ErrorMessage = LanguageHelper.GetDictionaryItem(_dictionaryKey); // this needs to be set here in order to refresh the translation every time
yield return new ModelClientValidationRule
{
ErrorMessage = this.ErrorMessage, // if you invoke the LanguageHelper here, the result gets cached and you're locked to the current language
ValidationType = "required"
};
}
}