2009-08-17 87 views
5

我在ASP.net中实现了URL重写,我的URL导致了我一个问题的世界。ASP.Net URL编码

该URL由部门数据库&类别生成。我希望员工能够使用任何特殊字符将数据添加到数据库,而不会中断网站。

我在构建URL之前对数据进行编码。

有几个问题...

  1. IIS达到.NET使其无法正常使用“/”,在它解析任何东西之前的URL进行解码。
  2. ASP.net获取由url建设“〜”糊涂某些页面
  3. 我从内置的测试服务器,以我的本地IIS服务器(XP机)和含有编码&(26%)的任何URL迁移内无用给我一个“错误的请求”错误。
  4. UrlEncode会留下一些未改变的分隔符,例如'。'

我确实在这个问题上有两个其他相关的帖子,当时我只看到小问题而不是上游的大问题。我发现了一些注册表技巧来解决“错误请求”问题,但我将部署到共享主机环境,使其无用。我也知道这是一个安全问题的解决方案,所以我不想在不知道我打开什么蠕虫的情况下绕过它。

与其试图强制.net向我传递原始URL或覆盖IIS设置,我想首先制作真正安全的URL。

我会注意到我试过AntiXss.URLEncode,HttpUtility.URLEncode,URI.EscapeDataString。我甚至尝试过像URLEncodng这样的愚蠢的东西。有没有一种能够满足我需要的功能,还是我真的需要推出自己的产品。我甚至考虑做一些Hacky,比如用一串不寻常的字符替换%。最终的结果应该至少是可读的,这是首先使用URL重写的要点。

对不起,很长的文章 - 我只是想确保我已经包含了所有必要的细节。我似乎无法找到任何有关这方面的信息,似乎这将是一个普遍的问题 - 所以也许我错过了一些大事。感谢您的帮助,并耐心解释长篇大论!


编辑为清楚:

当我说的网址正在从数据库建立我的意思是,目录结构是从我的数据库中的部门和类别contstructed。

的一些示例网址 -

的MyStore /制冷/酒吧+ Fridge.aspx
的MyStore /烹调+ Equipment.aspx
的MyStore /厨房/切割+ Boards.asxpx

的问题进来时我使用“Beverage & Bar”或“Pastry/Decorating”等部门来构建我的网址。尽管首先被编码,但会导致上述问题。

我的处理程序已经实现并且工作正常,除了特殊字符编码问题。

+0

在这里充分披露的利益是我的其他相关posts- http://stackoverflow.com/questions/1274669/ url-encoding-being-lost-before-processing-asp-net - 类似的问题,但我试图强制.net给我的原始URL,而不是固定在原始链接上的编码。 http://stackoverflow.com/questions/1194900/asp-net-path-problems-caused-by-encoded-urls 试图修复“〜”问题之前,我意识到有更大的问题。 – 2009-08-17 15:37:32

回答

4

您应该考虑让您的类别/部门表具有一个表格,该表格具有每个类别的唯一网址。然后,您可以使用特殊的例程来生成URL。这可以是一个SQL标量函数或一个CLR函数,但它会做的一件事就是规范Web的URL。您可以将“Beverage &酒吧”转换为“Beverage-And-Bar”和“Pastry/Decorating”以“Pastry-Decorating”。主要是,例程需要用其他东西替换所有无效的HTTP URL字符。一个例子是这样的:

public static class URL 
{ 
    static readonly Regex feet = new Regex(@"([0-9]\s?)'([^'])", RegexOptions.Compiled); 
    static readonly Regex inch1 = new Regex(@"([0-9]\s?)''", RegexOptions.Compiled); 
    static readonly Regex inch2 = new Regex(@"([0-9]\s?)""", RegexOptions.Compiled); 
    static readonly Regex num = new Regex(@"#([0-9]+)", RegexOptions.Compiled); 
    static readonly Regex dollar = new Regex(@"[$]([0-9]+)", RegexOptions.Compiled); 
    static readonly Regex percent = new Regex(@"([0-9]+)%", RegexOptions.Compiled); 
    static readonly Regex sep = new Regex(@"[\s_/\\+:.]", RegexOptions.Compiled); 
    static readonly Regex empty = new Regex(@"[^-A-Za-z0-9]", RegexOptions.Compiled); 
    static readonly Regex extra = new Regex(@"[-]+", RegexOptions.Compiled); 

    public static string PrepareURL(string str) 
    { 
     str = str.Trim().ToLower(); 
     str = str.Replace("&", "and"); 

     str = feet.Replace(str, "$1-ft-"); 
     str = inch1.Replace(str, "$1-in-"); 
     str = inch2.Replace(str, "$1-in-"); 
     str = num.Replace(str, "num-$1"); 

     str = dollar.Replace(str, "$1-dollar-"); 
     str = percent.Replace(str, "$1-percent-"); 

     str = sep.Replace(str, "-"); 

     str = empty.Replace(str, string.Empty); 
     str = extra.Replace(str, "-"); 

     str = str.Trim('-'); 
     return str; 
    } 
} 

你可以使这个SQL增强功能,或作为一个单独的进程运行URL生成。然后为了实现映射,您可以将整个URL直接映射到类别ID。从长远来看,这种方法有好几个原因。首先,您并不总是生成网址,您只需执行一次这些操作,并且它们保持静态,您不必担心程序更改,然后GoogleBot无法找到旧网址。另外,如果遇到碰撞,您可能会注意到潜在的重复类别名称,因为碰撞只会因特殊字符而不同。最后,您始终可以从数据库中查看您的URL,而无需运行映射功能。

+1

这绝对是完美的。非常感谢你,你救了我更多的时间,而不是我不愿意承认的。 – 2009-08-17 19:49:51

1

我有一个url重写我在global.asax文件中执行开始验证请求,因为我有一些安全性。这是我采取原始网址,然后做数据库查找。然后重写aspx页面的路径,并且所有参数都通过查询字符串传递。没有编码是必要的。

但是,如果您正在使用该网址实际更改数据,那么我可以看到,您将有巨大的问题,因为您正在有效地使用http GET来更改数据库。它通常是一个糟糕的理念,而不是我所做的。

我只使用post请求来进行任何数据库操作。这可以保持网页清洁,因为所有数据都在页面表单中。

我唯一的问题是将正确的url设置为page.form.action,在大多数情况下它是原始url。

如果它的类别名称导致问题,那么也许你应该限制名称为字母数字字符只有交换空间的“ - ”。 IIS将会带来一段时间的摇摆。“因为它查找文件名。

P.S. IIS不理解代字符“〜”,这是编译器可以理解的。所以如果您在锚标记中使用它,它将无法按预期工作,您应该使用应用程序根目录代替代字号。

编辑:

OK,它看起来像与具有一定的字符,如IIS问题的问题。 /和&。即使你做urlencode这些IIS仍然会尝试实现它自己的意义。 因此考虑删除它们,以便:

饮料&栏将变为BeverageBar

糕点/装饰变得PastryDecorating。

这将使你的网站清洁,但确实意味着在数据库中的额外列,所以你可以根据这个缩短的类别名称cheack URL。

+0

对不起,我应该更清楚 - 我没有做任何数据库操作与我的网址。我的商店分为多个部门和类别。目录结构不是硬编码的,而是从数据库构建的。各种菜单都有形式为Mystore/Department或Mystore/Department/Category的链接,这些链接虽然编码且技术上正确,但在请求甚至返回给我的httpHandler之前,正在被IIS打破。 – 2009-08-17 16:06:59

+0

这可能是最好的解决方案。我可能刚刚大量过度复杂的事情。我唯一担心的是我需要能够从URL中查找可能由不可逆编码方法复杂化的项目。 我唯一的其他想法是用Uri.EscapeDataString(B).Replace(“%”,“_”),这我相当肯定会谴责我程序员地狱。 非常感谢您的快速响应和对此的帮助。我再看看我的代码,看看这是否可行。 – 2009-08-17 16:43:17

+0

非常感谢您的帮助。这是我无法接受多个答案的那些令我深感沮丧的时期之一。你指出了我正确的方向,并让我重返正轨......谢谢! – 2009-08-17 19:52:53

1

我有完全相同的问题。感谢你把它写得很好。它实际上帮助我更好地理解问题。

但是我有一些其他的考虑。我拥有的目标之一是支持任何角色在基于文章标题的url中的潜力。此外,我想确保编码和双向编码/解码过程的唯一性。

所以我做了一些手动编码来解决这个问题。这不会完全消除百分比编码,但会大大减少它,并防止用户生成无法访问的网址。我的过程从使用Server.URLEncode函数开始。但是这并不能消除url中的问题。由于IIS正在对url进行解码并将其传递给应用程序,因此某些字符会将其与危险的请求异常分开。这些字符包括+, &, /, !, *, ., ()。所以在这些字符加上其他字符,我想使更具可读性,我做了一个双重编码更可用的网址。编码也很困难,因为URL中允许的字符数量有限。所以在编码之前,我把所有的字母都写成大写,然后用小写字母进行编码。这样可以防止它被完全解码,但是我可以通过使我希望匹配的值成为大写字母来轻松地在数据库或代码中进行匹配。

嗯,这是我的代码。反馈将不胜感激。噢,这是在VB中,但事情应该转移到C#很容易。

Dim strReturn As String = Trim(strStringToEncode) 
strReturn = Server.UrlEncode(strReturn) 

strReturn = strReturn.Replace("-", "dash").Replace("+", "-") 

strReturn = strReturn.Replace("%26", "and"). 
        Replace("%2f", "or"). 
        Replace("!", "excl"). 
        Replace("*", "star"). 
        Replace("%27", "apos"). 
        Replace("(", "lprn"). 
        Replace(")", "rprn"). 
        Replace("%3b", "semi"). 
        Replace("%3a", "coln"). 
        Replace("%40", "at"). 
        Replace("%3d", "eq"). 
        Replace("%2b", "plus"). 
        Replace("%24", "dols"). 
        Replace("%25", "pct"). 
        Replace("%2c", "coma"). 
        Replace("%3f", "query"). 
        Replace("%23", "hash"). 
        Replace("%5b", "lbrk"). 
        Replace("%5d", "rbrk"). 
        Replace(".", "dot"). 
        Replace("%3e", "gt"). 
        Replace("%3c", "lt") 

Return strReturn 
+0

已经发现问题。 URL扫描拒绝单个智能报价。 – Nate 2010-11-02 21:46:35

+0

发现很多引起urlscan疯狂的引言。这将有助于解决它。替换(“%e2%80%99”,“rsquo”)。 替换(“%e2%80%98”,“lsquo”)。 替换(“%e2%80%9d”,“rdquo”)。 替换(“%e2%80%9c”,“ldquo”)。 替换(“%e2%80%9b”,“lsrquo”)。 替换(“%e2%80%9f”,“ldrquo”)。 – Nate 2010-11-02 22:02:14

+0

查看web.config参数,例如'requestFiltering allowDoubleEscaping =“true”'(http://stackoverflow.com/a/1453287/1178314)和'httpRuntime requestValidationMode =“2.0”relaxedUrlToFileSystemMapping =“true”requestPathInvalidCharacters =“” '。在我的使用案例中,它允许我在url中支持更多字符。 – 2015-03-31 11:59:03

0

我猜你正在寻找HttpUtility.UrlEncodeHttpUtility.HtmlDecode

string url = "http://www.google.com/search?q=" + HttpUtility.UrlEncode("Example"); 
+1

感谢您的信息,虽然问题是更多的urlencode /解码不工作,因为无论是asp.net或iis仍然拒绝编码的网址。我想我最终使用了替代方案,但这是一段时间,所以我有点模糊。 – 2011-12-17 17:45:05