仅使用 {id} 参数的路由返回错误"resource cannot be found"



我正在尝试按如下方式设置路由。

现在我的网址看起来像 www.mysite.com/Products/index/123

我的目标是像 www.mysite.com/123 一样设置 URL

其中:产品是我的控制器名称,索引是我的操作名称,123id参数为空

这是我的路线:

public static void RegisterRoutes(RouteCollection routes)
    {         
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
          "OnlyId",
          "{id}",
      new { controller = "Products", action = "index", id = UrlParameter.Optional }
     );
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

    }

这是我的行动方法

public ActionResult index (WrappedViewModels model,int? id)
    {
        model.ProductViewModel = db.ProductViewModels.Find(id);
        model.ProductImagesViewModels = db.ProductImagesViewModels.ToList();
        if (id == null)
        {
            return HttpNotFound();
        }
        return View(model);
    }

这是我的模型包装器:

 public class WrappedViewModels
{          
    public ProductViewModel ProductViewModel { get; set; }               
    public ProductImagesViewModel ProductImagesViewModel { get; set; }
    public List<ProductImagesViewModel> ProductImagesViewModels { get; set; 
}

此 URL 上抛出错误:www.mysite.com/123

问题是:为什么我的视图返回此错误以及如何避免此行为?

提前谢谢。

在 RegisterRoutes 中,您需要指定更多内容。

  routes.MapRoute(
    name: "OnlyId",
    url: "{id}",
    defaults: new { controller = "Products", action = "index" },
    constraints: new{ id=".+"});

然后您需要将每个锚标记的路由指定为

@Html.RouteLink("123", routeName: "OnlyId", routeValues: new { controller = "Products", action = "index", id= "id" })

我认为这会立即解决你。

如果您确定id参数是可为空的整数值,请使用如下所示d正则表达式放置路由约束,以便它不会影响其他路由:

routes.MapRoute(
     name: "OnlyId",
     url: "{id}",
     defaults: new { controller = "Products", action = "index" }, // note that this default doesn't include 'id' parameter
     constraints: new { id = @"d+" }
);

如果您对标准参数约束不满意,可以创建一个继承IRouteConstraint的类,并将其应用于自定义路由,如以下示例所示:

// adapted from /a/11911917/
public class CustomRouteConstraint : IRouteConstraint
{
    public CustomRouteConstraint(Regex regex)
    {
        this.Regex = regex;
    }
    public CustomRouteConstraint(string pattern) : this(new Regex("^(" + pattern + ")$", RegexOptions.CultureInvariant | RegexOptions.Compiled | RegexOptions.IgnoreCase)) 
    {
    }
    public Regex Regex { get; set; }
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        if (routeDirection == RouteDirection.IncomingRequest && parameterName == "id")
        {
            if (values["id"] == UrlParameter.Optional)
                 return true;
            if (this.Regex.IsMatch(values["id"].ToString()))
                 return true;
            // checking if 'id' parameter is exactly valid integer
            int id;
            if (int.TryParse(values["id"].ToString(), out id))
                 return true;
        }
        return false;
    }
}

然后在基于id路由上放置自定义路由约束,以使其他路由正常工作:

routes.MapRoute(
     name: "OnlyId",
     url: "{id}",
     defaults: new { controller = "Products", action = "index", id = UrlParameter.Optional },
     constraints: new CustomRouteConstraint(@"d*")
);
我想

你错过了路由顺序。因此,创建第一个处理所有可用控制器的路由定义,然后定义一个将处理其余请求的路由定义,例如,一个处理www.mysite.com/{id}类型的请求。

因此,交换OnlyId默认规则,无需更多更改。我相信它现在应该可以正常工作。

最新更新