2011-06-29 10 views
1

モバイル版のサイトを作成するには、コントローラーやビューなどを再利用したいが、モバイル版のサブディレクトリーのように見えるようにする。だからあなたのようなURLを持つことができ:すべてのルートを偽装サブディレクトリとして複製する方法

 /Controller/Action/Id 
/mobile/Controller/Action/Id 
etc. 

をこれらのルートは、理想的には同じコントローラにマップすると、私はURLがモバイル1かどうかを確認するために、ルートデータのようにどこかになります。ビュー内で@Html.ActionLink()などを使うことができ、デフォルトではこれを指定することなくモバイル版またはデスクトップ版のいずれかにとどまりますが、どちらか一方を強制する能力があります。

これは、すべてのルートの前面にオプションのパラメータを設定することで実現できます。

routes.MapRoute(
     "Default", 
     "{mobile}/{controller}/{action}/{id}", 
     new { controller = "Home", action = "Index", id = UrlParameter.Optional, mobile = UrlParameter.Optional }, 
     new { mobile = "mobile|" } 
    ); 

これはその後、期待通りに動作します:私は本当にすべてのルートの前にそれを追加したくないので

Takes you to either/or /mobile version depending on where you are currently: 
@Html.ActionLink("Current", "Index"); 

/version 
@Html.ActionLink("Desktop", "Index", new { mobile = "" }); 

/mobile version 
@Html.ActionLink("Mobile", "Index", new { mobile = "mobile" }); 

しかしこれは、本当にラメ解決策のように思えます。たとえば、オプションの/mobile接頭辞をすべてのルートに追加して、この作業を正しく行うなど、より良い方法でこれを行うことができます。あるいは、私は問題全体にアプローチすることができますが、これはもっと意味があるでしょうか?

これはあまりあいまいではありませんが、アドバイスをいただければ幸いです。

答えて

2

着信リクエストの場合は、簡単に2セットのruotesが必要です.1セットはすべてのルートがmobile/で始まるセットです。問題はURL生成であり、解決するにはURL生成のみに作用するIRouteConstraintを実装し、現在のHTTP要求の現在のルートがmobile/で始まるかどうかを確認し、それをテストされているルートと比較します。私はMvcCodeRoutingライブラリで同様のアプローチを使用します。

+0

ありがとう、これを見てみましょう。あなたは問題が実際に世代にあることは間違いありません - それは有益なおかげです。 –

1

あなたはこの見ている:私はルートがリンクにマッチしているときと信じ

routes.MapRoute(
       "Mobile", // Mobile route 
       "mobile/{controller}/{action}/{id}", // URL with parameters 
       new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 
      ); 

routes.MapRoute(
       "Default", // Default route 
       "{controller}/{action}/{id}", // URL with parameters 
       new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 
      ); 

:同じコードベース

0

、これは動作しないでしょうに、モバイル/ブラウザを有するために非常に良いhttp://51degrees.codeplex.com/

をActionLinkを使って作成したルートを考慮してリンクを作成しますか?

私は間違っている可能性があります - 私は実際にそれをテストしていません。

+0

ありがとうございました。私はこれを試しましたが、デスクトップ部分内で@ Html.ActionLink()を使用すると、最初の(モバイル)ルートが一致します。可能であればこの種の重複を避けたいと思います。 –

+0

いいえ、デスクトップパーツはモバイルルートをモバイルURL/URLの一部として含まないため、モバイルルートと一致しません。私が完全に間違ってルーティングがどのように動作するか理解していない限り、私はむしろ私のアプリの1つのためのMVCのルーティングでやった。http://haacked.com/archive/2008/03/13/url-routing-debuggerを使ってください。あなたのルートをデバッグするためのaspx - 扱います。 –

+0

コントローラー、アクション、およびパラメーターが指定されたURLを作成しようとすると、逆の照合が行われます。その場合、あなたはいつも私が思う最初のルートを得るでしょう。本当に役に立つリンクに感謝します。 –

1

私はすでに、「一般的な」ブラウザの場合はasp.net mvc + jquery、モバイルブラウザの場合はasp.net mvc + jqueryMobileのWebプロジェクトでこれを実行しています。私はグローバルなasaxで新しいルートを作成する必要はありませんでした。また、これらはモバイルリダイレクトのためにかなりのサイトです:

Mobile enabled web apps with ASP.NET MVC 3 and jQuery Mobile(あなたがmvc3を使用している場合ははるかに簡単である) Walkthrough: Creating an ASP.NET MVC Areas Application Using Multiple Projects A First Look at ASP.NET MVC 2

だから、私の解決策では、私は、私の中にそのIタグをモバイルリダイレクト属性を使用しました私がリダイレクトをチェックしたいコントローラーのアクション。私はあなたの解決策であなたが正しいリンクをクリックするようにユーザーに "尋ねる"ことを見ました。ユーザーに依存していて、良くないです(おそらく私はあなたの意図を捕まえていませんでした)。しかし、このソリューションでは、あなたのサイトにリクエストを行うブラウザを知って、要求でユーザーエージェントをチェック:

/// <summary> 
    /// Attribute for Mobile Redirection when the request action comes from a mobile device. 
    /// </summary> 
    public class MobileRedirectAttribute : AuthorizeAttribute 
    { 
     private const string defaultMobileController = "Mobile"; 

     #region Properties 

     /// <summary> 
     /// Gets or sets the action. 
     /// </summary> 
     /// <value>The action.</value> 
     private string Action { get; set; } 

     /// <summary> 
     /// Gets or sets the controller. 
     /// </summary> 
     /// <value>The controller.</value> 
     private string Controller { get; set; } 

     private UrlHelper _urlHelper; 
     /// <summary> 
     /// Sets the URL helper. 
     /// </summary> 
     /// <value>The URL helper.</value> 
     internal UrlHelper UrlHelper { set { this._urlHelper = value; } } 

     /// <summary> 
     /// Gets or sets the last URL redirected. 
     /// </summary> 
     /// <value>The last URL redirected.</value> 
     internal string RedirectedTo { get; private set; } 

     /// <summary> 
     /// Gets or sets a value indicating whether this instance is mobile device. 
     /// </summary> 
     /// <value> 
     ///  <c>true</c> if this instance is mobile device; otherwise, <c>false</c>. 
     /// </value> 
     internal bool IsMobileDevice { get; private set; } 

     #endregion 

     #region Methods 

     /// <summary> 
     /// Determines whether the specified controller is mobile. 
     /// </summary> 
     /// <param name="controller">The controller.</param> 
     /// <returns> 
     ///  <c>true</c> if the specified controller is mobile; otherwise, <c>false</c>. 
     /// </returns> 
     private bool IsMobile(Controller controller) 
     { 
      bool isMobile = controller.Request.Browser.IsMobileDevice; 
      string userAgent = controller.Request.UserAgent.ToLower(); 

      return (isMobile || userAgent.Contains("iphone") || userAgent.Contains("ipod") || userAgent.Contains("blackberry") || userAgent.Contains("mobile") 
          || userAgent.Contains("opera mini") || userAgent.Contains("palm")); 
     } 

     /// <summary> 
     /// Called when [authorization]. 
     /// </summary> 
     /// <param name="filterContext">The filter context.</param> 
     public override void OnAuthorization(AuthorizationContext filterContext) 
     { 
      Controller controller = filterContext.Controller as Controller; 
      this.IsMobileDevice = IsMobile(controller); //test porpouse 
      if (this.IsMobileDevice) 
      { 
       this.RedirectedTo = GetUrlRedirectAction(filterContext.RequestContext); 
       filterContext.Result = new RedirectResult(this.RedirectedTo); 
      } 
     } 

     /// <summary> 
     /// Gets the URL redirect action. 
     /// </summary> 
     /// <param name="requestContext">The request context.</param> 
     /// <returns></returns> 
     private string GetUrlRedirectAction(RequestContext requestContext) 
     { 
      UrlHelper urlHelper = _urlHelper; 
      if (urlHelper == null) //mocking porpouse; 
       urlHelper = new UrlHelper(requestContext); 

      return urlHelper.Action(this.Action, this.Controller, requestContext.RouteData.Values); 
     } 

     #endregion 

     #region Constructor 

     /// <summary> 
     /// Initializes a new instance of the <see cref="MobileRedirectAttribute"/> class. 
     /// </summary> 
     /// <param name="action">The action.</param> 
     public MobileRedirectAttribute(string action) 
     { 
      this.Action = action; 
     } 

     /// <summary> 
     /// Initializes a new instance of the <see cref="MobileRedirectAttribute"/> class. 
     /// </summary> 
     /// <param name="controller">The controller.</param> 
     /// <param name="action">The action.</param> 
     public MobileRedirectAttribute(string controller, string action) 
     { 
      this.Action = action; 
      this.Controller = controller; 
     } 

     #endregion 

    } 

をので、この後、あなたがする必要がある唯一のものはタグ付けすることです他のビューにリダイレクトしたいコントローラのアクション。コントローラーロジックはリファクタリングすることができ、共通のメソッドに抽出することができます。

// GET: /MyController/ 
[MobileRedirectAttribute("MyController","IndexMobile")] 
public ActionResult Index(string guid) 

ご質問がある場合はお気軽にお問い合わせください。

関連する問題