MVC网站地图提供商和本地化 [英] MVC Site Map Provider and localization

查看:299
本文介绍了MVC网站地图提供商和本地化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在发现,我的网站我可以用我已经从GitHub下载了一个MVC3网站地图提供商,因为我的web应用程序是MVC3。

I've found out today that for my site i could use a SiteMap provider which i've downloaded from Github for the MVC3, as my web application is MVC3.

情况下,我的应用程序是多国语言。我有一个单独的库,其中包含的所有资源。然后,这个库添加到我目前的项目,并处处,我需要我使用这些资源文件。

Situation is following, my application is multilingual. I have a separate Library which contains all the resources. This Library is then added to my current project and everywhere where i need i use those resource files.

现在我已经实现了站点地图提供者:

Now i've implemented the site map provider:

  <mvcSiteMapNode title="$resources:Base,Home" controller="Home" action="Index" enableLocalization="true">
    <mvcSiteMapNode title="Search" controller="Search" action="Index"/>
    <mvcSiteMapNode title="Contact" controller="Contact" action="Index"/>
    <mvcSiteMapNode title="About" controller="Home" action="About"/>
  </mvcSiteMapNode>

但是,当我运行它,我得到一个错误,因为它无法找到具有关键家庭资源。我认为这是由于这一事实,即在应用程序之外,但在一个单独的图书馆。

But when i run it i get an error because it cannot find the resource with the key home. I think it is due to the fact that is outside of the application but in a separate Library.

如何指向则资源文件,该文件位于喧嚣单独的项目?

How do i point to the resource file then, which is located din separate project?

推荐答案

我想借此将切换到外部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"/>

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

这篇关于MVC网站地图提供商和本地化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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