.Net Core TestClient无法使用参数发布

时间:2019-04-25 14:43:25

标签: integration

我正在使用MSTest测试服务器创建Web API集成测试。我可以索取数据。但是,当我发布数据时,请求不带参数路由到测试服务器。以下是我的代码,我哪里写错了?

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    protected async Task TestDataInitializeAsync()
    {
        _factory = new WebApplicationFactory<MyWebApi.Startup>();
        _client = _factory.CreateClient();

        _client.DefaultRequestHeaders.Clear();
        _client.DefaultRequestHeaders.Accept.Clear();
        _client.DefaultRequestHeaders.Accept.Add(
         new MediaTypeWithQualityHeaderValue("application/json"));
        _client.DefaultRequestHeaders.Add("User-Agent", ".NET Foundation Repository Reporter");
        var content = new FormUrlEncodedContent(new[]
        {
            new KeyValuePair<string, string>("username", "userABC"),
            new KeyValuePair<string, string>("password","password123")
        });

        var response = await _client.PostAsync("/account/login", content);
     }

这是我的Controller方法:

/// <summary>
/// Account controller ASP.NET identity authentication
/// </summary>
[Produces("application/json")]
[Route("[controller]")]
[ApiController]
[Authorize]
public class AccountController : ControllerBase
{
    [HttpPost]
    [AllowAnonymous]
    [Route("login")]
    public async Task<object> Login(string userName, string password)
    {
        try
        {
            var result = await _signInManager.PasswordSignInAsync(userName, password, false, false);
            if (result.Succeeded)
            {
                var appUser = _userManager.Users.SingleOrDefault(r => r.UserName == userName);
                return GenerateJwtToken(userName, appUser);
            }
            else
            {
                return BadRequest(new { message = "No user found! Please check user name and password." });
            }
        }
        catch (Exception ex)
        {
            return StatusCode(Microsoft.AspNetCore.Http.StatusCodes.Status500InternalServerError, ex.Message);
        }
    } 
 }

}

参数,用户名密码始终为空。

2 个答案:

答案 0 :(得分:0)

您应该编辑控制器的操作,以使用FromBody从请求的正文中获取发布参数:

[HttpPost]
[AllowAnonymous]
[Route("login")]
public async Task<object> Login([FromBody]LoginVm model)
{
   ...
}

使用LoginVm类,其中包含用户名和密码作为字符串属性。

希望有帮助。

答案 1 :(得分:0)

仔细阅读ASP.NET Core 2.2 Microsoft Document后,我知道原因。关键是 [ApiController] 属性。它与 TestClient 不相关。

在.NET Core 2.2中,如果将 [ApiController] 属性放在类级别或程序集级别,.NET Core框架将自动进行参数绑定。对于复杂类型,我们无需在对象参数前面定义为 [FromBody] 。但是,对于简单类型(例如int,string,bool),我们需要放入 [FromBody] [FromForm] [FromQuery] [FromHeader] [FromRoute] [FromServices]

对于我来说,我只是将 [FromFrom] 属性放在下面的两个简单类型参数前面,问题就解决了。

    <summary>
    /// To log-in to the system by using userName and password.
    /// If authentication is successed, bearer token will response from server.
    /// </summary>
    /// <param name="userName"></param>
    /// <param name="password"></param>
    /// <returns>Bearer Token</returns>
    /// <remarks>
    /// </remarks>
    [HttpPost]
    [AllowAnonymous]
    [Route("login")]
    public async Task<object> Login([FromForm] string userName, [FromForm] string password)
    {
        try
        {
            var result = await _signInManager.PasswordSignInAsync(userName, password, false, false);
            if (result.Succeeded)
            {
                var appUser = _userManager.Users.SingleOrDefault(r => r.UserName == userName);
                return GenerateJwtToken(userName, appUser);
            }
            else
            {
                return BadRequest(new { message = "No user found! Please check user name and password." });
            }
        }
        catch (Exception ex)
        {
            return StatusCode(Microsoft.AspNetCore.Http.StatusCodes.Status500InternalServerError, ex.Message);
        }
    }