【问题标题】:Localization in separate project Asp.net Core MVC在单独的项目 Asp.net Core MVC 中进行本地化
【发布时间】:2016-05-21 07:19:02
【问题描述】:

我刚刚升级到 Rc2,以前的工作不再有效。我在一个单独的项目中有几个 resx 文件,我使用自定义类来访问数据。现在运行时出现以下错误:

MissingManifestResourceException:找不到适合指定区域性或中性区域性的任何资源。确保“GarageWeb.Core.CoreResources.resources”在编译时被正确嵌入或链接到程序集“GarageWeb.Core”中,或者所有所需的附属程序集都是可加载的并且是完全签名的。

编辑:我对此进行了简化并创建了一个控制台应用程序,该应用程序除去了所有内容,但在此处重现错误所需的内容:https://github.com/GarageWeb/ResourceTest

这是访问资源的类:

public  class ResourceService : IResourceService
{
    private readonly ILoggingService _loggingService;
    private readonly ICoreGlobalResourceService _coreGlobalResources;
    private readonly ISiteGlobalResourceService _siteGlobalResources;
    public ResourceService(ILoggingService loggingService, ICoreGlobalResourceService coreGlobalResourceService, ISiteGlobalResourceService siteGlobalResources)
    {
        _loggingService = loggingService;
        _coreGlobalResources = coreGlobalResourceService;
        _siteGlobalResources = siteGlobalResources;
    }
    public  string GetGlobalText(string resourceKey, bool includeBrackets = true)
    {
        var localizedString = _coreGlobalResources.ResourceManager.GetString(resourceKey);
        if (string.IsNullOrEmpty(localizedString))
        {
            localizedString = _siteGlobalResources.ResourceManager.GetString(resourceKey);
        }
        if (string.IsNullOrEmpty(localizedString) && includeBrackets)
        {
           _loggingService.LogInvalidResource(resourceKey);
        }

        if (includeBrackets)
        {
            return localizedString ?? "[" + resourceKey + "]";
        }
        return localizedString ?? resourceKey;
    }

    public  string BuildMessageFromResource(string resourceKey, string placeHolderResourceKey1,
        bool includeBrackets = true)
    {
        var errorString = string.Format(CultureInfo.CurrentCulture, GetGlobalText(resourceKey, includeBrackets),
            GetGlobalText(placeHolderResourceKey1, includeBrackets));
        return errorString;
    }

    public  string BuildMessageFromResourceAndArray(string resourceKey, string[] arrayOfValues,
        bool includeBrackets = true)
    {
        var placeHolderValue = "";

        for (var i = 0; i < arrayOfValues.Length; i++)
        {
            if (i + 1 == arrayOfValues.Length)
            {
                placeHolderValue += GetGlobalText(arrayOfValues[i], includeBrackets);
            }
            else
            {
                placeHolderValue += GetGlobalText(arrayOfValues[i], includeBrackets) + ", ";
            }
        }

        var errorString = string.Format(CultureInfo.CurrentCulture, GetGlobalText(resourceKey, includeBrackets),
            placeHolderValue);
        return errorString;
    }

    public  string BuildMessageFromResourceAndTwoArrays(string resourceKey, string[] firstArrayOfValues,
        string[] secondArrayOfValues,
        bool includeBrackets = true)
    {
        var placeHolderOneValue = "";
        var placeHolderTwoValue = "";

        for (var i = 0; i < firstArrayOfValues.Length; i++)
        {
            if (i + 1 == firstArrayOfValues.Length)
            {
                placeHolderOneValue += GetGlobalText(firstArrayOfValues[i], includeBrackets);
            }
            else
            {
                placeHolderOneValue += GetGlobalText(firstArrayOfValues[i], includeBrackets) + ", ";
            }
        }
        for (var i = 0; i < secondArrayOfValues.Length; i++)
        {
            if (i + 1 == secondArrayOfValues.Length)
            {
                placeHolderTwoValue += GetGlobalText(secondArrayOfValues[i], includeBrackets);
            }
            else
            {
                placeHolderTwoValue += GetGlobalText(secondArrayOfValues[i], includeBrackets) + ", ";
            }
        }
        var errorString = string.Format(CultureInfo.CurrentCulture, GetGlobalText(resourceKey, includeBrackets),
            placeHolderOneValue, placeHolderTwoValue);
        return errorString;
    }

    public  string BuildMessageFromResource(string resourceKey, string placeHolderResourceKey1,
        string placeHolderResourceKey2, bool includeBrackets = true)
    {
        var errorString = string.Format(CultureInfo.CurrentCulture, GetGlobalText(resourceKey, includeBrackets),
            GetGlobalText(placeHolderResourceKey1, includeBrackets),
            GetGlobalText(placeHolderResourceKey2, includeBrackets));
        return errorString;
    }

    public  string BuildMessageFromResource(string resourceKey, string placeHolderResourceKey1,
        string placeHolderResourceKey2, string placeHolderResourceKey3,
        bool includeBrackets = true)
    {
        var errorString = string.Format(CultureInfo.CurrentCulture, GetGlobalText(resourceKey, includeBrackets),
            GetGlobalText(placeHolderResourceKey1, includeBrackets),
            GetGlobalText(placeHolderResourceKey2, includeBrackets),
            GetGlobalText(placeHolderResourceKey3, includeBrackets));
        return errorString;
    }
}

这里失败了:var distinctString = _coreGlobalResources.ResourceManager.GetString(resourceKey);

有什么想法吗?有没有新的方法来嵌入这些资源?

【问题讨论】:

  • 您是否嵌入了资源文件as outlined here
  • "buildOptions": { "embed": { "includeFiles": [ "Resources/CoreResources.resx", "Resources/SiteResources.resx" ] } }这是我嵌入文件的地方。这是在引用的 project.json
  • 您是否指定了保存资源的程序集的默认区域性?
  • 我在 Web 应用程序中设置了默认区域性,该区域性引用了这些资源所在的类库。我不确定我是否知道如何在类库本身中设置默认文化。
  • 这里是我设置语言并嵌入类库的地方:` "language": "en-US", "buildOptions": { "embed": { "include": [ "Resources " ] } }`

标签: c# asp.net-core .net-core asp.net-core-1.0 asp.net-core-localization


【解决方案1】:

因此,如果我将 .resx 文件移动到项目的根目录而不是子文件夹中,它会按预期工作。我已经尝试了从子文件夹嵌入的所有方法,但它不再有效。现在我将使用此解决方法,但我怀疑这是 RC2 中的错误。

【讨论】:

【解决方案2】:

就像你提到的,我也相信这是一个错误。我猜这么久,该错误位于自动生成设计器工具中。 出于奇怪的原因,以及为什么您的解决方法有效,该工具假定您将所有 resx 文件放在应用程序的根目录中。

这里是该工具的输出示例:

[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
    public static global::System.Resources.ResourceManager ResourceManager {
        get {
            if (object.ReferenceEquals(resourceMan, null)) {
                global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Cosmos.ViewModels.Default", typeof(Default).GetTypeInfo().Assembly);
                resourceMan = temp;
            }
            return resourceMan;
        }
    }

其中,Cosmos.ViewModels 是程序集名称,但 .resx 文件都集中在(对于我们当前的解决方案)Resources.da 命名空间,提供了一个完全限定的命名空间 Cosmos.ViewModels.Resources.da.

考虑到这一点,您可以将文件保留在您希望的位置,然后将Cosmos.ViewModels.Default 的硬编码字符串更改为Cosmos.ViewModels.Resources.da.Default

当然,该工具可能会再次意外删除您的更改。

我希望微软能解决这个问题。我在 github 上创建了一个问题,但我认为问题实际上应该在核心 cli 中。

MissingManifestResourceException from included assembly although present #1534

【讨论】:

    【解决方案3】:

    我使用的是 MVC Core 1.1.0,我可以在子文件夹中添加资源文件。当您尝试更改没有子文件夹的资源文件的命名空间时,它会引发错误。所以资源文件的命名空间和生成时一样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-03
      • 2017-06-22
      • 2019-01-28
      • 1970-01-01
      • 2021-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多