PDA

View Full Version : Help w/ ASP.NET resources



andrew1906
06-28-2006, 10:36 PM
I'm at a bit of a loss with customizing the ASP.NET resource locator. My goal is this - I want to have custom XML files that act as resource files for a given page. I'm using Model-View-Controller - so one view might have 10 different functions, and thus have ten separate XML resource files that provide labels for buttons, headers, etc. For instance - I might have a <B>Bulleted List</B> view that displays a list of items, but in my application, I might have to display a Grocery List, a Todo List, and a DVD list. Thus, the header and buttons on that view would have to change each time, and since I'm supporting localization, then have the take into account culture. Not to mention, for a given client, I MIGHT want to overload the text.

Given that, my goal is to take an XML file from a database and APPLY it to a view a run-time. I've tried to implement ILocalizer and did the following:


/// <summary>
/// Provides localization via XML command files
/// </summary>
public class XmlLocalizer : AbstractLocalizer
{

/// <summary>
/// The template to use for localization
/// </summary>
private XmlDocument _template;

public XmlLocalizer( XmlDocument template )
{
_template = template;
}

protected override System.Collections.IList LoadResources( object target, global::Spring.Context.IMessageSource messageSource, System.Globalization.CultureInfo culture )
{
Debug.Assert( _template != null, "No template has been defined" );

ArrayList resources = new ArrayList();


XmlElement resourceNode = (XmlElement) _template.SelectSingleNode( "//Invariant" );

foreach( XmlElement xe in resourceNode.ChildNodes )
{
Resource r = new Resource( Expression.Parse( xe.GetAttribute( "Name" ) ), xe.GetAttribute("Value" ) );

resources.Add( r );
}


return resources;
}


}

I pass it the following XML:


<Localization>
<Invariant>
<Resource Name="btnAdd.Text" Value="Add your name here"/>

</Invariant>

</Localization>

This works fine. But now, I want to internationalize it. So I want to pass it something like:


<Localization>
<Invariant>
<Resource Name="btnAdd.Text" Value="Add your name here"/>

</Invariant>
<Culture name='en'>
<Resource Name="btnAdd.Text" Value="Add your name here"/>

</Culture>
<Culture name='en-us'>
<Resource Name="btnAdd.Text" Value="Add your name here, dude"/>

</Culture>
</Localization>

... and then have my code correctly resolve to the appropriate culture. I looked through your <B>AbstractLocalizer</B> and I see that you somehow do this with a ResourceManager and ResourceSet, but I don't think those are applicable to me because I'm not using Resource files.

How do you all suggest I proceed?

Also... what is the IMessageSource in the ILocalizer for?

andrew1906
07-18-2006, 03:26 PM
Thanks!
Andrew

Aleks Seovic
07-28-2006, 11:11 PM
Yes, sorry it took so long, but I didn't have much time to look at the forums lately :(

There are two problems with your code:

1. You only load invariant resources

XmlElement resourceNode = (XmlElement) _template.SelectSingleNode( "//Invariant" );

What you really need here is something like

XmlElement resourceNode = (XmlElement) _template.SelectSingleNode( "//Culture[@name = '" + culture.Name + "']" );

That would actually return the node for the appropriate culture instead of always returning Invariant node.

2. The approach is wrong because you really shouldn't be loading resources from the XML file within ILocalizer implementation. What you need is an XmlMessageSource implementation that will be responsible for loading resources properly.

All ILocalizer.LoadResources implementation should do is decide which of the resources from the message source should be automatically applied (which is basically the only thing localizer does).

HTH,

Aleks

andrew1906
07-31-2006, 05:08 PM
OK, I looked at the IMessageSource and IAbstractMessageSource code and think I know what to do... I should implement an XmlMessageSource method derived from AbstractMessageSource. What I don't understand, however, is what the ApplyResourceToObject method does or should do in my implementation.

And fundamentally, I don't know that I understand what a "message" is. It looks like your abstracting away the idea of a resource into a type of message - but I'm not sure why. Is there anything I can read to clear this up?

Andrew

andrew1906
08-15-2006, 09:43 PM
Anyone have an answer to this follow up question?