Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.NET MVC 5中的本地化路由无意中重定向到主页_C#_Asp.net_Asp.net Mvc - Fatal编程技术网

C# ASP.NET MVC 5中的本地化路由无意中重定向到主页

C# ASP.NET MVC 5中的本地化路由无意中重定向到主页,c#,asp.net,asp.net-mvc,C#,Asp.net,Asp.net Mvc,我正在为一个已经在ASP.NET MVC 5中发布的网站配置本地化 我遵循的将本地化集成到我的站点的指南来自codeproject,我发现它非常好: 现在,为了解释这个问题,每当我加载主页索引http://www.example.com/如果没有路由路径,它将重定向到正确的语言http://www.example.com/en这是所需的结果 我的网站URL的格式为http://www.example.com/controller/action。每当我访问http://www.example.co

我正在为一个已经在ASP.NET MVC 5中发布的网站配置本地化

我遵循的将本地化集成到我的站点的指南来自codeproject,我发现它非常好:

现在,为了解释这个问题,每当我加载主页索引
http://www.example.com/
如果没有路由路径,它将重定向到正确的语言
http://www.example.com/en
这是所需的结果

我的网站URL的格式为
http://www.example.com/controller/action
。每当我访问
http://www.example.com/controller/
它现在会将我重定向回
http://www.example.com/en
而不是
http://www.example.com/en/controller/index
。当我试着输入
http://www.example.com/controller/action
它抛出404错误,而不是
http://www.example.com/en/controller/action

我认为问题出在
LocalizationHelper.cs
文件中的
GetLocalistedUrl
函数中

    public static string GetLocalisedUrl(Uri initialUri, IList<string> controllersNames, IList<string> userLangs)
    {
        var res = string.Empty;

        var supportedLocales = GetSupportedLocales();

        var origUrl = initialUri;

        // Dicide requested url to parts
        var cleanedSegments = origUrl.Segments.Select(X => X.Replace("/", "")).ToList();

        // Check is already supported locale defined in route
        // cleanedSegments[0] is empty string, so lang parameter will be in [1] url segment
        var isLocaleDefined = cleanedSegments.Count > 1 && supportedLocales.Contains(cleanedSegments[1]);

        // does request need to be changed
        var isRequestPathToHandle =
            // Url has controller's name part
            (cleanedSegments.Count > 1 && cleanedSegments.Intersect(controllersNames).Count() > 0) ||
            // This condition is for default (initial) route
            (cleanedSegments.Count == 1) ||
            // initial route with lang parameter that is not supported -> need to change it
            (cleanedSegments.Count == 2 && !supportedLocales.Contains(cleanedSegments[1]));     

        if (!isLocaleDefined && isRequestPathToHandle)
        {
            var langVal = "";
            // Get user preffered language from Accept-Language header
            if (userLangs != null && userLangs.Count > 0)
            {
                // For our locale name approach we'll take only first part of lang-locale definition
                var splitted = userLangs[0].Split(new char[] { '-' });
                langVal = splitted[0];
            }

            // If we don't support requested language - then redirect to requested page with default language
            if (!supportedLocales.Contains(langVal))
                langVal = supportedLocales[0];

            var normalisedPathAndQuery = origUrl.PathAndQuery;
            if ((cleanedSegments.Count > 2 &&
                !controllersNames.Contains(cleanedSegments[1]) &&
                controllersNames.Contains(cleanedSegments[2])) ||
                (cleanedSegments.Count == 2) && (!controllersNames.Contains(cleanedSegments[1])))
            {
                // Second segment contains lang parameter, third segment contains controller name
                cleanedSegments.RemoveAt(1);

                // Remove wrong locale name from initial Uri
                normalisedPathAndQuery = string.Join("/", cleanedSegments) + origUrl.Query;
            }

            // Finally, create new uri with language loocale
            res = string.Format("{0}://{1}:{2}/{3}{4}", origUrl.Scheme, origUrl.Host, origUrl.Port, langVal.ToLower(), normalisedPathAndQuery);
        }

        return res;
    }
公共静态字符串GetLocalisedUrl(Uri初始Uri、IList控制器名称、IList用户语言)
{
var res=string.Empty;
var supportedLocales=GetSupportedLocales();
var origUrl=initialUri;
//Dicide请求的零件url
var cleanedSegments=origUrl.Segments.Select(X=>X.Replace(“/”,“”)).ToList();
//路由中已定义了支持的区域设置
//cleanedSegments[0]是空字符串,因此lang参数将位于[1]url段中
var isLocaleDefined=cleanedSegments.Count>1&&supportedLocales.Contains(cleanedSegments[1]);
//请求是否需要更改
var isRequestPathToHandle=
//Url包含控制器的名称部分
(cleanedSegments.Count>1&&cleanedSegments.Intersect(controllersNames.Count()>0)||
//此条件适用于默认(初始)路线
(cleanedSegments.Count==1)||
//不支持lang参数的初始路由->需要更改它
(cleanedSegments.Count==2&&!supportedLocales.Contains(cleanedSegments[1]);
如果(!isLocaleDefined&&isRequestPathToHandle)
{
var langVal=“”;
//从Accept language标头获取用户首选的语言
if(userLangs!=null&&userLangs.Count>0)
{
//对于我们的语言环境名称方法,我们只使用语言环境定义的第一部分
var splitted=userLangs[0]。拆分(新字符[]{'-});
langVal=splitted[0];
}
//如果我们不支持请求的语言,则使用默认语言重定向到请求的页面
如果(!supportedLocales.Contains(langVal))
langVal=supportedLocales[0];
var normalisedPathAndQuery=origUrl.PathAndQuery;
如果((cleanedSegments.Count>2&&
!controllersNames.Contains(已清除的段[1])&&
controllersNames.Contains(cleanedSegments[2]))||
(cleanedSegments.Count==2)和(!controllersNames.Contains(cleanedSegments[1]))
{
//第二段包含lang参数,第三段包含控制器名称
清除段。移除(1);
//从初始Uri中删除错误的区域设置名称
normalisedPathAndQuery=string.Join(“/”,cleanedSegments)+origUrl.Query;
}
//最后,使用loocale语言创建新的uri
res=string.Format(“{0}://{1}:{2}/{3}{4}”,origUrl.Scheme,origUrl.Host,origUrl.Port,langVal.ToLower(),normalisedPathAndQuery);
}
返回res;
}
该函数在创建的IHttpModule扩展中调用

public class LangQueryAppenderModule : IHttpModule
{
    /// <summary>
    /// List of supported locales
    /// </summary>
    private readonly IList<string> _supportedLocales;

    /// <summary>
    /// We need to have controllers list to correctly handle situations
    /// when target method name is missed
    /// </summary>
    private readonly IList<string> _controllersNamesList;

    public LangQueryAppenderModule()
    {
        // Get list of supported locales 
        _supportedLocales = LocalizationHelper.GetSupportedLocales();

        // Get controllers list of current project by reflection
        var asmPath = HttpContext.Current.Server.MapPath("~/bin/Central.dll");
        Assembly asm = Assembly.LoadFile(asmPath);

        var controllerTypes = asm.GetTypes()
            .Where(type => typeof(Controller).IsAssignableFrom(type));
        _controllersNamesList = new List<string>();

        foreach (var controllerType in controllerTypes)
        {
            var fullName = controllerType.Name;

            // We need only name part of Controller class that is used in route
            _controllersNamesList.Add(fullName.Substring(0, fullName.Length - "Controller".Length));
        }
    }

    // In the Init function, register for HttpApplication 
    // events by adding your handlers.
    public void Init(HttpApplication application)
    {
        application.BeginRequest += (new EventHandler(this.Application_BeginRequest));
    }

    private void Application_BeginRequest(Object source, EventArgs e)
    {
        try
        {
            HttpApplication app = (HttpApplication)source;
            HttpContext ctx = app.Context;

            // We will redirect to url with defined locale only in case for HTTP GET verb
            // cause we assume that all requests with other verbs will be called from site directly
            // where all the urls created with URLHelper, so it complies with routing rules and will contain "lang" parameter
            if (string.Equals(ctx.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
            {
                var localisedUri = LocalizationHelper.GetLocalisedUrl(ctx.Request.Url, _controllersNamesList, ctx.Request.UserLanguages);
              if (!string.IsNullOrEmpty(localisedUri))
                    // Perform redirect action to changed url if it exists
                    ctx.Response.Redirect(localisedUri);
            }
        }
        catch (Exception)
        {
            // Some logging logic could be here
        }
    }

    public void Dispose() { }

}
公共类LangQueryAppenderModule:IHttpModule
{
/// 
///支持的区域设置列表
/// 
私有只读IList_支持的Locales;
/// 
///我们需要有控制器列表来正确处理情况
///缺少目标方法名称时
/// 
私有只读IList_控制器名称列表;
公共LangQueryAppenderModule()
{
//获取支持的区域设置列表
_supportedLocales=LocalizationHelper.GetSupportedLocales();
//通过反射获取当前项目的控制器列表
var asmPath=HttpContext.Current.Server.MapPath(“~/bin/Central.dll”);
Assembly asm=Assembly.LoadFile(asmPath);
var controllerTypes=asm.GetTypes()
其中(type=>typeof(Controller).IsAssignableFrom(type));
_controllersNamesList=新列表();
foreach(controllerTypes中的var controllerType)
{
var fullName=controllerType.Name;
//我们只需要命名路由中使用的控制器类的一部分
_添加(fullName.Substring(0,fullName.Length—“Controller.Length”);
}
}
//在Init函数中,注册HttpApplication
//事件,通过添加处理程序。
public void Init(HttpApplication应用程序)
{
application.BeginRequest+=(新的EventHandler(this.application_BeginRequest));
}
私有void应用程序_BeginRequest(对象源,事件参数e)
{
尝试
{
HttpApplication应用程序=(HttpApplication)源;
HttpContext ctx=app.Context;
//仅在HTTP GET动词的情况下,我们将重定向到具有已定义语言环境的url
//因为我们假设所有带有其他谓词的请求都将直接从站点调用
//其中所有URL都是使用URLHelper创建的,因此它符合路由规则并将包含“lang”参数
if(string.Equals(ctx.Request.HttpMethod,“GET”,StringComparison.OrdinalIgnoreCase))
{
var localisedUri=Loc
  public static string GetLocalisedUrl(Uri initialUri, IList<string> controllersNames, IList<string> userLangs)
    {
        var res = string.Empty;

        var supportedLocales = GetSupportedLocales();


        var origUrl = initialUri;

        // Dicide requested url to parts
        var cleanedSegments = origUrl.Segments.Select(X => X.Replace("/", "")).ToList();

        // Check is already supported locale defined in route
        // cleanedSegments[0] is empty string, so lang parameter will be in [1] url segment
        var isLocaleDefined = cleanedSegments.Count > 1 && supportedLocales.Contains(cleanedSegments[1]);

        cleanedSegments = cleanedSegments.ConvertAll(d => d.ToLower());

        // does request need to be changed
        var isRequestPathToHandle =
            // Url has controller's name part
            (cleanedSegments.Count > 1 && cleanedSegments.Intersect(controllersNames).Count() > 0) ||
            // This condition is for default (initial) route
            (cleanedSegments.Count == 1) ||
            // initial route with lang parameter that is not supported -> need to change it
            (cleanedSegments.Count == 2 && !supportedLocales.Contains(cleanedSegments[1]));     

        if (!isLocaleDefined && isRequestPathToHandle)
        {
            var langVal = "";
            // Get user preffered language from Accept-Language header
            if (userLangs != null && userLangs.Count > 0)
            {
                // For our locale name approach we'll take only first part of lang-locale definition
                var splitted = userLangs[0].Split(new char[] { '-' });
                langVal = splitted[0];
            }

            // If we don't support requested language - then redirect to requested page with default language
            if (!supportedLocales.Contains(langVal))
                langVal = supportedLocales[0];

            var normalisedPathAndQuery = origUrl.PathAndQuery;
            if ((cleanedSegments.Count > 2 &&
                !controllersNames.Contains(cleanedSegments[1].ToLower()) &&
                controllersNames.Contains(cleanedSegments[2].ToLower())) ||
                (cleanedSegments.Count == 2) && (!controllersNames.Contains(cleanedSegments[1])))
            {
                // Second segment contains lang parameter, third segment contains controller name
                cleanedSegments.RemoveAt(1);

                // Remove wrong locale name from initial Uri
                normalisedPathAndQuery = string.Join("/", cleanedSegments) + origUrl.Query;
            }

            // Finally, create new uri with language loocale
            res = string.Format("{0}://{1}:{2}/{3}{4}", origUrl.Scheme, origUrl.Host, origUrl.Port, langVal.ToLower(), normalisedPathAndQuery.ToLower());
        }

        return res;
    }