错误消息:模型没有选择特定于语言的资源文件

本文关键字:语言 源文件 资源 于语言 消息 模型 有选择 错误 | 更新日期: 2023-09-27 18:10:41

我想用西班牙语显示模型错误消息,我已经在资源文件中定义了这些字符串。我已经做了同样的页面上的其他字符串使用剃刀语法,但那些从ViewModel注释没有被选中。

它实际上是选择默认值-英语。所以我猜可能是没有检测到语言/文化,但页面上的其他字符串显示为西班牙语

//Spanish: El campo {0} se requiere
//English: The {0} field is required  <--- this comes out always irrespective of set language
[Required(ErrorMessageResourceName = "ErrorMessage_Required", 
     ErrorMessageResourceType = typeof(GlobalResources.Resources))]
[Display(Name = "CardNumber", ResourceType = typeof(GlobalResources.Resources) )]
public string CardNumber { get; set; }

我在控制器中设置了语言

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
    base.OnActionExecuting(filterContext);
    HttpCookie cookie = Request.Cookies["lang"];
    string lang = cookie != null ? cookie.Value : "en-US";
    System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(lang);
}

如何将文化设置扩展到ViewModels?

类似的帖子:MVC3全球化:在模型绑定之前需要全局过滤器

在我的浏览器设置中更改首选语言使其正常工作。这意味着模型属性正在使用不受System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(lang);影响的设置。有办法让这发生吗?-仍在搜索....

Update:将代码移动到Application_AcquireRequestState似乎解决了这个问题。

protected void Application_AcquireRequestState()
{
    HttpCookie cookie = Request.Cookies["lang"];
    string lang = cookie != null ? cookie.Value : "en-US";
    System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(lang);
}

我得到的解释,也在这个问题中发布的链接中发现,对于模型来说,利用在控制器覆盖方法中设置的区域性已经太晚了,因为在调用方法之前绑定已经发生。这个链接很有帮助

错误消息:模型没有选择特定于语言的资源文件

尝试使用下面的class

public sealed class LanguageManager
{
    /// <summary>
    /// Default CultureInfo
    /// </summary>
    public static readonly CultureInfo DefaultCulture = new CultureInfo("en-US");
    /// <summary>
    /// Available CultureInfo that according resources can be found
    /// </summary>
    public static readonly CultureInfo[] AvailableCultures;
    static LanguageManager()
    {
        List<string> availableResources = new List<string>();
        string resourcespath = Path.Combine(System.Web.HttpRuntime.AppDomainAppPath, "App_GlobalResources");
        DirectoryInfo dirInfo = new DirectoryInfo(resourcespath);
        foreach (FileInfo fi in dirInfo.GetFiles("*.*.resx", SearchOption.AllDirectories))
        {
            //Take the cultureName from resx filename, will be smt like en-US
            string cultureName = Path.GetFileNameWithoutExtension(fi.Name); //get rid of .resx
            if (cultureName.LastIndexOf(".") == cultureName.Length - 1)
                continue; //doesnt accept format FileName..resx
            cultureName = cultureName.Substring(cultureName.LastIndexOf(".") + 1);
            availableResources.Add(cultureName);
        }
        List<CultureInfo> result = new List<CultureInfo>();
        foreach (CultureInfo culture in CultureInfo.GetCultures(CultureTypes.SpecificCultures))
        {
            //If language file can be found
            if (availableResources.Contains(culture.ToString()))
            {
                result.Add(culture);
            }
        }
        AvailableCultures = result.ToArray();
        CurrentCulture = DefaultCulture;
        if (!result.Contains(DefaultCulture) && result.Count > 0)
        {
            CurrentCulture = result[0];
        }
    }
    /// <summary>
    /// Current selected culture
    /// </summary>
    public static CultureInfo CurrentCulture
    {
        get { return Thread.CurrentThread.CurrentCulture; }
        set
        {
            Thread.CurrentThread.CurrentUICulture = value;
            Thread.CurrentThread.CurrentCulture = value;
        }
    }
}

最后设置如下所示的文化。

LanguageManager.CurrentCulture = new CultureInfo("Your culture");
现在重写区域性

确保同时设置 CurrentCultureCurrentUICulture。我怀疑CurrentCulture实际上是资源文件正在查看的内容:

 //I've taken off System.Threading, add a using to it (aids readability)
 Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(lang);
 Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(lang);