Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带PUT的ASP.NET Web API路由_Asp.net_Asp.net Mvc_Asp.net Web Api Routing - Fatal编程技术网

带PUT的ASP.NET Web API路由

带PUT的ASP.NET Web API路由,asp.net,asp.net-mvc,asp.net-web-api-routing,Asp.net,Asp.net Mvc,Asp.net Web Api Routing,我正在尝试为我认为非常简单的事情设置WebAPI路由。然而,Web API中的路由似乎与不同的HTTP谓词不一致。假设我有这个控制器和这些动作 public class AvalancheController : ApiControllerBase { // GET api/avalanche public IEnumerable<Avalanche> Get() {} // GET api/avalanche/5 public Avalanche

我正在尝试为我认为非常简单的事情设置WebAPI路由。然而,Web API中的路由似乎与不同的HTTP谓词不一致。假设我有这个控制器和这些动作

public class AvalancheController : ApiControllerBase
{

    // GET api/avalanche
    public IEnumerable<Avalanche> Get() {}

    // GET api/avalanche/5
    public Avalanche Get(int id) {}

    // GET api/avalanche/ActionTest/5
    [ActionName("ActionTest")]
    public Avalanche GetActionTest(int id) {}

    // GET api/avalanche/ActionTest/2
    [ActionName("ActionTest2")]
    public Avalanche GetActionTest2(int id) {}

    // POST api/avalanche
    public void Post([FromBody]Avalanche value) {}

    // PUT api/avalanche/5
    public void Put(int id, [FromBody]Avalanche value) {}

    // PUT api/avalanche/test/5
    [ActionName("Test")]
    public void PutTest(int id, [FromBody]Avalanche value) {}

    // DELETE api/avalanche/5
    public void Delete(int id) {}
}
最后,我定义了以下路线

    config.Routes.MapHttpRoute(
        name: "ActionRoutes",
        routeTemplate: "api/{controller}/{action}/{id}",
        defaults: new { id = RouteParameter.Optional },
        constraints: new
            {
                controller = "Avalanche",
                action = "(ActionTest|ActionTest2|Test)"
            }
    );


    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
GET api/Avalanche/ActionTest/{id}
GET api/Avalanche/ActionTest2/{id}
PUT api/Avalanche/Test/{id}
GET api/Avalanche   
POST api/Avalanche  
DELETE api/Avalanche/{id}
为什么默认的PUT路由没有被拾取?默认GET和默认PUT的路由有什么不同?我尝试过用各种可以想象的方式来装饰函数,但我得到了同样的结果

我主要想知道如何获取要拾取的默认PUT路由。如果您对如何修改这些路由有任何建议,这样我就不必为每个控制器指定一个路由来指定操作名称,这也将非常棒

谢谢

伊恩

编辑:今天早上我注意到以下路线也没有定义

GET api/Avalanche/{id}

很高兴你找到了解决问题的办法。但我会根据我在REST服务中的学习情况提供反馈。RESTWebService的想法是将每个url解析为一个资源(或者可能是实体),并根据HttpVerb决定操作。在本例中,您有三个GET操作,这些操作与您的修改配合得很好

但我认为,控制器也可以重新安排为具有单一GET操作和单一责任,从而提高可维护性。例如:

雪崩控制器

public class AvalancheController : ApiControllerBase
{
    public IEnumerable<Avalanche> GET()
    {

    }

    public void POST(Avalanche avalanche)
    {

    }
}
public class AvalancheDetailsController : ApiControllerBase
{
    public Avalanche GET(int id)
    {

    } 


    public int PUT(int id)
    {

    }

    public int DELETE(int id)
    {

    }
}
可以假设它处理单个雪崩,下面是要定义的操作

GET:返回单个雪崩
POST:未使用
PUT:更新单个雪崩
删除:删除单个雪崩

现在我假设我们对控制器有了明确的区分。在您提到的OP中,可以有不同的GET操作,但它只返回单个
Avalanche
。因此,我将更改GET方法,以对象作为输入,并检查值,即

public class AvalanceRequest
{
  public int? Id {get;set;}
  public string Name {get;set;}
}


   public class AvalancheDetailsController : ApiControllerBase
    {
        public Avalanche GET(AvalanceRequest request)
        {
           //write business logic based on parameters
           if(request.Id.HasValue)
           //return avalanche;
           if(request.Name.IsNullOrEmpty())
           //return avalanche
        } 
        //other methods
  }
在处理URL时,我并没有真正使用WebAPI,而是尝试使用ServiceStack开发REST服务。它允许附加独立于控制器名称的url

Url
api/Avalanche-->AvalancheController(基于HttpVerb调用操作)
api/Avalanche/Id-->AvalancheDetailsController(基于HttpVerb调用操作)

我不知道是否可以在WebAPI中同样附加url,否则您将使用默认配置并通过调用。api/雪崩和api/雪崩详细信息/id

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

很抱歉发了这么长的帖子,希望有意义。

有趣的方法。我得好好考虑一下。这是我的第一个RESTAPI,所以我当然愿意接受所有的想法。我一直遵循的想法是,容器将描述所操作的主要数据类型,并使用操作来描述更困难的操作。例如,如果需要返回雪崩项目数组(如GetAvalanchCreatedWithinTerrange())的更复杂的查找,该怎么办?“每个动词有一个功能的想法很快就被打破了。”IanLee,我还在学习。对,实施前想一想比较好。对于你的问题,因为它是IEnumerable上的一个过滤器