Search code examples
c#asp.net-core.net-coreasp.net-core-1.0asp.net-core-localization

Localization in separate project Asp.net Core MVC


I just upgraded to Rc2 and what used to work no longer does. I have a couple of resx files in a separate project and I use a custom class to access the data. Now I get the following error when running it:

MissingManifestResourceException: Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "GarageWeb.Core.CoreResources.resources" was correctly embedded or linked into assembly "GarageWeb.Core" at compile time, or that all the satellite assemblies required are loadable and fully signed.

EDIT: I simplified this and create a console app that is stripped of everything but what is required to reproduce the error here: https://github.com/GarageWeb/ResourceTest

Here is the class that accesses the resources:

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;
    }
}

It fails here: var localizedString = _coreGlobalResources.ResourceManager.GetString(resourceKey);

Any ideas? Is there a new way to embed these resources?


Solution

  • So, if I move the .resx files to the root of the project instead of in a sub-folder, it works as expected. I have tried every way to embed from a sub-folder and it no longer works. For now I will use this workaround, but I suspect this is a bug in RC2.