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

时间:2012-06-07 18:18:49

标签: asp.net asp.net-mvc rest 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. 在查询字符串中传递参数。
    What is best way to pass multiple query parameters to a restful api?

  3. 定义路线中的参数: API /控制器/日期1 /日期2

  4. 使用POST本身允许我传递带有参数的对象。

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

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

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

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

11 个答案:

答案 0 :(得分:126)

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

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

示例:

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

{}名称需要与您的参数匹配。

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

答案 1 :(得分:48)

只需在WebApiConfig条目中添加新路线即可。

例如,致电:

public IEnumerable<SampleObject> Get(int pageNumber, int pageSize) { ..

添加:

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

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

GET //<service address>/Api/Data/2/10 

答案 2 :(得分:46)

我只需要实现一个RESTfull api,我需要传递参数。我通过传递查询字符串中的参数来完成此操作,其格式与Mark的第一个示例“api / controller?start = date1&amp; end = date2”

所描述的相同。

在控制器中,我使用了来自URL split in C#?

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

在我的情况下,我通过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');
                       }
        }
   });

我希望这会有所帮助......

答案 3 :(得分: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
    }
}

答案 4 :(得分:10)

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

答案 5 :(得分:8)

@LukLed 清楚地解释了

使用 GET POST 。关于你可以传递参数的方法,我建议采用第二种方法(我不太了解 ODATA )。

  

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

这不是用户友好 SEO友好

  

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

这是通常的首选方法。

  

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

这绝对不是一个好方法。这使得感觉某个date2date1的子资源,而事实并非如此。 date1date2都是查询参数,并且属于同一级别。

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

api/controller?start=date1&end=date2

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

api/controller/date1,date2

答案 6 :(得分:8)

答案 7 :(得分:2)

 [Route("api/controller/{one}/{two}")]
    public string Get(int One, int Two)
    {
        return "both params of the root link({one},{two}) and Get function parameters (one, two)  should be same ";
    }

根链接({one},{two})的两个参数和Get函数参数(一个,两个)应该相同

答案 8 :(得分:1)

现在您只需使用

        public string Get(int id, int abc)
        {
            return "value: " + id + "  " + abc;
        }

这将返回:“值:5 10”

如果您用https://yourdomain/api/yourcontroller?id=5&abc=10

调用

答案 9 :(得分:0)

    public HttpResponseMessage Get(int id,string numb)
    {
        //this will differ according to your entity name
        using (MarketEntities entities = new MarketEntities())
        {
          var ent=  entities.Api_For_Test.FirstOrDefault(e => e.ID == id && e.IDNO.ToString()== numb);
            if (ent != null)
            {
                return Request.CreateResponse(HttpStatusCode.OK, ent);
            }
            else
            {
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, "Applicant with ID " + id.ToString() + " not found in the system");
            }
        }
    }

答案 10 :(得分:0)

我知道这确实很老,但是最近我想要同样的东西,这就是我发现的东西...

    public HttpResponseMessage Get([FromUri] string var, [FromUri] string test) {
        var retStr = new HttpResponseMessage(HttpStatusCode.OK);
        if (var.ToLower() == "getnew" && test.ToLower() == "test") {
            retStr.Content = new StringContent("Found Test", System.Text.Encoding.UTF8, "text/plain");
        } else {
            retStr.Content = new StringContent("Couldn't Find that test", System.Text.Encoding.UTF8, "text/plain");
        }

        return retStr;
    }

所以现在在您的地址/ URI /...

http(s):// myURL / api / myController /?var = getnew&test = test

结果:“找到测试”


http(s):// myURL / api / myController /?var = getnew&test =任何东西

结果:“找不到该测试”