【问题标题】:how to use/configure routing in MVC如何在 MVC 中使用/配置路由
【发布时间】:2016-10-11 15:04:25
【问题描述】:

当它被称为 /api/Games/aaa 时,我希望运行方法 Get(string deviceId = "")。但是当它被称为 api/Games/GameById/TaskId 我希望方法 GameById(int id) 被运行。但它不起作用,尤其是第二种方法。

控制器:

public class GamesController : ApiController
    {
        private List<Game> _gamesRepository;


        public GamesController()
        {
            _gamesRepository = CreateGamesRepository();
        }



        // GET api/Games/DeviceId
        [HttpGet]
        public IEnumerable<Game> Get(string deviceId = "")
        {
            IEnumerable<Game> result;

            if (String.IsNullOrEmpty(deviceId))
            {
                result = _gamesRepository.AsEnumerable();
            }
            else
            {
                result = _gamesRepository.Where(x => x.DeviceId == deviceId).AsEnumerable();
            }
            return result;

        }


        // GET api/Games/GameById/Id
        [HttpGet]
        public IEnumerable<Game> GameById(int id)
        {
            IEnumerable<Game> result;

            result = _gamesRepository.Where(x => x.TaskId == id).AsEnumerable();

            return result;

        }

路由:

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

            routes.MapRoute(
            name: "GamesRoute",
            url: "api/{controller}/{deviceId}",
            defaults: new { controller = "controller", action = "get", deviceId = UrlParameter.Optional }
        );

            routes.MapRoute(
           name: "GamesRoute2",
           url: "api/games/GameById/{id}",
                // defaults: new { id = UrlParameter.Optional }
                defaults: new { controller = "games", action = "GameById" },
                constraints: new { id = @"\d+" }
       );

型号:

   public class Game
    {
        public int TaskId { get; set; }
        public string SalesForceId { get; set; }
        public string Name { get; set; }
        public string Thumbnail { get; set; }
        public string DeviceId { get; set; }
    }
}

【问题讨论】:

  • 以下任何答案都回答了您的问题吗?
  • 我不得不承认 :) ... 不 :)。我刚刚弄错了 2 个文件:RouteConfig 和 WebApiConfig :)。当我使用 webapiconfig 时,一切都按预期工作:)
  • 您能否将您的解决方案作为答案发布或关闭您的问题(或在下面选择一个答案)?

标签: c# asp.net-mvc asp.net-web-api asp.net-web-api-routing


【解决方案1】:

您可以尝试将 RouteParameters 设置为可选吗?

defaults: new { id = RouteParameter.Optional }

【讨论】:

    【解决方案2】:

    地图路线的顺序很重要,因为匹配的第一条路线获胜,并且框架停止寻找更多路线。

    一般路线应该添加在更具体的路线之后。

    public static class WebApiConfig {
    
        public static void Register(HttpConfiguration config) {
    
             config.Routes.MapRoute(
               name: "GamesRoute2",
               routeTemplate: "api/games/GameById/{id}",
               defaults: new { controller = "games", action = "GameById" },
               constraints: new { id = @"\d+" }
            );
    
            config.Routes.MapRoute(
                name: "GamesRoute",
                routeTemplate: "api/{controller}/{deviceId}",
                defaults: new { controller = "controller", action = "get", deviceId = UrlParameter.Optional }
    
            );
         }
    }
    

    【讨论】:

    • 感谢帮助,但是当调用http://localhost:49296/api/Games/GameById/11时,结果是'找不到资源'
    • 当调用 http://localhost:49296/api/Games/aaa 运行时。错误是“请求无效。 参数字典包含方法“System.Collections”的不可为空类型“System.Int32”的参数“id”的空条目。 'Int29MockedBackend.Controllers.GamesController' 中的 Generic.IEnumerable`1[Int29MockedBackend.Models.Game] GameById(Int32)'。可选参数必须是引用类型、可空类型或声明为可选参数。 ' 。与更改前相同。
    • 等等。您正在配置错误的路线。你的控制器是 ApiController 还是普通的 Mvc Controller
    【解决方案3】:

    我个人认为您不需要映射 Web API 配置中的每条路由。使用可持续的架构并支持您想要使用的设计类型。

    在您的情况下,我会通过在 WebApiConfig 中使用此配置来为我的 API 使用更具描述性的 URI:

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
    

    它的作用是允许您在 URI 中指定 /action,这样您就可以在调用中非常明确。然后您的端点将变为:

    /api/games/getById?id=1
    /api/games/get?"Test"
    

    编辑

    如果您希望路由与 api/games/{parameter} 完全匹配,那么我会在该方法上添加一个 Route 属性,如下所示:

    [Route("api/games/{id}")]
    public IEnumerable<Game> Get(string deviceId = "")
    

    希望这会有所帮助。

    【讨论】:

    • 假设我需要使用格式: api/games/aaa, api/Games/GameById/TaskId 。我有existign API,我只想切换服务器名称来使用它。
    猜你喜欢
    • 1970-01-01
    • 2016-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-25
    • 1970-01-01
    相关资源
    最近更新 更多