如何在外部 DLL 中测试和调用我的 api

How to test and call my api in external DLL

第一次使用 ASP.NET Core 2.0。

我有一个 Web 项目,它引用了我创建的 DLL。

在这个DLL中是一个简单的方法...

namespace InformedWorkerApi
{
    [Route("api/[controller]")]
    public class RegistrationController: Controller
    {
        private readonly IAccountRepository _accountRepository;
        public RegistrationController(IAccountRepository accountRepository)
        {
            _accountRepository = accountRepository;
        }

        [HttpPost()]
        [Route("SignOn")]
        public async Task<InformedWorkerModels.Account> SignOn([FromBody]SignOnRequest model)
        {
            return await _accountRepository.SignOn(model.EmailAddress, model.Password);
        }
    }
}

我还创建了一个引用我的 DLL 的测试项目...

    [TestMethod]
    public async Task SignOn()
    {

        var webHostBuilder = new WebHostBuilder()
            .UseStartup<Startup>();

        using (var host = new TestServer(webHostBuilder))
        {
            using (var client = host.CreateClient())
            {
                var requestData = new SignOnRequest { EmailAddress = "emailAddress", Password= "password" };
                var content = new StringContent(JsonConvert.SerializeObject(requestData), Encoding.UTF8, "application/json");
                var response = await client.PostAsync("api/Registration/SignOn", content);
                //do some asserts here
            }
        }
    }

我收到错误状态代码 404 未找到。

请问我哪里错了?

您将电子邮件和密码作为路由的一部分,但将它们作为正文中的内容发送。不匹配操作的路由模板,因此 404 Not Found。

创建一个模型来保存数据

public class SignOnRequest {
    [Required]
    public string emailAddress { get; set; }
    [Required]
    public string password { get; set; }
}

对于核心,您还必须指定框架应在何处查找参数的参数属性。

[Route("api/[controller]")]
public class RegistrationController : Controller{

    [HttpPost()]
    [Route("SignOn")] // Matches POST api/Registration/SignOn
    public async Task<IActionResult> SignOn([FromBody]SignOnRequest model) {
        if(ModelState.IsValid) {                
            var response = await _accountRepository.SignOn(model.emailAddress, model.password);
            return Ok(response);
        }
        return BadRequest();
    }
}

现在应该与集成测试中提出的请求相匹配

var requestData = new { emailAddress = "emailAddress", password = "password" };
var content = new StringContent(JsonConvert.SerializeObject(requestData), Encoding.UTF8, "application/json");
var response = await client.PostAsync("api/Registration/SignOn", content);

正如您还提到的,控制器在另一个程序集中,您需要确保控制器已在 Startup 中向 ServiceCollection 注册,以便框架知道如何解析控制器。更新 ConfigureServices 以包含

services.AddMvc()
  .AddApplicationPart(typeof(RegistrationController).GetTypeInfo().Assembly)
  .AddControllersAsServices();

参考以下答案