我应该如何将多个参数传递给ASP.Net Web API GET?

sig*_*606 131 asp.net rest asp.net-mvc asp.net-mvc-4 asp.net-web-api

我正在使用.Net MVC4 Web API(希望)实现RESTful api.我需要将一些参数传递给系统并让它执行一些操作,然后返回一个对象列表作为结果.具体来说,我传递了两个日期并返回它们之间的记录.我还跟踪返回的记录,以便后续调用不会在系统中重新处理.

我考虑过几种方法:

  1. 将params序列化为单个JSON字符串并在API中将其分开. http://forums.asp.net/t/1807316.aspx/1

  2. 在查询字符串中传递参数.
    将多个查询参数传递给restful api的最佳方法是什么?

  3. 定义路径中的参数:api/controller/date1/date2

  4. 使用POST本身可以让我传递一个带有params的对象.

  5. 研究ODATA,因为Web API(目前)支持它.我还没有做太多,所以我对它不是很熟悉.

似乎正确的REST实践表明何时提取数据,您应该使用GET.但是,GET也应该是无效的(不会产生副作用),我想知道我的具体实现是否违反了,因为我在API系统中标记了记录,因此我产生了副作用.

它还引出了支持变量参数的问题.如果输入参数列表发生变化,那么如果发生很多事情,必须重新定义选择3的路线将是很繁琐的.如果在运行时定义参数会发生什么......

在任何情况下,对于我的具体实现,哪个选择(如果有的话)似乎最好?

Mar*_*.io 132

我认为最简单的方法就是简单地使用AttributeRouting.

在您的控制器中显而易见,您为什么要在全局WebApiConfig文件中使用它?

例:

    [Route("api/YOURCONTROLLER/{paramOne}/{paramTwo}")]
    public string Get(int paramOne, int paramTwo)
    {
        return "The [Route] with multiple params worked";
    }
Run Code Online (Sandbox Code Playgroud)

{}名称必须符合您的参数.

就这么简单,现在你有一个单独GET处理这个实例中的多个参数.

  • 这很棒.大多数人建议在`WebApiConfig`文件中设置路由,但这确实更好. (11认同)
  • 实际上,我们(大多数人)确实建议为您的配置设置集中管理区域.对于Web API(Microsoft或其他),REST的集中模式是关键.属性路由很可爱,但它使一次性异常太诱人了. (4认同)
  • 同意,我需要实际更新我的答案.使用GET进行多个参数的方法要好得多.当我更新WebAPI时发布这个,现在我不使用AttributeRouting(除非我只是不想创建一个新的Controller),并传递QueryString中的所有参数,它们会自动映射.当我有机会更新,以便人们不使用这种旧方法 (3认同)

Gra*_*ght 49

只需为WebApiConfig条目添加新路由即可.

例如,致电:

public IEnumerable<SampleObject> Get(int pageNumber, int pageSize) { ..
Run Code Online (Sandbox Code Playgroud)

加:

config.Routes.MapHttpRoute(
    name: "GetPagedData",
    routeTemplate: "api/{controller}/{pageNumber}/{pageSize}"
);
Run Code Online (Sandbox Code Playgroud)

然后将参数添加到HTTP调用:

GET //<service address>/Api/Data/2/10 
Run Code Online (Sandbox Code Playgroud)

  • 这似乎是列出所有部分的唯一答案.我希望有人能更好地描述如何使用`api/controller?start = date1&end = date2`样式的URI. (10认同)

Nig*_*ter 45

我只需要实现一个RESTfull api,我需要传递参数.我通过传递查询字符串中的参数来完成此操作,其格式与Mark的第一个示例"api/controller?start = date1&end = date2"所描述的相同.

在控制器中我使用了来自C#中URL分割的提示

// uri: /api/courses
public IEnumerable<Course> Get()
{
    NameValueCollection nvc = HttpUtility.ParseQueryString(Request.RequestUri.Query);
    var system = nvc["System"];
    // BL comes here
    return _courses;
}
Run Code Online (Sandbox Code Playgroud)

在我的情况下,我通过Ajax调用WebApi看起来像:

$.ajax({
        url: '/api/DbMetaData',
        type: 'GET',
        data: { system : 'My System',
                searchString: '123' },
        dataType: 'json',
        success: function (data) {
                  $.each(data, function (index, v) {
                  alert(index + ': ' + v.name);
                  });
         },
         statusCode: {
                  404: function () {
                       alert('Failed');
                       }
        }
   });
Run Code Online (Sandbox Code Playgroud)

我希望这有帮助...

  • 我猜你没有使用WebApi,因为ParameterBinding会自动将你的查询字符串映射到你的api方法参数...... (2认同)

小智 37

我在http://habrahabr.ru/post/164945/找到了优秀的解决方案

public class ResourceQuery
{
   public string Param1 { get; set; }
   public int OptionalParam2 { get; set; }
}

public class SampleResourceController : ApiController
{
    public SampleResourceModel Get([FromUri] ResourceQuery query)
    {
        // action
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这里的线索是[FromUri] (5认同)
  • 虽然这篇文章是俄文的,但@tranceporter是对的."FromUri"看起来是从网址获取参数的好方法.另一篇可能有用的文章:http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api (2认同)

Luk*_*Led 10

这个记录标记是什么意思?如果这仅用于记录目的,我将使用GET并禁用所有缓存,因为您要记录此资源的每个查询.如果记录标记有另一个目的,POST就是要走的路.用户应该知道,他的动作影响系统,POST方法是一个警告.


VJA*_*JAI 8

@LukLed清楚地解释了使用GETPOST.关于你可以传递参数的方法,我建议采用第二种方法(我对ODATA也不太了解).

1.将params转换为单个JSON字符串并在API中将其拆分.http://forums.asp.net/t/1807316.aspx/1

这不是用户友好SEO友好

2.在查询字符串中输入params.将多个查询参数传递给restful api的最佳方法是什么?

这是通常的优选方法.

3.定义路径中的参数:api/controller/date1/date2

这绝对不是一个好方法.这使得感觉某人date2是子资源date1而事实并非如此.两者都是date1date2查询参数并且处于同一级别.

在简单的情况下,我会建议像这样的URI,

api/controller?start=date1&end=date2
Run Code Online (Sandbox Code Playgroud)

但我个人喜欢下面的URI模式,但在这种情况下,我们必须编写一些自定义代码来映射参数.

api/controller/date1,date2
Run Code Online (Sandbox Code Playgroud)

  • 对不起,这个迟到的回应,马克.我曾尝试了一些解决方案,但不确定哪个是最好的,并且试图坚持使用行业标准的方法,所以我在这里发布了SO. (2认同)