.net core 在.net核心控制器中使用相同的路由处理GET和POST请求

.net core 在.net核心控制器中使用相同的路由处理GET和POST请求,.net-core,razor,asp.net-core-mvc,asp.net-mvc-controller,.net Core,Razor,Asp.net Core Mvc,Asp.net Mvc Controller,我试图在同一控制器中使用相同的路由处理GET和POST,因为我有某些rest调用,数据可能使用GET或POST调用相同的端点 这可以很好地使用GET: [Produces("application/json")] [ApiController] public class AccountController : ControllerBase { [HttpGet("GetAccount")] [Route("api/accounts

我试图在同一控制器中使用相同的路由处理GET和POST,因为我有某些rest调用,数据可能使用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;
    }
}
这对邮局来说很有用:

[Produces("application/json")]
[ApiController]
public class AccountController : ControllerBase
{
    [HttpPost("GetAccount")]
    [Route("api/accounts/GetAccount")]
    public string GetAccount([FromForm] string accountID)
    {
        return "echoing accountID: " + accountID;
    }
}
但这不会从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]
,以使其与GET一起工作

有什么方法可以把它合并成一条路线吗

这是针对.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");
   });
这是我的完整启动文件(以防我没有正确注册某些内容):


谢谢

您可以尝试更改代码,如下所示:

    [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],因此必须指定源。如果不想指定为[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将使用查询参数而不是数据负载。 e、 g.
/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;
    }
}

为什么post请求中的
accountID
null?对我来说,即使我删除了
[FromForm]
,我也可以成功地获得accountID。真的吗???我不知道为什么我的显示为空,但它肯定是…我已经更新了我的问题,以显示我是如何张贴到它。。。并在一篇帖子中确认我在控制器中的accountID为空…嗨@MikeLuken,你可以查看我的更新答案。谢谢你的回复。你是对的,你提到的方法绝对有效。然而,我们有300多个rest端点,所以我希望避免这样做。还有人说accountID对他们来说不是空的。为什么我的accountID显示为空?我已经更新了我的问题以显示我是如何发布到它的。。。并在一篇帖子中确认我在控制器中的accountID为NULL…感谢您的额外建议。我只是尝试修改代码以匹配您的代码,accountID仍然为空。我甚至在控制器中放了一个断点,并验证了它也是空的……你还有其他用于此ajax的代码吗?不确定“其他用于此ajax的代码”是什么意思?似乎我所有的POST控制器都需要[FromForm]才能通过方法签名。它可能是一个.NETCore5.0的东西吗?不确定我需要更改什么其他配置来绕过此行为?我尝试过,但不起作用。它给了我一个错误,说检测到了两个可能的路由…我编辑了这篇文章,使用[FromQuery]作为GET,使用[FromBody]作为post可以工作
[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;
    }
}