我理解为什么会这样,但我需要一个解决方法。我在StackOverflow上查看了一些其他问题,但没有一个是有用的。我不想在整个网站上禁用输入验证,因为这绝对是危险的。我只有一个(至少现在)我需要禁用输入验证的地方。
我用[ValidateInput(false)]属性修饰了Action方法,我用Html.Encode对字符串进行编码。但是,我仍然得到同样的错误。这是我的观点:
<div id="sharwe-categories">
<ul class="menu menu-vertical menu-accordion">
@foreach(var topLevel in Model)
{
var topLevelName = Html.Encode(topLevel.Name);
<li class="topLevel">
<h3>
@Html.ActionLink(topLevel.Name, "Index", "Item", new { category = topLevelName }, new {@class = "main"} )
<a href="#" class="drop-down"></a>
</h3>
<ul>
@foreach (var childCategory in topLevel.Children)
{
var childcategoryName = Html.Encode(childCategory.Name);
<li>@Html.ActionLink(childCategory.Name, "Index", "Item", new RouteValueDictionary { { "category", topLevelName }, { "subcategory", childcategoryName } }, null)</li>
}
</ul>
</li>
}
</ul>
</div>
如您所见,没有用户输入。但是一些类别名称中有一些“危险”字符......任何解决方案?
答案 0 :(得分:11)
尽管Darin的答案是完全可行的,但我不建议使用Scott Hanselman的技术逐步完成所有这些验证。你迟早会深陷......
使用ID和虚拟字符串(对SEO和人们来说很棒)的第二个建议是一种方法,但有时它们也不可行。想象一下这个请求URL:
/111/Electronics/222/Computers/333/Apple
虽然我们拥有这些ID,但我们也可以依赖这些ID和人类/ SEO友好类别名称,这绝对不是必需的。当我们需要代表一个单独的项目时,ID + Dummy字符串是可行的。在其他情况下,它不是。由于你必须显示类别和子类别,这是一个问题。
那你能做什么?
两种可能的解决方案:
清理类别名称只能包含有效字符 - 可以这样做但如果特权用户不是静态和可编辑的,那么你在这里运气不好,因为即使你现在已经清理它们了,有人会在以后输入无效的内容
随时随地清理字符串 - 当您使用类别名称时,清理它并在阅读和使用它时(为了获得实际的类别ID)您可以比较提供的(先前已清除的)类别名称和值您即时清理的数据库:
我建议你采用2.2方法。将数据库表扩展为两列:
您还可以在第二列上设置唯一约束,因此不会发生两个类别(即使它们具有不同的显示名称)具有相同的URL友好名称。
首先想到的是剥离无效字符,但这非常繁琐,你很可能会遗漏一些东西。从类别显示名称中获取有效字符会更容易,更明智。生成虚拟 URL类别名称时,我也做了同样的事情。只需取出有效的东西,然后将其余部分分开。它通常工作得很好。这种正则表达式的两个例子:
(\w{2,})
- 仅使用字母,数字和下划线以及其中至少两个(因此我们省略 a 或单个数字和相似内容,不会增加任何含义并且不必要地延长我们的网址([a-zA-Z0-9]{2,})
- 只有字母和数字(也是2 +)获取类别显示名称中的所有匹配项,并使用空格/破折号连接它们并与原始显示名称一起保存。另一个question of mine就是这个。
为什么要添加其他列?因为您无法在SQL Server中运行正则表达式。如果您正在使用MySql,则可以使用一列并在DB上使用正则表达式。
答案 1 :(得分:2)
即使你不应该这样做......有时也没有一种简单的方法可以绕过它。 web.Config中的httpRuntime标记上的requestPathInvalidCharacters是您寻求的。只需在&lt; system.web&gt;中输入以下内容即可。部分:
<httpRuntime requestPathInvalidCharacters="<,>,*,%,:,\" />
我强烈建议使用以下内容将其锁定:
<location path="the/path/you/need/to/lock/down">
<system.web>
<httpRuntime requestPathInvalidCharacters="<,>,*,%,:,\"/>
</system.web>
</location>
只需将其投入根&lt; configuration&gt;标签。这样......你不会打开你的整个网站,以允许在路径中使用&符号......并且可能会使整个站点暴露在不可预见的攻击中。
答案 2 :(得分:0)
您可能会发现following blog post对于在网址中使用特殊字符非常有用。但总的来说,最好的做法是replace those titles with slugs和StackOverflow一样,在url中使用问题标题来获得更好的搜索引擎优化,并使用ID来识别它们。