2017-08-03 10 views
2

私は確立されたサイトで働いています。小さな(ページの面では)、いくつかの大きなマネーランディングページと通常の在庫ページがあります。Webformsルーティング - 異なるページの同じ署名?

サイトが比較的小さいため、ページ構造はフラットでした。

https://example.com/contact 
https://example.com/big-money-page 

異なるページデザインのページをさらに多く導入する予定です。つまり、マスターページやaspxテンプレートページを使用して、独自のデータベース駆動CMSを作成します。

ここで私が見ることができる問題は、URLルーティングとされます:

テンプレートタイプ1

Route url: /{Name} - e.g. /big-money-page 
Physica path: ~/template1.aspx 

テンプレートタイプ2

Route url: /{Name} - e.g. /new-supporting-page 
Physical path: ~/template2.aspx 
私はを中断せずにこの仕事をしたいと思い

既存のマネーページ、可能であれば、訪問者のためのよく知られたウェブサイト構造を維持する、template1とtemplate2は類似のページであり、自然に異なるフォルダには存在しません。デザインが異なります。

また、ディープルーティングされたフォルダ構造が固定されているため、将来変更が難しくなります。

私はしばらくの間、単純な方法でWFルーティングを使用してきました。限られた結果で変更をどのように働かせることができるのか誰でも知っていますか?

更新--------------------------------------------- -----------------------

いいえ、フィードバックがなければ、私はテーブルを置くという考えを思いつきました。私はfesibilityと考えられる欠点についてのフィードバックを感謝します。

私の考えは、ダミーのルート/ページを持つことです。

経路はhttp://example.com/{name}の形式になります。

ダミーページは、placeholder {name}を使用して、ターゲットページのデータベースからデータを取得します。

次に、データベースから取得したデータを使用して正しいターゲットページに転送します。

私は知らない私は、これが機能すると思いますが、私は物事が心配です:Server.Transferのため

  • ブラウザの互換性
  • パフォーマンス・オーバーヘッド
  • 出力キャッシュへの影響
  • 私の心を越えていないその他のもの

もちろんこれは理想的な解決策ではありませんが、私はまた開いています他のアイデアに

答えて

2

WebFormプロジェクトでは、カスタムHTTPModuleを使用してタスクを実装できます。実装にはいくつかのステップがあります。簡易版は、以下の通りである:App_Codeフォルダー内のクラスを作成します

create table dbo.UrlMap (
    publicUrl varchar(255) not null primary key, 
    PhysUrl varchar(255) not null 
) 

publicUrl  PhysUrl 
big-money-page template1.aspx?id=1 
huge-money-page template1.aspx?id=2 
no-money-page template2.aspx?id=3 
other-page  template1.aspx?id=4 

2のようないくつかのデータを持つテーブルを埋める
1. SQL

using System; 
using System.Web; 

/// <summary> 
/// Implements IHttpModule with custom URLs 
/// </summary> 
public class UrlMap:IHttpModule 
{ 
    /// <summary> 
    /// Initialize the module 
    /// </summary> 
    /// <param name="context"></param> 
    void IHttpModule.Init(HttpApplication context) 
    { 
     context.BeginRequest += Context_BeginRequest; 
     context.PostMapRequestHandler += Context_PostMapRequestHandler; 
    } 

    private void Context_BeginRequest(object sender, EventArgs e) 
    { 
     var app = (HttpApplication)sender; 
     Url2PhysPath(app.Request.Path, app); 
    } 

    private void Context_PostMapRequestHandler(object sender, EventArgs e) 
    { 
     var app = (HttpApplication)sender; 
     var pg = app.Context.Handler as System.Web.UI.Page; 
     if (pg != null) 
     { 
      pg.PreRenderComplete += Pg_PreRenderComplete; 
     } 
    } 

    private void Pg_PreRenderComplete(object sender, EventArgs e) 
    { 
     ProcessPageTree((System.Web.UI.Control)sender); 
    } 

    /// <summary> 
    /// Replaces physical URLs on the page with "beutified" version 
    /// </summary> 
    /// <param name="control"></param> 
    private void ProcessPageTree(System.Web.UI.Control control) 
    { 
     var form = control as System.Web.UI.HtmlControls.HtmlForm; 
     if (form != null) 
     { 
      form.Action = BeautifyUrl(form.Page.Request.Url.PathAndQuery); 
     } 
     //other types in a similar way 
     if (control.HasControls()) 
     { 
      foreach(System.Web.UI.Control c in control.Controls) 
      { 
       ProcessPageTree(c); 
      } 
     } 
    } 
    /// <summary> 
    /// Helper function. Can be inlined. 
    /// Searches "beautified" url in a DB and rewrites path 
    /// </summary> 
    /// <param name="url"></param> 
    /// <param name="app"></param> 
    private static void Url2PhysPath(string url, HttpApplication app) 
    { 
     using (var cnn = new System.Data.SqlClient.SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["SiteCnn"].ConnectionString)) 
     { 
      var cmd = new System.Data.SqlClient.SqlCommand("select physPath from dbo.urlMap where [email protected]", cnn); 
      cmd.CommandType = System.Data.CommandType.Text; 
      cmd.Parameters.Add("@url", System.Data.SqlDbType.VarChar, 255).Value = url; 
      cnn.Open(); 
      string physPath = null; 
      using(var r = cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection)) 
      { 
       if (r.Read()) 
       { 
        physPath = (string)r["physPath"]; 
       } 
       r.Close(); 
      } 
      if (!string.IsNullOrEmpty(physPath)) 
      { 
       app.Context.RewritePath("/" + physPath); 
      } 
     } 
    } 

    /// <summary> 
    /// Helper function 
    /// </summary> 
    /// <param name="physUrl"></param> 
    /// <returns>returns original url when nothing is found</returns> 
    private static string BeautifyUrl(string physUrl) 
    { 
     using (var cnn = new System.Data.SqlClient.SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["SiteCnn"].ConnectionString)) 
     { 
      var cmd = new System.Data.SqlClient.SqlCommand("select publicUrl from dbo.urlMap where [email protected]", cnn); 
      cmd.CommandType = System.Data.CommandType.Text; 
      cmd.Parameters.Add("@url", System.Data.SqlDbType.VarChar, 255).Value = physUrl; 
      cnn.Open(); 
      string pubUrl = physUrl;//to return original url when nothing is found 
      using(var r = cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection)) 
      { 
       if (r.Read()) 
       { 
        pubUrl = (string)r["publicUrl"]; 
       } 
       r.Close(); 
      } 
      return pubUrl; 
     } 

    } 
    /// <summary> 
    /// Required by interface 
    /// </summary> 
    void IHttpModule.Dispose() 
    { 
    // throw new NotImplementedException(); 
    } 
} 

3. Modify Web.config
モジュールを登録します。 Server.Transferをない問題について
ブラウザの互換性をフォローアップconfiguration \ system.webServer \ modules

<add name="UrlRewriter" type="UrlMap" preCondition="managedHandler"/> 

に次の行を追加します。ブラウザは、HTMLのみ
パフォーマンスのオーバーヘッドが出力キャッシュキャッシュへの影響より良いとしてもpublicUrlphysUrlの両方が一意である必要があります私の心を交差させていないtemplate.aspx?id=123
他のもの、次に

あまり受けます。実際には、直接キーと逆キーの参照を静的なDictionary<string, string>変数にキャッシュすることができます。

+0

アレックスの説明に感謝します。 –

関連する問題