ResourceMap not found error when referencing a resource file within a portable class library
Asked Answered
B

5

12

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..

Boardman answered 29/5, 2012 at 14:1 Comment(0)
Q
2

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");
Quetzalcoatl answered 12/9, 2014 at 20:51 Comment(3)
still getting the same error. Do we need to initialize something before this?Lilley
I dont think it is deprecated. I dont get any message like that in 2017 now. String parameter is used if you use different path than Strings default path I believeRhizoid
With ResourceLoader.GetForCurrentView() I'm getting the same error ("Resource Map not found"). The new ResourceLoader("Assembly/ResourceFile") solution is working, but accompanied with a deprecation warning.Raveaux
S
13

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.

Slyke answered 4/4, 2013 at 14:53 Comment(0)
C
8

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.

Conciliar answered 18/7, 2013 at 11:33 Comment(0)
F
4

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.

Furnish answered 5/12, 2012 at 16:5 Comment(0)
Q
2

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");
Quetzalcoatl answered 12/9, 2014 at 20:51 Comment(3)
still getting the same error. Do we need to initialize something before this?Lilley
I dont think it is deprecated. I dont get any message like that in 2017 now. String parameter is used if you use different path than Strings default path I believeRhizoid
With ResourceLoader.GetForCurrentView() I'm getting the same error ("Resource Map not found"). The new ResourceLoader("Assembly/ResourceFile") solution is working, but accompanied with a deprecation warning.Raveaux
R
1

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");
Raveaux answered 11/9, 2017 at 21:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.