【问题标题】:Creating multilingual not found page in MVC在 MVC 中创建多语言未找到页面
【发布时间】:2016-01-03 13:42:44
【问题描述】:

我们有一个多语言网站,其中包含四种语言的内容。每种语言都可以通过我们在网址第一个添加的语言名称来理解。 这是我们的 routeConfig.cs:

   routes.MapRoute(
            name: "Default",
            url: "{lang}/{controller}/{action}/{id}/{title}",
            defaults: new { lang = "fa", controller = "Home", action = "Index", id = UrlParameter.Optional,title = UrlParameter.Optional }

这是生成的网址:/en/ContactUs/Index

此外,在我们的控制器中,我们从 url 获取语言名称,并根据它更改 currentCulture 和 currentUiCulture。 现在,我们希望在所有语言中都有一个未找到的页面。通常,为了实现它,我们添加一个错误控制器和一个 NotFound 操作和视图,然后我们在 web.config 中添加此部分:

  <customErrors mode="On" defaultRedirect="error">
  <error statusCode="404" redirect="error/notfound" />
  <error statusCode="403" redirect="error/forbidden" />
</customErrors>

我们添加了一个 NotFound 页面,我们在其中使用 .resx 文件来制作 rtl/ltr 并以四种语言显示消息。 但是这里的问题是,在多语言网站中,我们不允许使用这个地址“error/notfound”,因为其中没有语言名,我们不知道如何在redirect="error/notfound"中添加语言名在 web.config 文件中创建类似“en/error/notfound”或“fa/error/notfound”的内容。 我们将不胜感激每一个帮助

【问题讨论】:

    标签: asp.net-mvc http-status-code-404 asp.net-mvc-routing multilingual


    【解决方案1】:

    首先,查看this answer 了解有关通过 URL 本地化您的网站的信息。

    接下来,&lt;customErrors&gt; 是 ASP.NET 错误消息的集合。但总的来说,您可以通过使用包罗万象的路由来控制 ASP.NET MVC 中的 404(路由未命中)。在这种情况下,您可以简单地将包罗万象的路由本地化,并在 web.config 中去掉此配置。

    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
            routes.MapRoute(
                name: "Localized-Default",
                url: "{lang}/{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                constraints: new { lang = new CultureConstraint(defaultCulture: "fa", pattern: "[a-z]{2}") }
            );
    
            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { lang = "fa", controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
    
            // Catch-all route (for routing misses)
            routes.MapRoute(
                name: "Localized-404",
                url: "{lang}/{*url}",
                defaults: new { controller = "Error", action = "PageNotFound" },
                constraints: new { lang = new CultureConstraint(defaultCulture: "fa", pattern: "[a-z]{2}") }
            );
    
            routes.MapRoute(
                name: "Default-404",
                url: "{*url}",
                defaults: new { lang = "fa", controller = "Error", action = "PageNotFound" }
            );
        }
    }
    

    错误控制器

    public class ErrorController : Controller
    {
        public ActionResult PageNotFound()
        {
            Response.CacheControl = "no-cache";
            Response.StatusCode = (int)HttpStatusCode.NotFound;
    
            return View();
        }
    }
    

    这可以解决 ASP.NET 中的路由丢失问题。对于那些不使用 ASP.NET(假设您使用 IIS 进行托管)的用户,您应该使用 web.config 的 &lt;httpErrors&gt; 部分而不是 &lt;customErrors&gt;&lt;httpErrors&gt; 可通过 prefixLanguageFilePath setting 进行本地化。

    可选的字符串属性。

    在为自定义错误生成路径时指定初始路径段。此段出现在自定义错误路径的特定语言部分之前。比如路径C:\Inetpub\Custerr\en-us\404.htm中,C:\Inetpub\Custerr就是prefixLanguageFilePath。

    <configuration>
       <system.webServer>
          <httpErrors errorMode="DetailedLocalOnly" defaultResponseMode="File" >
             <remove statusCode="404" />
             <error statusCode="404"
                prefixLanguageFilePath="C:\Contoso\Content\errors"
                path="404.htm" />
           </httpErrors>
       </system.webServer>
    </configuration>
    

    这意味着您需要设置一个带有语言前缀的文件结构,并使用静态文件作为目标。

    C:\Contoso\Content\errors\fa\404.htm
    C:\Contoso\Content\errors\en\404.htm
    

    AFAIK,不幸的是,这意味着您需要在这些位置拥有物理文件。但是,您可以将这些页面的内容设置为执行元刷新重定向将 JavaScript 重定向到正确的控制器操作。

    <html>
    <head>
        <title>404 Not Found</title>
        <meta http-equiv="refresh" content="1;http://www.example.com/fa/Error/PageNotFound" />
    </head>
    <body>
        <!-- Add localized message (for those browsers that don't redirect). -->
        
        <script>
            //<!--
            setTimeout(function () {
                window.location = "http://www.example.com/fa/Error/PageNotFound";
            }, 1000);
            //-->
        </script>
    </body>
    </html>
    

    【讨论】:

    • 很好的答案!虽然我在摆脱 时遇到了问题,但我还需要实现对错误 500 和 403 的捕获,那么该怎么做呢?
    【解决方案2】:

    web.config 中的customErrors 部分是有关某些状态代码以及如何处理它们的静态数据。本节的职责可以通过 Global.asax 中的Application_EndRequest 方法动态生成。

    protected void Application_EndRequest()
    {
        if (Context.Response.StatusCode == 404)
        {
            Response.Clear();
    
            var routeData = new RouteData();
            HttpContextBase currentContext = new HttpContextWrapper(HttpContext.Current);
            var lang = RouteTable.Routes.GetRouteData(currentContext).Values["lang"];
            routeData.Values["lang"] = lang;
            routeData.Values["controller"] = "CustomError";
            routeData.Values["action"] = "NotFound";
    
            IController customErrorController = new CustomErrorController();
            customErrorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
        }
    }
    

    【讨论】:

      【解决方案3】:

      我相信您可以使用会话变量来保存当前用户的 ui-culture 数据。

      我没有看到任何意义,但是,如果您不想这样做,您可以按照本教程为 MVC 自定义错误页面处理生成您自己的路由。

      http://setiabud.blogspot.com.tr/2013/04/handling-404-error-in-aspnet-mvc.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-29
        • 1970-01-01
        • 2019-07-08
        • 1970-01-01
        • 2022-11-24
        • 1970-01-01
        相关资源
        最近更新 更多