C# Web API-REST帮助和说明

C# Web API-REST帮助和说明,c#,web-services,rest,asp.net-web-api,C#,Web Services,Rest,Asp.net Web Api,我正在使用WebAPI编写一个API,当我从头开始设计这个API时,我正在尝试使它成为RESTful的。在过去做web服务工作时,我总是使用RPC模式(ASMX、SOAP等)——例如,使用与我希望它执行的操作相匹配的任意方法名。对我来说,这似乎比REST更直观、更明确,但考虑到WebApi本质上更为RESTful(我知道您可以更改路由,所以它不是),我决定尝试使其成为RESTful 我理解(我想!)基础知识-例如,在指定ID时发布以创建、放置以更新、获取、删除以删除等 我的困惑是如何处理返回的集

我正在使用WebAPI编写一个API,当我从头开始设计这个API时,我正在尝试使它成为RESTful的。在过去做web服务工作时,我总是使用RPC模式(ASMX、SOAP等)——例如,使用与我希望它执行的操作相匹配的任意方法名。对我来说,这似乎比REST更直观、更明确,但考虑到WebApi本质上更为RESTful(我知道您可以更改路由,所以它不是),我决定尝试使其成为RESTful

我理解(我想!)基础知识-例如,在指定ID时发布以创建、放置以更新、获取、删除以删除等

我的困惑是如何处理返回的集合与单个对象。例如,假设我有一个名为
userscoontroller
的API控制器。据我所知,我有以下URL:

GET: /api/users (lists all users)
GET: /api/users/1 (lists details about user with ID 1)
POST: /api/users (creates a new user with details sent in the POST data)
PUT: /api/users/1 (updates the existing user with ID 1 with details sent in the POST data)
DELETE: /api/users/1 (deletes the existing user with ID 1)

对于上面的第一个URL,我还需要发送各种筛选/搜索条件。这个条件只是作为查询字符串参数传递吗?或者我应该为这个“搜索”功能使用完全不同的控制器吗?用户搜索控制器?如果是的话,在这种情况下,这应该是一个帖子还是一个GET?实际上,在我写这篇文章时,我想知道一个单独的控制器是否有意义,因为我可能希望在GET中为单个用户返回比在搜索结果中更多的细节。如果同一个控制器为单个对象GET返回不同的数据,而不是为返回集合的GET返回不同的数据,这是否会使它不是RESTful的?

是的,我会将过滤器参数作为查询字符串选项传递。应用程序的“RESTfusion”不依赖于控制器结构,因此可以遵循最适合应用程序的结构

对于上面的第一个URL,我还需要发送各种筛选/搜索条件。这个条件只是作为查询字符串参数传递吗

使用查询字符串来指定过滤器/搜索参数绝对有意义

对于这个“搜索”功能,我应该使用完全不同的控制器吗?用户搜索控制器

你不应该那样做。我在这里看到了两个原因:

  • GET:/api/users
  • 您可以通过一种方法轻松实现
    GET:/api/users
    GET:/api/users?filter=…&sort=…
    GET:/api/users/1

    //If you are using EF it could look like
    //filter and sort arguments could be added here as well
    public HttpResponseMessage Get(int? id)  
    {
       if(id.HasValue)
       {
           return Request.CreateResponse(
               HttpStatusCode.OK, 
               Context.Users.SingleOrDefault<Users>(u => u.Id == id));              
       }
    
       var users = Context.Users.Select(apply filter).OrderBy(apply sort).ToList();
       return Request.CreateResponse(HttpStatusCode.OK, users);   
    }
    
    //如果您使用的是EF,它可能看起来像
    //这里也可以添加筛选和排序参数
    公共httpresponsemessageget(int?id)
    {
    if(id.HasValue)
    {
    return Request.CreateResponse(
    HttpStatusCode.OK,
    Context.Users.SingleOrDefault(u=>u.Id==Id));
    }
    var users=Context.users.Select(应用过滤器).OrderBy(应用排序).ToList();
    返回请求.CreateResponse(HttpStatusCode.OK,用户);
    }
    
  • 您可以看看-它可能会帮助您实现

  • 在不同的控制器之间传播此逻辑会损害单一责任原则-您的用户控制器应该处理与用户相关的所有逻辑,并且只处理此逻辑
  • 如果是的话,在这种情况下,这应该是一个帖子还是一个GET

    如果你想让你的API是RESTful的,你应该使用GET但是您应该知道,通过GET返回JSON对象数组可能容易受到攻击。此漏洞最简单的解决方案之一是只允许通过POST获取JSON数组(还有其他解决方案)

    我可能希望在GET中为单个用户返回比搜索结果中更多的详细信息。如果同一个控制器为单个对象GET和返回集合的GET返回不同的数据,这会使它不是RESTful吗

    对于单个对象返回的详细信息比对于集合返回的详细信息要多,这是完全正确的。它不会以任何方式影响API的RESTfull

    评论

    你写道:

    指定ID时放置以进行更新

    事实上,这并不完全正确:

    • PUT应用于整个实体的完全替换
    • 应使用修补程序执行部分更新

    如果希望通过条件作为URI的查询字符串参数传递,可以使用WebApi中的属性路由来实现。我想这对你有帮助。

    谢谢你的详细回答。如果我有一个单独的控制器来进行搜索,我之所以想使用POST是因为我将搜索本身视为一种资源,所以我假设因为我正在“创建搜索”,所以使用POST仍然是RESTful的。但也许这太扭曲了规则我明白你的意思,因为不必要地把它分离出来,它就不那么干了。另外,阅读关于JSON劫持的文章也很有趣!谢谢你的链接:)