.NET Core 3.1/5 Api 查询字符串参数不起作用
.NET Core 3.1/5 Api Querystring parameters do not work
我注意到我的 .Net Core 3.1 和 .Net Core 5 Apis 有一些奇怪的地方。当有 2 种不同的 GET 方法通过 id 检索所有记录和单个记录时,基于路由的参数有效但查询字符串参数无效。
这是一些示例代码
using Core5TestApi.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Core5TestApi.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class DataController : ControllerBase
{
private readonly ILogger<DataController> _logger;
List<Data> allData = new List<Data>{
new Data { Id = 1, Name = "Name 1" },
new Data { Id = 2, Name = "Name 2" }
};
public DataController(ILogger<DataController> logger)
{
_logger = logger;
}
[HttpGet]
public IEnumerable<Data> GetAll ()
{
return allData;
}
[HttpGet("{id}")]
[Route("{id}")]
public Data Get(int id)
{
return allData.First(i => i.Id == id);
}
}
}
以下是网址和结果
调用:http://localhost:51672/api/data
结果:[{"id":1,"name":"姓名 1"},{"id":2,"name":"姓名 2"}]
调用:http://localhost:51672/api/data/1
结果:{"id":1,"name":"名称 1"}
调用:http://localhost:51672/api/data?id=1
结果:[{"id":1,"name":"姓名 1"},{"id":2,"name":"姓名 2"}]
最后的结果忽略querystring参数,执行GetAll。
虽然我相信我以前看过这部作品,但我觉得我错过了一些非常基本的东西
我也试过Get方法中参数前的[FromQuery]属性。这实际上打破了基于路由的参数 path
当您调用 http://localhost:51672/api/data?id=1 路由时忽略 ?id=1 因为没有任何路由。
如果你想要 id=1 的记录,你必须使用 http://localhost:51672/api/data/1。
并从最后一个动作[Route("{id}")]中移除,应该是:
[HttpGet("{id}")]
public Data Get(int id)
{
return allData.First(i => i.Id == id);
}
但是如果你仍然想使用 http://localhost:51672/api/data?id=1
你的行动应该是:
[HttpGet]
public Data Get([FromQuery] int id)
{
return allData.First(i => i.Id == id);
}
或者您可以对两者使用一个操作:
//http://localhost:51672/api/data/getAll
[HttpGet("GetAll")]
public IEnumerable<Data> GetAll()
{
return allData.ToArray();
}
[HttpGet("{id0?}")]
[HttpGet]
public Data Get(int id0, [FromQuery] int id)
{
var itemId = id0 == 0 ? id : id0;
if(itemId==0) ...return error
return allData.FirstOrDefault(i => i.Id == itemId);
}
我注意到我的 .Net Core 3.1 和 .Net Core 5 Apis 有一些奇怪的地方。当有 2 种不同的 GET 方法通过 id 检索所有记录和单个记录时,基于路由的参数有效但查询字符串参数无效。
这是一些示例代码
using Core5TestApi.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Core5TestApi.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class DataController : ControllerBase
{
private readonly ILogger<DataController> _logger;
List<Data> allData = new List<Data>{
new Data { Id = 1, Name = "Name 1" },
new Data { Id = 2, Name = "Name 2" }
};
public DataController(ILogger<DataController> logger)
{
_logger = logger;
}
[HttpGet]
public IEnumerable<Data> GetAll ()
{
return allData;
}
[HttpGet("{id}")]
[Route("{id}")]
public Data Get(int id)
{
return allData.First(i => i.Id == id);
}
}
}
以下是网址和结果
调用:http://localhost:51672/api/data 结果:[{"id":1,"name":"姓名 1"},{"id":2,"name":"姓名 2"}]
调用:http://localhost:51672/api/data/1 结果:{"id":1,"name":"名称 1"}
调用:http://localhost:51672/api/data?id=1 结果:[{"id":1,"name":"姓名 1"},{"id":2,"name":"姓名 2"}]
最后的结果忽略querystring参数,执行GetAll。
虽然我相信我以前看过这部作品,但我觉得我错过了一些非常基本的东西
我也试过Get方法中参数前的[FromQuery]属性。这实际上打破了基于路由的参数 path
当您调用 http://localhost:51672/api/data?id=1 路由时忽略 ?id=1 因为没有任何路由。
如果你想要 id=1 的记录,你必须使用 http://localhost:51672/api/data/1。
并从最后一个动作[Route("{id}")]中移除,应该是:
[HttpGet("{id}")]
public Data Get(int id)
{
return allData.First(i => i.Id == id);
}
但是如果你仍然想使用 http://localhost:51672/api/data?id=1 你的行动应该是:
[HttpGet]
public Data Get([FromQuery] int id)
{
return allData.First(i => i.Id == id);
}
或者您可以对两者使用一个操作:
//http://localhost:51672/api/data/getAll
[HttpGet("GetAll")]
public IEnumerable<Data> GetAll()
{
return allData.ToArray();
}
[HttpGet("{id0?}")]
[HttpGet]
public Data Get(int id0, [FromQuery] int id)
{
var itemId = id0 == 0 ? id : id0;
if(itemId==0) ...return error
return allData.FirstOrDefault(i => i.Id == itemId);
}