0

I have been searching google whole day and I cannot find the answer: the problem is to validate a class with the attributes when I create a class. So it goes: I read a POST request body and each field should be validated. It's deserialized from Json to Request class. Then this class has its requirements. Is it possible to do this in asp.net core using attributes? As far as I know there are 2 ways to check class: using ValidationAttribute and Attribute inheritance. I could swear that some time ago I was able to debug it and go to Validation class, but now it seems that is only regarding some client validation and it does not validate in backend middleware. The last thing I am trying is using Validator.TryValidateObject. Is it better option?

2
  • 1
    did you try "ModelState.IsValid" in your controller? Could you also attach controller and model code? Commented Jul 14, 2020 at 22:43
  • The idea is to use it outside of a controller, in proxy middleware, where only model and validation is stored. I don't want to edit controller if possible, as it is next layer which shouldn't be accessible if validation fails. Commented Jul 15, 2020 at 4:29

1 Answer 1

1

I could swear that some time ago I was able to debug it and go to Validation class, but now it seems that is only regarding some client validation and it does not validate in backend middleware.

Be sure that your razor view does not add jquery.validate.min.js and jquery.validate.unobtrusive.min.js.

For using asp.net core default template,you could just avoid using the following code in your razor view:

@*@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}*@

Then add the following code to your backend:

if (!ModelState.IsValid)  
{
    return View(model);
}

Update:

If you want to validate before controller,I suggest that you could custom ActionFilter.Here is a working demo with asp.net core 3.1 web api:

Model:

public class Test
{
    [Range(1,4)]
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
}

Custom ActionFilter:

public class ValidationFilter : IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext context)
    {
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {
            context.Result = new JsonResult(context.ModelState.Select(m=>m.Value).ToList())
            {
                StatusCode = 400
            };
        }
    }
}

Controller:

[Route("api/[controller]")]
public class ValuesController : ControllerBase
{
    // POST api/<controller>
    [HttpPost]
    public void Post(Test test)
    {

    }
}

Register in Startup.cs:

services.AddControllers(config =>
{
    config.Filters.Add(new ValidationFilter());
});

Result: enter image description here

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, but I do not have any views - it's an API :) Like I wrote above - this is the proxy validation layer which passes the request or not.
Yes! Thank you, that works perfectly :) This is the smartest and the cleanest way for that job.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.