繁体   English   中英

仅使用{id}参数的路由返回“找不到资源”错误

[英]Routing with only {id} parameter returns “resource cannot be found” error

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

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

我的目标是设置网址,如www.mysite.com/123

其中: Products是我的控制器名称, index是我的动作名称, 123空的 id参数。

这是我的路线:

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 regex这样放置路由约束,以免影响其他路由:

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}类型的请求的路由定义。

因此, 交换 OnlyIdDefault规则,并且不需要其他更改。 我相信它现在应该可以正常工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM