【问题标题】:Multiple HttpPost Method in ASP.NET Core Webb APIASP.NET Core Webb API 中的多个 HttpPost 方法
【发布时间】:2019-07-22 14:18:33
【问题描述】:

我无法在 ASP.NET Core 中处理我的路由规则。我有以下用户身份验证操作方法的后端和前端应用程序。由于这两种操作方法在有效负载中都有一个带有不同或附加参数的参数。 Http 客户端实际上无法导航确切的方法,因此抛出一个带有错误“歧义”的异常,这是正确的,因为这两种 HttpPost 方法都有一个具有不同参数的参数。如何确保该方法根据操作触发。代码如下:-

API 控制器:-

  [Route("api/[controller]")]
  public class AccountController: Controller
  {
         [HttpPost, ActionName("Login")]
         public async Task<IActionResult> UserLogin(LoginDto user)
         {
            //Code goes here
         }

        [HttpPost, ActionName("Register")]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> UserRegistration(RegisterDto register)
        {
             //Code goes here
        }
  }

前端 API 服务

   public async Task<IActionResult> GetLoginAsync(LoginDto loginUser)
   {
                var request = "/api/account";
                var content = new StringContent(JsonConvert.SerializeObject(loginUser), Encoding.UTF8, "application/json");
                try
                {
                    var result = await ExecuteWithResiliencePolicies(() => _client.PostAsync(request, content));
                    return new StatusCodeResult((int)result.StatusCode);

                }
                catch (HttpRequestException)
                {
                    return new StatusCodeResult(StatusCodes.Status503ServiceUnavailable);
                }           
     }

     public async Task<IActionResult> PostRegistrationAsync(RegisterDto registerUser)
     {
                var request = "/api/account";
                var content = new StringContent(JsonConvert.SerializeObject(registerUser), Encoding.UTF8, "application/json");
                try
                {
                    var result = await ExecuteWithResiliencePolicies(() => _client.PostAsync(request, content));
                    return new StatusCodeResult((int)result.StatusCode);

                }
                catch (HttpRequestException)
                {
                    return new StatusCodeResult(StatusCodes.Status503ServiceUnavailable);
                }
      }

网络控制器:-

     [HttpPost, ActionName("Login")]
            [ValidateAntiForgeryToken]
            public async Task<IActionResult> UserLogin(LoginDto user)
            {
                SetCorrelation();
                if (!ModelState.IsValid)
                {
                    return RedirectToAction(nameof(Login));
                }
                await _accountService.GetLoginAsync(user);              
                return RedirectToAction("Index", "Home");
            }

            [HttpPost, ActionName("Register")]
            [ValidateAntiForgeryToken]
            public async Task<IActionResult> UserRegistration(RegisterDto register)
            {
                SetCorrelation();
                if (!ModelState.IsValid)
                {
                    return RedirectToAction(nameof(Login));
                }
                await _accountService.PostRegistrationAsync(register);
                return RedirectToAction("Index", "Home");


}

网络路由:

app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "WebRoute",
                    template: "{controller}/{action}/{id?}",
                    defaults: new { controller = "Home", action = "Index" },
                    constraints: new { id = "[0-9]+" });                
            });

API 路由:-

app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "KtsWebAPIRoute",
                    template: "{controller=Posts}/{action=GetAsync}/{id?}");

                routes.MapRoute(
                    name: "KtsAccountRoute",
                    template: "{controller}/{action}/{id?}",
                    defaults: new { controller = "Account", Action = "Login" },
                    constraints: new { id = "[0-9]+" });
            });

【问题讨论】:

  • 在您的前端 API 服务中,您是否尝试过使用请求网址 /api/account/Login/api/account/Register
  • 是的,我已经尝试过了,它会抛出错误 404。
  • 尝试将 Route 属性应用到您的 api 控制器而不是 ActionName 例如[Route("login")]public async Task&lt;IActionResult&gt; UserLogin(LoginDto user)

标签: c# asp.net-core asp.net-core-mvc asp.net-core-webapi


【解决方案1】:

有几种可能的解决方案。对于每个解决方案前端部分都应调用以下网址

"/api/account/login"
"/api/account/register"

解决方案 1

您需要在HttpPost属性中指定模板 ASP.NET Core 路由无法从请求中获取操作名称

[Route("api/[controller]")]
public class AccountController : Controller
{
    [HttpPost("Login")]
    public async Task<IActionResult> UserLogin(LoginDto user) { /*..*/ }
}

或者你可以将模板与ActionName结合起来

[Route("api/[controller]")]
public class AccountController : Controller
{
    [HttpPost("[action]"), ActionName("Login")]
    public async Task<IActionResult> UserLogin(LoginDto user) { /*..*/ }
}

解决方案 2

更新控制器的路由以包含动作名称

[Route("api/[controller]/[action]")]
public class AccountController : Controller
{
    [HttpPost, ActionName("Login")]
    public async Task<IActionResult> UserLogin(LoginDto user) { /*..*/ }
}

解决方案 3

使用Route 属性进行操作

[Route("api/[controller]")]
public class AccountController : Controller
{
    [HttpPost, Route("Login")]
    public async Task<IActionResult> UserLogin(LoginDto user) { /*..*/ }
}

【讨论】:

  • 我已经尝试了您的建议,但不幸的是没有成功。得到 400(错误请求)但 api 没有抛出任何异常但是 httpclient 抛出这个错误。我会尝试更多的研究让我们看看。顺便说一句,谢谢你的帮助..
  • @Urgen 好吧,你现在有 400 错误而不是 404,所以找到了行动。尝试调试操作方法以查看是否被击中。您也可以尝试在操作参数UserLogin([FromBody]LoginDto user)之前添加[FromBody]
  • @Urgen 如果您使用的是HttpClient,则请求字符串必须是有效的Uri 并包含http://server/api/..
【解决方案2】:

使用 apiController 属性和 ControllerBase

[ApiController]
[Route("api/[controller]/[action]")]
public class AccountController : ControllerBase
{
.....
}

网址应该是这样的

var uri = "............/api/Account/Login"

【讨论】:

    猜你喜欢
    • 2019-05-15
    • 2012-07-09
    • 2019-06-30
    • 2021-08-27
    • 2021-12-25
    • 1970-01-01
    • 2012-09-03
    相关资源
    最近更新 更多