2013-09-02 3 views
1

몇 페이지 만있는 간단한 ASP.NET WebForms 프로젝트가 있는데 나는 (SEO뿐만 아니라 URL의 현지화도) 친숙한 URL을 사용하고 싶습니다. 이 프로젝트에 .NET 4.5를 사용하고 도움이 될만한 Microsoft.AspNet.FriendlyUrls Nuget 패키지를 사용하려고했습니다. 하지만 한 가지 문제가 있습니다.ASP.NET WebForms : Request.GetFriendlyUrlFileVirtualPath() 빈 문자열을 반환합니다.

난의 Global.asax에있어이 :

void Application_Start(object sender, EventArgs e) 
    { 
     // Code that runs on application startup 
     BundleConfig.RegisterBundles(BundleTable.Bundles); 
     RouteConfig.RegisterRoutes(RouteTable.Routes); 
    } 

및 RouteConfig 클래스는 다음과 같습니다

public static class RouteConfig 
{ 
    public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.MapPageRoute("HowItWorks", "ako-to-funguje", "~/HowItWorks.aspx"); 
     routes.MapPageRoute("AboutUs", "o-nas", "~/AboutUs.aspx"); 
     routes.MapPageRoute("Contact", "kontakt", "~/Contact.aspx"); 

     var settings = new FriendlyUrlSettings(); 
     settings.AutoRedirectMode = RedirectMode.Permanent; 
     routes.EnableFriendlyUrls(settings); 
    } 
} 

난 당신이 모두/HowItWorks를 통해 액세스하는 경우 같은 페이지를 표시 할 및/ako-to-funguje (슬로바키아어 로켈입니다).

이제 실제 문제에 가까워지고 있습니다. 지역화 된 경로 중 하나 (예 :/ako-to-funguje)로 사이트에 액세스하면 Request.GetFriendlyUrlFileVirtualPath()는 빈 문자열을 반환합니다 (그러나 "~/HowItWorks.aspx"를 얻으려는 경우 master에서 몇 가지 작업을 수행하려고합니다 페이지).

string pageFileName = Request.GetFriendlyUrlFileVirtualPath(); 
switch (pageFileName) 
{ 
     case "~/AboutUs.aspx": 
      //do some stuff 
      break; 
     case "~/HowItWorks.aspx": 
      //do some stuff 
      break; 
     case "~/Contact.aspx": 
      //do some stuff 
      break; 
     default: 
      break; 
} 

나는/HowItWorks URL을 다음 Request.GetFriendlyUrlFileVirtualPath() 반환 사이트에 액세스하는 경우 "~/HowItWorks.aspx"예상대로.

/HowItWorks 및/ako-to-funguje를 통해 사이트에 액세스 할 때 Request.GetFriendlyUrlFileVirtualPath()에서 "~/HowItWorks.aspx"를 얻는 방법에 대한 아이디어가 있습니까?

답변

1

결국이 문제에 대한 자체 해결 방법을 생각해 냈습니다. 나는 현재 페이지 실행하는 가상 파일 경로를 반환 HTTP 요청에 대한 자신의 확장 메서드를 만들었습니다

using System.Web; 
using System.Web.Routing; 
using Microsoft.AspNet.FriendlyUrls; 

namespace Utils.Extensions 
{ 
     public static class HttpRequestExtensions 
     { 
      public static string GetFileVirtualPathFromFriendlyUrl(this HttpRequest request) 
      { 
      string ret = string.Empty; 

      ret = request.GetFriendlyUrlFileVirtualPath(); 

      if (ret == string.Empty) 
      { 
       foreach (RouteBase r in RouteTable.Routes) 
       { 
        if (r.GetType() == typeof(Route)) 
        { 
         Route route = (Route)r; 
         if ("/" + route.Url == request.Path) 
         { 
          if (route.RouteHandler.GetType() == typeof(PageRouteHandler)) 
          { 
           PageRouteHandler handler = (PageRouteHandler)route.RouteHandler; 

           ret = handler.VirtualPath; 
          } 
          break; 
         } 
        } 
       } 
      } 

      return ret; 
      } 
    } 
} 
+0

감사합니다. Petriq, 훌륭한 솔루션입니다. 나는 며칠 동안 비슷한 문제를 해결할 방법을 찾으려고 노력해 왔으며 (http://stackoverflow.com/q/22577826/236860 참조), 이것이 완벽하게 작동합니다. – Neilski

+0

URL에 매개 변수가 있거나 가상 디렉터리를 사용하는 경우에는 작동하지 않습니다. – Mike

0

내가 URL에 매개 변수를 처리하는 Petriq의 답변을 업데이트

string requestUrl = this.Request.GetFriendlyUrlFileVirtualPath().ToLowerInvariant(); 
if (String.IsNullOrEmpty(requestUrl)) { 
    requestUrl = this.Request.AppRelativeCurrentExecutionFilePath.ToLowerInvariant(); 
} 
0

에 문의하십시오를

public static string GetFileVirtualPathFromFriendlyUrl(this HttpRequest request) { 
     string ret = request.GetFriendlyUrlFileVirtualPath(); 

     if (ret == string.Empty) { 
      for(int j = 0, a = RouteTable.Routes.Count; j<a;j++) { 
       RouteBase r = RouteTable.Routes[j]; 
       if (r.GetType() == typeof(Route)) { 
        Route route = (Route)r; 

        StringBuilder newroute = new StringBuilder(route.Url); 
        if (route.Defaults != null && route.Defaults.Count > 1) { 
         string[] keys = route.Defaults.Select(x => x.Key).ToArray(); 
         foreach (string k in keys) { 
          newroute = newroute.Replace("{" + k + "}", k.CheckQueryString()); 
         } 
        } 

        if (String.Compare(newroute.ToString(), request.Path.Replace(request.ApplicationPath, ""), true) == 0) { 
         if (route.RouteHandler.GetType() == typeof(PageRouteHandler)) { 
          PageRouteHandler handler = (PageRouteHandler)route.RouteHandler; 
          return handler.VirtualPath; 
         } 
        } 
       } 
      } 
     } 

     return ret; 
    } 

노선은 지금 될 수

RouteValueDictionary contactDefault = new RouteValueDictionary { { "person", UrlParameter.Optional } }; 

routes.MapPageRoute("Contact", "kontakt/{person}", "~/Contact.aspx");