在 .net 核心控制器中使用相同的路由处理 GET 和 POST 请求
Handle both GET and POST request with same route in .net core controller
我正在尝试在同一控制器中使用相同的路由处理 GET 和 POST,因为我有一些其他调用,数据可能使用 GET 或 POST 来调用相同的端点....
这适用于 GET:
[Produces("application/json")]
[ApiController]
public class AccountController : ControllerBase
{
[HttpGet("GetAccount")]
[Route("api/accounts/GetAccount")]
public string GetAccount(string accountID)
{
return "echoing accountID: " + accountID;
}
}
这适用于 POST:
[Produces("application/json")]
[ApiController]
public class AccountController : ControllerBase
{
[HttpPost("GetAccount")]
[Route("api/accounts/GetAccount")]
public string GetAccount([FromForm] string accountID)
{
return "echoing accountID: " + accountID;
}
}
但这不是 return 来自 POST 的值:
[Produces("application/json")]
[ApiController]
public class AccountController : ControllerBase
{
[HttpPost("GetAccount"),HttpGet("GetAccount")]
[Route("api/accounts/GetAccount")]
public string GetAccount(string accountID)
{
// accountID is NULL when doing a POST, but is correct for a GET...
return "echoing accountID: " + accountID;
}
}
在上面的示例中,GET 请求工作正常,但是在执行 POST 时,参数 accountID 为 NULL,因为我已经删除了 [FromForm]
以使其与获取。
有什么方法可以将其组合成一条路线吗?
这是 .net core 5.0 站点....
我如何从 javascript 发布到端点的示例:
$.ajax({
url: '/api/accounts/GetAccount',
data: {
accountID: 'abcdefg'
},
type: 'POST',
dataType: 'JSON',
contentType: "application/x-www-form-urlencoded; charset=UTF-8"
})
.done(function (result) {
// verified that the result is NULL
console.log(result);
})
.fail(function () {
alert("ERROR");;
})
.always(function () {
alert("DONE");
});
这是我完整的启动文件(以防我没有正确注册的东西):
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddSession();
services.AddHttpContextAccessor();
services.AddRazorPages();
services.AddControllers();
services.AddControllers().AddNewtonsoftJson();
services.AddControllersWithViews();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseSession();
app.UseExceptionHandler("/Error");
app.UseHsts();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
});
}
}
谢谢!
您可以尝试如下更改代码:
[HttpPost("GetAccount"), HttpGet("GetAccount")]
[Route("api/accounts/GetAccount")]
public string GetAccount()
{
if ("GET" == HttpContext.Request.Method)
{
//if your `accountID` is fromquery in your get method.
string accountID = HttpContext.Request.Query["accountID"];
return "echoing accountID: " + accountID;
}
else if ("POST" == HttpContext.Request.Method)
{
string accountID = HttpContext.Request.Form["accountID"];
return "echoing accountID: " + accountID;
}
else
{
return "error";
}
}
另外,我觉得你的代码可能没有问题。发出 post 方法时,您应该检查您的 accountID 参数。
更新
api控制器的默认属性是[FromBody],所以你必须指定你不想指定的source.If为[FromForm],你可以通过querystring传递数据。
$.ajax({
url: '/api/values/GetAccount?accountID=abcdefg',
type: 'POST',
dataType: 'JSON',
contentType: "application/x-www-form-urlencoded; charset=UTF-8"
})
.done(function (result) {
// verified that the result is NULL
console.log(result.message);
})
.fail(function () {
alert("ERROR");;
})
.always(function () {
alert("DONE");
});
});
动作:
[HttpPost("GetAccount"), HttpGet("GetAccount")]
[Route("api/accounts/GetAccount")]
public IActionResult GetAccount(string accountID)
{
string message = "echoing accountID: " + accountID;
// accountID is NULL when doing a POST, but is correct for a GET...
return new JsonResult(new { message = message });
}
您是否尝试过创建两个单独的函数。一个用于 GET,另一个用于 POST?
您仍然可以将 Route
属性设置为相同,但它将是来自消费者的 HTTP 方法,它将确定将调用哪个方法。
此外,您需要使用 [FromBody]
属性来访问随请求发送的任何负载。
[Produces("application/json")]
[ApiController]
public class AccountController : ControllerBase
{
[HttpGet]
[Route("api/accounts/GetAccount")]
public string GetAccount([FromBody] request)
{
return "echoing accountID: " + request.accountID;
}
[HttpPost]
[Route("api/accounts/GetAccount")]
public string CreateAccount([FromBody] request)
{
return "echoing accountID: " + request.accountID;
}
}
编辑
您可能需要为您的 GET 端点使用 [FromQuery]
,为您的 POST 端点使用 [FromBody]
。
然后对于您的 GET,您的 URL 将使用查询参数而不是数据负载。
例如/api/accounts/GetAccount?accountID=12345
[Produces("application/json")]
[ApiController]
public class AccountController : ControllerBase
{
[HttpGet]
[Route("api/accounts/GetAccount")]
public string GetAccount([FromQuery] request)
{
return "echoing accountID: " + request.accountID;
}
[HttpPost]
[Route("api/accounts/GetAccount")]
public string CreateAccount([FromBody] request)
{
return "echoing accountID: " + request.accountID;
}
}
我正在尝试在同一控制器中使用相同的路由处理 GET 和 POST,因为我有一些其他调用,数据可能使用 GET 或 POST 来调用相同的端点....
这适用于 GET:
[Produces("application/json")]
[ApiController]
public class AccountController : ControllerBase
{
[HttpGet("GetAccount")]
[Route("api/accounts/GetAccount")]
public string GetAccount(string accountID)
{
return "echoing accountID: " + accountID;
}
}
这适用于 POST:
[Produces("application/json")]
[ApiController]
public class AccountController : ControllerBase
{
[HttpPost("GetAccount")]
[Route("api/accounts/GetAccount")]
public string GetAccount([FromForm] string accountID)
{
return "echoing accountID: " + accountID;
}
}
但这不是 return 来自 POST 的值:
[Produces("application/json")]
[ApiController]
public class AccountController : ControllerBase
{
[HttpPost("GetAccount"),HttpGet("GetAccount")]
[Route("api/accounts/GetAccount")]
public string GetAccount(string accountID)
{
// accountID is NULL when doing a POST, but is correct for a GET...
return "echoing accountID: " + accountID;
}
}
在上面的示例中,GET 请求工作正常,但是在执行 POST 时,参数 accountID 为 NULL,因为我已经删除了 [FromForm]
以使其与获取。
有什么方法可以将其组合成一条路线吗?
这是 .net core 5.0 站点....
我如何从 javascript 发布到端点的示例:
$.ajax({
url: '/api/accounts/GetAccount',
data: {
accountID: 'abcdefg'
},
type: 'POST',
dataType: 'JSON',
contentType: "application/x-www-form-urlencoded; charset=UTF-8"
})
.done(function (result) {
// verified that the result is NULL
console.log(result);
})
.fail(function () {
alert("ERROR");;
})
.always(function () {
alert("DONE");
});
这是我完整的启动文件(以防我没有正确注册的东西):
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddSession();
services.AddHttpContextAccessor();
services.AddRazorPages();
services.AddControllers();
services.AddControllers().AddNewtonsoftJson();
services.AddControllersWithViews();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseSession();
app.UseExceptionHandler("/Error");
app.UseHsts();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
});
}
}
谢谢!
您可以尝试如下更改代码:
[HttpPost("GetAccount"), HttpGet("GetAccount")]
[Route("api/accounts/GetAccount")]
public string GetAccount()
{
if ("GET" == HttpContext.Request.Method)
{
//if your `accountID` is fromquery in your get method.
string accountID = HttpContext.Request.Query["accountID"];
return "echoing accountID: " + accountID;
}
else if ("POST" == HttpContext.Request.Method)
{
string accountID = HttpContext.Request.Form["accountID"];
return "echoing accountID: " + accountID;
}
else
{
return "error";
}
}
另外,我觉得你的代码可能没有问题。发出 post 方法时,您应该检查您的 accountID 参数。
更新
api控制器的默认属性是[FromBody],所以你必须指定你不想指定的source.If为[FromForm],你可以通过querystring传递数据。
$.ajax({
url: '/api/values/GetAccount?accountID=abcdefg',
type: 'POST',
dataType: 'JSON',
contentType: "application/x-www-form-urlencoded; charset=UTF-8"
})
.done(function (result) {
// verified that the result is NULL
console.log(result.message);
})
.fail(function () {
alert("ERROR");;
})
.always(function () {
alert("DONE");
});
});
动作:
[HttpPost("GetAccount"), HttpGet("GetAccount")]
[Route("api/accounts/GetAccount")]
public IActionResult GetAccount(string accountID)
{
string message = "echoing accountID: " + accountID;
// accountID is NULL when doing a POST, but is correct for a GET...
return new JsonResult(new { message = message });
}
您是否尝试过创建两个单独的函数。一个用于 GET,另一个用于 POST?
您仍然可以将 Route
属性设置为相同,但它将是来自消费者的 HTTP 方法,它将确定将调用哪个方法。
此外,您需要使用 [FromBody]
属性来访问随请求发送的任何负载。
[Produces("application/json")]
[ApiController]
public class AccountController : ControllerBase
{
[HttpGet]
[Route("api/accounts/GetAccount")]
public string GetAccount([FromBody] request)
{
return "echoing accountID: " + request.accountID;
}
[HttpPost]
[Route("api/accounts/GetAccount")]
public string CreateAccount([FromBody] request)
{
return "echoing accountID: " + request.accountID;
}
}
编辑
您可能需要为您的 GET 端点使用 [FromQuery]
,为您的 POST 端点使用 [FromBody]
。
然后对于您的 GET,您的 URL 将使用查询参数而不是数据负载。
例如/api/accounts/GetAccount?accountID=12345
[Produces("application/json")]
[ApiController]
public class AccountController : ControllerBase
{
[HttpGet]
[Route("api/accounts/GetAccount")]
public string GetAccount([FromQuery] request)
{
return "echoing accountID: " + request.accountID;
}
[HttpPost]
[Route("api/accounts/GetAccount")]
public string CreateAccount([FromBody] request)
{
return "echoing accountID: " + request.accountID;
}
}