Пользовательский атрибут валидатора работает в модульном тесте, но не в веб-контроллере API?
Атрибут валидации ValidateMinMaxListCountAttribute работает в моем модульном тесте, но не при использовании в рамках веб-API?
Например, в модульном тесте "isValid" возвращает true, но в контроллере происходит сбой. Я предполагаю какую-то проблему с сериализацией?
У кого-нибудь есть идеи?
[TestCategory("ServiceTests")]
[TestMethod]
public void CallServiceCalc()
{
var client = new RestClient();
client.BaseUrl = new Uri("https://localhost:44379");
client.Authenticator = new HttpBasicAuthenticator("eric.schneider", "password");
var request = new RestRequest();
request.Resource = "api/Calculation/Calculate";
CoralRequest coralReq = new CoralRequest();
coralReq.ModelId = 1;
coralReq.ModelName = "2018";
coralReq.BasePlan = new BeneifitsPlanInputs();
coralReq.Plans.Add(new BeneifitsPlanInputs());
request.AddBody(coralReq);
ValidateMinMaxListCountAttribute va = new ValidateMinMaxListCountAttribute(1, 999);
bool isValid = va.IsValid(coralReq.Plans);
IRestResponse response = client.Execute(request);
Assert.IsTrue(response.StatusCode == System.Net.HttpStatusCode.OK, "Should not be ok");
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class ValidateMinMaxListCountAttribute : ValidationAttribute
{
public ValidateMinMaxListCountAttribute(int minimum, int maximum)
{
this.MinimumCount = minimum;
this.MaximumCount = maximum;
}
public int MinimumCount { get; set; }
public int MaximumCount { get; set; }
public override bool IsValid(object value)
{
var list = value as ICollection;
if (list != null)
{
if (list.Count > MaximumCount) { return false; }
if (list.Count < MinimumCount) { return false; }
return true;
}
return false;
}
}
public class CoralRequest
{
public CoralRequest()
{
this.Plans = new List<BeneifitsPlanInputs>();
}
/// <summary>
///
/// </summary>
[ValidateMinMaxListCount(1, 99, ErrorMessage = "Must have between 1 and 99 plans")]
public IList<BeneifitsPlanInputs> Plans { get; set; }
}
1 ответ
Основываясь на одном из ваших других вопросов, которые, кажется, связаны, вы показываете, что действие контроллера выглядит так...
[HttpGet("{mock}")]
public ActionResult<CoralResult> CalculateMock(CoralRequest mock)
Во время теста выполняется запрос GET, у запросов GET нет тела, и вы добавляете его в запрос. Это означает, что, скорее всего, модель не заполняется / привязывается к серверу правильно
Это похоже на классическую проблему XY
Это действие, скорее всего, должно быть запросом POST, если вы хотите получить BODY запроса, и действие должно быть реорганизовано, чтобы явно указать, откуда должны быть получены данные.
[Route("api/[controller]")]
public class CalculationController: Controller {
//POST api/Calculation/Calculate
[HttpPost("[action]")]
public ActionResult<CoralResult> Calculate([FromBody]CoralRequest model) {
if(ModelState.IsValid) {
CoralResult result = new CoralResult();
//...do something with model and populate result.
return result;
}
return BadRequest(ModelState);
}
}
Который должен теперь более близко соответствовать тому, что пыталось в интеграционном тесте
[TestCategory("ServiceTests")]
[TestMethod]
public void CallServiceCalc() {
var client = new RestClient();
client.BaseUrl = new Uri("https://localhost:44379");
client.Authenticator = new HttpBasicAuthenticator("eric.schneider", "password");
var request = new RestRequest(Method.POST); //<-- POST request
request.Resource = "api/Calculation/Calculate";
request.AddHeader("content-type", "application/json");
CoralRequest coralReq = new CoralRequest();
coralReq.ModelId = 1;
coralReq.ModelName = "2018";
coralReq.BasePlan = new BeneifitsPlanInputs();
coralReq.Plans.Add(new BeneifitsPlanInputs());
request.AddJsonBody(coralReq); //<-- adding data as JSON to body of request
IRestResponse response = client.Execute(request);
Assert.IsTrue(response.StatusCode == System.Net.HttpStatusCode.OK, "Should be HttpStatusCode.OK");
}
Связыватель модели теперь должен иметь возможность проверять модель после ее связывания и передачи в действие.
Связывание эталонной модели в ASP.NET Core