【问题标题】:Routing with only {id} parameter returns "resource cannot be found" error仅使用 {id} 参数的路由返回“找不到资源”错误
【发布时间】:2018-04-09 22:40:17
【问题描述】:

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

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

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

这样的 URL

其中:Products 是我的控制器名称,index 是我的操作名称,123可为空的 @987654321 @参数。

这是我的路线:

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

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

提前致谢。

【问题讨论】:

  • 您的WrappedViewModels 定义如何?这应该可以正常工作。您正在尝试的 404 网址是什么?
  • 嗨。我已经编辑了我的问题,这个 URL “www.mysite.com/123”出现错误
  • 您需要包含所有路线,因为顺序很重要。
  • 该路由必须是第一个,但这也意味着您的大多数其他 url 都可以工作(您需要一个路由约束)。您需要显示所有路线定义
  • 我已经用请求的信息更新了我的问题,希望对您有所帮助。

标签: c# asp.net-mvc routing


【解决方案1】:

在 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" })

我认为这会立即解决您的问题。

【讨论】:

    【解决方案2】:

    如果您确定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*")
    );
    

    【讨论】:

      【解决方案3】:

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

      所以 交换 OnlyIdDefault 规则并且不需要更多更改。我相信它现在应该可以正常工作了。

      【讨论】:

        猜你喜欢
        • 2012-10-27
        • 2018-07-18
        • 2011-08-31
        • 2016-02-23
        • 2017-02-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多