如何在外部 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();
参考以下答案
第一次使用 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();
参考以下答案