全球化MVCSiteMapProvider [英] Globalization in MVCSiteMapProvider

查看:195
本文介绍了全球化MVCSiteMapProvider的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

喜有一个网站地图上像这样我的MVC应用4:

Hi have a sitemap on my mvc 4 application like this:

<?xml version="1.0" encoding="utf-8" ?>
<mvcSiteMap 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-4.0"
            xsi:schemaLocation="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-4.0 MvcSiteMapSchema.xsd">
    <mvcSiteMapNode title="Users" controller="User" action="Index" area="" preservedRouteParameters="culture,projectid">
        <mvcSiteMapNode title="New" controller="User" action="Create" area="" preservedRouteParameters="culture,projectid"/>
        <mvcSiteMapNode title="Edit" controller="User" action="Edit" area="" preservedRouteParameters="culture,projectid,id"/>
        <mvcSiteMapNode title="Profile" controller="User" action="Details" area="" preservedRouteParameters="culture,projectid,id"/>            
    </mvcSiteMapNode>
</mvcSiteMap>

我在另一个项目中,我使用的全球化我的应用程序资源少的文件,我需要在一个单独的项目的资源文件,因为它像DDL几个项目使用。

I have few resources files in another project that i use for globalize my app, I need the resources files in a separate project because its used in few projects like ddl.

我如何能为我的网站地图实现全球化?

How can i implement globalization for my sitemap?

推荐答案

我想借此将切换到外部DI,然后实现可以从另一个程序集读取资源的自定义IStringLocalizer类的方法。这里是一个工作的例子。我创建了一个演示应用在GitHub上也是如此。

The approach I would take would be to switch to external DI and then implement a custom IStringLocalizer class that can read the resources from another assembly. Here is a working example. I have created a demo application on GitHub as well.

using System;
using System.Collections.Specialized;
using System.Resources;

namespace MvcSiteMapProvider.Globalization
{
    public class ResourceManagerStringLocalizer
        : IStringLocalizer
    {
        public ResourceManagerStringLocalizer(
            ResourceManager resourceManager
            )
        {
            if (resourceManager == null)
                throw new ArgumentNullException("resourceManager");
            this.resourceManager = resourceManager;
        }
        protected readonly ResourceManager resourceManager;

        /// <summary>
        /// Gets the localized text for the supplied attributeName.
        /// </summary>
        /// <param name="attributeName">The name of the attribute (as if it were in the original XML file).</param>
        /// <param name="value">The current object's value of the attribute.</param>
        /// <param name="enableLocalization">True if localization has been enabled, otherwise false.</param>
        /// <param name="classKey">The resource key from the ISiteMap class.</param>
        /// <param name="implicitResourceKey">The implicit resource key.</param>
        /// <param name="explicitResourceKeys">A <see cref="T:System.Collections.Specialized.NameValueCollection"/> containing the explicit resource keys.</param>
        /// <returns></returns>
        public virtual string GetResourceString(string attributeName, string value, bool enableLocalization, string classKey, string implicitResourceKey, NameValueCollection explicitResourceKeys)
        {
            if (attributeName == null)
            {
                throw new ArgumentNullException("attributeName");
            }

            if (enableLocalization)
            {
                string result = string.Empty;
                if (explicitResourceKeys != null)
                {
                    string[] values = explicitResourceKeys.GetValues(attributeName);
                    if ((values == null) || (values.Length <= 1))
                    {
                        result = value;
                    }
                    else if (this.resourceManager.BaseName.Equals(values[0]))
                    {
                        try
                        {
                            result = this.resourceManager.GetString(values[1]);
                        }
                        catch (MissingManifestResourceException)
                        {
                            if (!string.IsNullOrEmpty(value))
                            {
                                result = value;
                            }
                        }
                    }
                }
                if (!string.IsNullOrEmpty(result))
                {
                    return result;
                }
            }
            if (!string.IsNullOrEmpty(value))
            {
                return value;
            }

            return string.Empty;
        }
    }
}

然后你可以把它注射到你的DI配置模块(如图StructureMap的例子,但所有的DI容器都可以)。

Then you can inject it into your DI configuration module (StructureMap example shown, but any DI container will do).

首先,你需要指定不将其添加到excludeTypes变量自动注册IStringLocalizer接口。

First of all, you need to specify not to register the IStringLocalizer interface automatically by adding it to the excludeTypes variable.

var excludeTypes = new Type[] {
// Use this array to add types you wish to explicitly exclude from convention-based  
// auto-registration. By default all types that either match I[TypeName] = [TypeName] or 
// I[TypeName] = [TypeName]Adapter will be automatically wired up as long as they don't 
// have the [ExcludeFromAutoRegistrationAttribute].
//
// If you want to override a type that follows the convention, you should add the name 
// of either the implementation name or the interface that it inherits to this list and 
// add your manual registration code below. This will prevent duplicate registrations 
// of the types from occurring. 

// Example:
// typeof(SiteMap),
// typeof(SiteMapNodeVisibilityProviderStrategy)
    typeof(IStringLocalizer)
};

然后提供ResourceManagerStringLocalizer(及其依赖)的显式注册,而不是

Then provide an explicit registration of the ResourceManagerStringLocalizer (and its dependencies) instead.

// Configure localization

// Fully qualified namespace.resourcefile (.resx) name without the extension
string resourceBaseName = "SomeAssembly.Resources.Resource1";

// A reference to the assembly where your resources reside.
Assembly resourceAssembly = typeof(SomeAssembly.Class1).Assembly;

// Register the ResourceManager (note that this is application wide - if you are 
// using ResourceManager in your DI setup already you may need to use a named 
// instance or SmartInstance to specify a specific object to inject)
this.For<ResourceManager>().Use(() => new ResourceManager(resourceBaseName, resourceAssembly));

// Register the ResourceManagerStringLocalizer (uses the ResourceManger)
this.For<IStringLocalizer>().Use<ResourceManagerStringLocalizer>();

然后,它仅仅是一个适当地指定资源的问题。您需要与基地名称启动它们(在这种情况下, SomeAssembly.Resources.Resource1 ),然后指定的资源作为第二个参数的关键。

Then it is just a matter of specifying the resources appropriately. You need to start them with the Base Name (in this case SomeAssembly.Resources.Resource1), and then specify the key of the resource as the second argument.

<mvcSiteMapNode title="$resources:SomeAssembly.Resources.Resource1,ContactTitle" controller="Home" action="Contact"/>

或者

[MvcSiteMapNode(Title = "$resources:SomeAssembly.Resources.Resource1,ContactTitle", Controller = "Home", Action = "Contact)]

注意在获取基本名称权的关键在于使其工作。请参阅以下MSDN文档:的http:// MSDN。 microsoft.com/en-us/library/yfsz7ac5(v=vs.110).aspx

这篇关于全球化MVCSiteMapProvider的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆