如何传递多个参数以获取方法并在.NET Core Web API中进行路由?

时间:2019-06-05 13:51:03

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

我正在.NET Core中制作一个(轻松的)Web API,并偶然发现了一些问题。

我似乎找不到如何传递多个订阅ID的...。我需要能够显示多个订阅的多个期间(发票)。

我目前的路线是 [Route(“ tenant / {tenantId:long} / subscriptions / {subscriptionId:long} / invoices / {invoiceId:long} / categories”)]

通过这种方式,我似乎无法传递更多的订阅ID。 我发现但不完全理解的一些术语是:

  • 模型绑定
  • [FromQuery]

我的课程:

    public class Subscription
    {
    public string Name { get; set; }
    public long TenantId { get; set; }
    public string Guid { get; set; }
    }

    public class Invoice
    {
    public long SubscriptionId { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public long PortalId { get; set; }
    }

我的路由为[Route("tenants/{tenantId:long}/subscriptions")][Route("tenants/{tenantId:long}/subscriptions/{subscriptionId:long}/invoices")]的控制器

    [HttpGet]
    public IEnumerable<SubscriptionViewModel> Find(long tenantId)
    {
        var subscriptionList = _subscriptionManager.Find(tenantId);
        ...
        return subscriptionViewModels;
    }

    [HttpGet]
    public IEnumerable<InvoiceViewModel> Find(long subscriptionId)
    {
        var invoiceList = _invoiceManager.Find(subscriptionId);
        ...
        return invoiceViewModels;
    }
  • 请注意,我对数据使用映射器(这就是为什么我使用ViewModels的原因)。
  • 当前编写的代码用于特定的订阅。

我正在寻找类似 / api / invoices?subscriptionId = x,y,z

的路线

我了解(?),我需要[FromQuery],但是我似乎无法找出方法,尤其是如果我的参数(subscriptionId)保持不变。

3 个答案:

答案 0 :(得分:2)

您提到的要求:

  

我正在寻找/ api / invoices?subscriptionId = x,y,z之类的路线

您可以做几件事:

  1. 在URL的查询字符串中依次传递subscriptionIds,并用&隔开,并更改action方法的输入参数以接受subscriptionIds数组 路线示例:
/api/invoices/find?subscriptionId=x&subscriptionId=y&subscriptionId=z

接受订阅ID数组的操作方法参数的示例:

public IEnumerable<InvoiceViewModel> Find([FromQuery]long[] subscriptionId)
  1. 在URL中将逗号分隔的字符串作为querystring传递,并在action方法中编写一段逻辑以基于逗号分割字符串以获取subscriptionIds数组 路线示例:
/api/invoices/find?subscriptionIds=x,y,z

操作方法示例:

public IEnumerable<InvoiceViewModel> Find([FromQuery]string subscriptionIds)
{
    var ids = subscriptionIds.Split(',').Select(int.Parse).ToArray();
    // do the logic on multiple subscriptionIds
}

除此之外,您还可以创建自定义模型活页夹以及其他答案中的建议。

希望这会有所帮助。

答案 1 :(得分:1)

您可以创建一个特定的请求视图模型,该模型接受发票ID的集合:

public class InvoiceRequestModel
{
    IEnumerable<long> InvoiceIDS { get; set; }
}

并将其用于您的操作方法:

[Route("tenants/{tenantId:long}/subscriptions/{subscriptionId:long}/invoices")]
[HttpGet]
public IEnumerable<InvoiceViewModel> Get(InvoiceRequestModel requestModel)
{

}

如果要使用查询参数,请使用[FromQuery]属性标记操作参数:

[Route("tenants/{tenantId:long}/subscriptions/{subscriptionId:long}/invoices")]
[HttpGet]
public IEnumerable<InvoiceViewModel> Get([FromQuery]IEnumerable<long> invoiceIDs)
{

}

并在创建请求时,在查询字符串中使用相同的键传递每个值:

invoiceIDs=1&invoiceIDs=2&invoiceIDs=3

最后,它看起来像这样:

tenants/{tenantId}/subscriptions/{subscriptionId}/invoices?invoiceIDs=1&invoiceIDs=2&invoiceIDs=3

答案 2 :(得分:1)

可以有很多方法来完成此任务(我现在可以想到两三个)。

1)代替长的subscriptionid,而是将字符串作为输入并在继续进行操作之前对其进行验证。

[HttpGet]
public IEnumerable<InvoiceViewModel> Find(string subscriptionIds)
{
    var list = validateInput(subscriptionIds);
    var invoiceList = _invoiceManager.FindList(list);
    ...
    return invoiceViewModels;
}

public IList<long> validateInput(string subscriptionIds)
{
    var list = subscriptionIds.Split(",");
    ... // Code to convert each element in long and throw if it is not long
    return longlist;
}

2)创建自定义模型联编程序。

此处提到步骤:

https://docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

=> [FromUri]属性可用于从查询字符串参数绑定复杂类型,但我不确定如何使用。

如果您问我,我会选择方法1(不增加复杂性)。