Asp.net Webforms路由-使用不同页面的相同签名?
我在一个已建立的网站上工作。虽然很小(就页面而言),但除了普通的股票页面外,还有一些大的登录页面 因为站点相对较小,所以页面结构是扁平的Asp.net Webforms路由-使用不同页面的相同签名?,asp.net,webforms,routing,url-routing,Asp.net,Webforms,Routing,Url Routing,我在一个已建立的网站上工作。虽然很小(就页面而言),但除了普通的股票页面外,还有一些大的登录页面 因为站点相对较小,所以页面结构是扁平的 https://example.com/contact https://example.com/big-money-page 我们计划推出更多不同页面设计的页面。这意味着我们将使用母版页和/或aspx模板页,并创建自己的数据库驱动的CMS 我发现url路由存在以下问题: 模板类型1 Route url: /{Name} - e.g. /big-money-p
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路由一段时间了,但总是以简单的方式。有人知道我如何在有限的后果下做出改变吗
更新--------------------------------------------------------------------
好的,在没有任何反馈的情况下,我想出了一个想法,可以提出来。我希望得到关于可能性的反馈以及可以考虑的任何不利因素
我的想法是创建一个虚拟路由/页面
路线将采用http://example.com/{name}
虚拟页面使用占位符{name}
从数据库中检索目标页面的数据
然后,我们使用从数据库检索到的数据将server.transfer传输到正确的目标页面
我认为这会奏效,但我担心我不知道的事情:
- server.transfer的浏览器兼容性
- 性能开销
- 对输出缓存的影响
- 我还没有想到的其他事情
当然,这不是一个理想的解决方案,但我也愿意接受任何其他想法。在网络表单项目中,可以使用自定义的
HTTPModule
来实现任务。实现包括几个步骤。简化版本如下:1。SQL
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。在App_code文件夹中创建一个类
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 publicUrl=@url", 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 physPath=@url", 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();
}
}
跟进server.transfer的浏览器兼容性不是问题。浏览器仅接收HTML
性能开销不多
对输出缓存的影响缓存比
template.aspx?id=123更好
我甚至没有想到的其他事情无论是publicUrl
还是physure
都必须是唯一的。实际上,您可以在静态字典变量中缓存直接键和反向键查找。感谢您的精彩解释。
<add name="UrlRewriter" type="UrlMap" preCondition="managedHandler"/>