子网址的ASP.NET MVC WebApi路由

时间:2014-05-06 06:32:54

标签: c# asp.net-web-api routes

这个主题有很多问题,但我几乎找不到解决我的问题。

同样Stackoverflow,我想得到问题(主)和回复(细节)层次json与以下四种情况。

  1. / api / question /:问题列表
  2. / api / question / {id}:ID问题
  3. / api / question / {id} / reply /:回复列表中的问题。
  4. / api / question / {id} / reply / {rid}:问题的一个回复项目。
  5. WebApi CRUD为我生成的两个网址不是问题。 但是在两个网址之下,我无法做到。

    以下方法是QuestionController中的相关方法(请注意,控制器名称为Question)。

    // case 1.
    public virtual Question Get(){
        // return list of questions
    }
    
    // case 2.
    public virtual Question Get(Int64 id)
    {
        // return question item.
            var item = ((IQuestionRepository)repository).GetFirstFiltered(n => n.Id == id);
            return item;
    }
    
    // case 3.
    public virtual Question GetReply(Int64 id)
    {
        // return a list of replies         
    }
    
    // case 4.
    public virtual Question GetReply(Int64 id, Int64 rid)
    {
        // return reply item of rid.
    }
    

    首先尝试
    我在默认路由上添加了如下路由,但只触发了第四种方法。第三个被省略。

                config.Routes.MapHttpRoute(
                name: "QuestionApi",
                routeTemplate: "api/{controller}/{id}/reply/{rid}",
                defaults: new
                {
                    controller = "Question",
                    rid = RouteParameter.Optional
                }
            );
    

    第二次尝试
    我在WebApi2中创建了新引入的Route属性。在案例3和4中没有命中。

        // case 3.
        [Route("reply")]
        public virtual Question GetReply(Int64 id)
        {
            // return list of reply
        }
    
        // case 4.
        [Route("reply/{rid}")]
        public virtual Question Get(Int64 id, Int64 rid)
        {
            // return reply item
        }
    
    如果我从第一个地址设置为"~api/{controller}/{id}/reply"

    路由可行,但它似乎不是一个好的解决方案。

    我该怎么做?

2 个答案:

答案 0 :(得分:0)

我想知道为什么单个Controller应该包含所有方法?

为了使其更易于管理,我们始终建议拥有多个控制器。

我可以建议的是

  1. 制作一个名为Reply的新控制器
  2. 回复将始终指望参数,即QuestionId
  3. 如果需要Particualr Reply Id,则/ QuestionId / ReplyId
  4. 路线可以是

    config.Routes.MapHttpRoute(
                name: "ReplyApi",
                routeTemplate: "api/{controller}/{id}/{rid}",
                defaults: new
                {
                    controller = "Reply",
                }
    

    更新

    尝试http://mvccoderouting.codeplex.com/ 它为路由提供了更大的灵活性

    对于您的方法,您可以尝试

    public ActionResult Reply(int Questionid, int? ReplyId) {
    
       if (ReplyId.HasValue) {
          // ReplyId present
       } else {
          // ReplyId not present
       }
    }
    

答案 1 :(得分:0)

为了在没有@Nipun介绍的http://mvccoderouting.codeplex.com/的帮助下解决我的问题,我向控制器类添加了RoutePrefix并为每个方法添加了Route属性。有点脏,但如果您的控制器没有很多动作,请使用它。

否则,http://mvccoderouting.codeplex.com/是一个不错的选择。