我在Global.asax(MVC 3网络项目)中定义了以下路线:
routes.MapRoute(
"BlogCategory", // Route name
"Blog/Category/{*category}", // URL with parameters
new { controller = "Blog", action = "Index", category = "" } // Parameter defaults
);
我的动作接受一个类别参数,如下所示:
public ViewResult Index(string category, int page = 1)
{
PostListViewModel viewModel;
if (string.IsNullOrEmpty(category))
{
....show all cats else show only the one passed in
这样可以正常工作,并将类别传递给控制器,适当地过滤我的结果。
我的问题是,我创建的其中一个类别对于它的类别名称是这样的:
项目/实验室
(注意空格和斜线)
这会创建一个类似这样的URL:
/博客/分类/项目%20 /%20Lab
当我点击链接时,我收到此错误:
描述:HTTP 404.您正在寻找的资源(或其中一个 依赖项)可能已被删除,其名称已更改,或者是 暂时不可用。请查看以下网址并制作 确保它拼写正确。
请求的网址:/博客/类别/项目/实验室
调试时它永远不会到达索引操作。
我的问题是,如何才能完成这项工作,或者在创建类别名称时是否必须进行一些输入验证以防止这种情况发生?
答案 0 :(得分:0)
正如Tyrsius建议更容易传递类别ID,但如果您想传递名称,那么我建议您每次创建链接或创建自定义Url.Encode()
时使用UrlHelper
为你而做。一旦它命中你的控制器动作,只需执行Url.Decode(
)即可恢复原始字符串。
更简洁的方法是创建自己的路由处理程序(实现IRouteHandler
)来为你完成。
答案 1 :(得分:0)
首先,感谢Tyrsius,Romias和eth0的建议。
我决定我不想将Id用于类别,我不想创建路由处理程序,因为这不能解决根本问题。
相反,我创建了一个名为“UsedAsUrl”的验证属性,并将其应用于我的域模型中的Category.Name。 从开发人员的角度来看,这具有内置验证(对最终用户有利)和良好的可重用性的好处。
所以我的类别模型现在看起来像这样(注意[UsedAsUrl]属性):
public class Category
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
[UsedAsUrl]
[MaxLength(50, ErrorMessage = "One word or groups of words please")]
public string Name { get; set; }
public virtual List<Post> Posts { get; set; }
}
我创建的属性如下所示:
using System;
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
namespace CommonWebsiteUtilities.Attributes
{
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class UsedAsUrlAttribute : ValidationAttribute
{
public UsedAsUrlAttribute() : base("Must not contain a slash with spaces either side") {}
public override bool IsValid(object value)
{
var input = value.ToString();
var result = true;
if (input.Contains("/"))
{
input = Regex.Replace(input, @"\s+", " ");
if (input.Contains(" /")) result = false;
if (input.Contains("/ ")) result = false;
if (input.Contains(" / ")) result = false;
}
return result;
}
}
}
现在我去添加一个类别:
我自动收到此回复:
JS还没有工作,但我的控制器可以接收模型状态,这是它的响应,所以属性工作正常。
这基本上检查在任何一侧/任何一侧有空格的斜杠。请注意,这不是一个详尽的URL验证器,但它将适用于我当前的项目。如果有人有任何改进,请告诉我,我会修改这个答案。
我对RegExp并不擅长,所以没有从RegularExpressionAttribute派生,而且我也不想从我的模型中提供错误消息。当使用类别作为URL部分时,应该真正建立此属性,因为会出现更多规则。