ResourceMap not found error when referencing a res

2019-06-15 14:49发布

The problem I am facing has as follows:

I have developed a portable class library to encapsulate a service connection. Inside this class library there is a Resources.resw file containing strings. These strings are called only by methods of the class library (for example to override ToString() methods).

As I said this is a portable class library. If I reference it as a dll, or even as a project inside another solution, it gets built and compiles correctly. Then I make a call using a method of this library within my application, say

        ClientFacadeConnector connector = new ClientFacadeConnector();
        ICollection<SearchResult> results = null;
        string message = string.Empty;

        if (maxResults != -1) //Search with max Results
        {
            try
            {
                if (!contextQuery.Trim().Equals(string.Empty))
                {

                    results = await connector.GetConnected().SearchAsync(contextQuery, query, maxResults);
                    message = "Search with ContextQuery " + contextQuery + ", Query " + query + ", max results " + maxResults.ToString();
                }
                else
                {

                    results = await connector.GetConnected().SearchAsync(query, maxResults, true);
                    message = "...using normal Query search, Query " + query + ", max results " + maxResults.ToString();
                }
            }
            catch (IQserException ex)
            {
                message = ex.Message;
            }
        }


        if (results != null)
        {
            ICollection<LocalSearchResult> contentResults = new List<LocalSearchResult>();
            foreach (SearchResult s in results)
            {
                var q = s.ToString();
                var contentItem = await connector.GetConnected().GetContentAsync(s.ContentId);
                LocalSearchResult lContent = new LocalSearchResult(contentItem);
                lContent.Score = s.Score;
                lContent.Relevance = s.Relevance;
                lContent.MarkFullText(query);
                contentResults.Add(lContent);
            }

At the point where I call s.ToString() method, I get an error "Resource Map not found".

To explain where this comes from:

public static class AppResources
{
    private static ResourceLoader resourceLoader;

    static AppResources()
    {
        // Load local file Resources.resw by default
        resourceLoader = new ResourceLoader();            
    }

    public static string GetResources(string key)
    {
        if (string.IsNullOrEmpty(key))
            throw new ArgumentNullException("key");

        return resourceLoader.GetString(key);
    }

}

and inside the overridden ToString() method there is code that looks as follows:

    public override string ToString()
    {
        StringBuilder buf = new StringBuilder(AppResources.GetResources("InstrSearchResultContent"));

        if (ContentId != -1)
        {
            buf.Append(AppResources.GetResources("StringContent") + " ID:" + ContentId.ToString() + " | ");
        }
        else
        {
            buf.Append(AppResources.GetResources("StringNo") + AppResources.GetResources("StringContent") + "ID" + " | ");
        }
        ...

The resource file is called resources.resw and is the default resw file that ResourceLoader calls if no other is called.

Strangely enough, if I copy the resource file inside the client application locally, it is referenced correctly by all calls to the class library resource file and everything works.

This class library is supposed to be an SDK when finished. Do I need to distribute the resource file separately?

Such a problem I have never experienced with normal Class libraries and resx files. Resw is giving me the creeps..

5条回答
欢心
2楼-- · 2019-06-15 15:00

I had a similar issue which i resolved by changing the Build Action of the resw file to PRIResource in the properties. I had renamed an existing resx to resw but the documentation doesn't mention that you also have to change the build action.

查看更多
老娘就宠你
3楼-- · 2019-06-15 15:00

I faced a similar issue when developing a UWP app with a class library. So I have a /Strings/en-Us/Resource.resw file in my library.

ResourceLoader.GetForCurrentView().GetString("someKey");

gives an exception

 new ResourceLoader("Company.Lib/Resources").GetString("someKey");

gives me a deprecation warning but works.

My solution which does not give a warning is this:

ResourceLoader.GetForViewIndependentUse("AssemblyNamespace/Resources").GetString("someKey");
查看更多
小情绪 Triste *
4楼-- · 2019-06-15 15:08

I also had similar issue even with repeating all steps from How to load string resources. The problem was that my Resources.resw file was empty. When I added some fake string to it all started working as expected.

查看更多
狗以群分
5楼-- · 2019-06-15 15:16

It looks like you have to specify the name of the resource map when you create the ResourceLoader, like this:

resourceLoader = new ResourceLoader("Assembly/ResourceFile");

For example, if your class library was called "Company.Lib.dll", and your resource file was "Resources.resw", you would use:

resourceLoader = new ResourceLoader("Company.Lib/Resources");

This doesn't seem to be documented fully on MSDN - it suggests that you can just specify the name of your resource file, but it might be that that only works for resource files that are in the Windows Store application project. It was this page that showed me that, for libraries, you need to specify the assembly name as well.

查看更多
Melony?
6楼-- · 2019-06-15 15:20

Accepted answer posted by @Rory MacLeod may no longer be true. I tried and VS warned that ResourceLoader(String) is deprecated. The following worked in my case:

var loader = ResourceLoader.GetForCurrentView();
string localName = loader.GetString("someKey");
查看更多
登录 后发表回答