Jose Francis
Jose Francis

Reputation: 960

Is there a way to validate a model which is created inside web api controller?

I have a controller where my PUT method uses multipart/form-data as content type and so I am getting the JSON and the mapped class thereby inside the controller.

Is there a way I could validate this model with respect to the annotations I have written in the model class while inside the controller?

public class AbcController : ApiController
{
    public HttpResponseMessage Put()
    {
        var fileForm = HttpContext.Current.Request.Form;
        var fileKey = HttpContext.Current.Request.Form.Keys[0];
        MyModel model = new MyModel();
        string[] jsonformat = fileForm.GetValues(fileKey);
        model = JsonConvert.DeserializeObject<MyModel>(jsonformat[0]);
     }
}

I need to validate "model" inside the controller. FYI, I have added required annotations to MyModel().

Upvotes: 5

Views: 1224

Answers (3)

Shameel Perayil
Shameel Perayil

Reputation: 96

You can also use Fluent Validation to do this. https://docs.fluentvalidation.net/en/latest/aspnet.html

Your Model Class:

public class Customer 
{
  public int Id { get; set; }
  public string Surname { get; set; }
  public string Forename { get; set; }
  public decimal Discount { get; set; }
  public string Address { get; set; }
}

You would define a set of validation rules for this class by inheriting from AbstractValidator<Customer>:

using FluentValidation;

public class CustomerValidator : AbstractValidator<Customer> 
{
  RuleFor(customer => customer.Surname).NotNull();
  . . . etc;
}

To run the validator, instantiate the validator object and call the Validate method, passing in the object to validate.

Customer customer = new Customer();
CustomerValidator validator = new CustomerValidator();

ValidationResult result = validator.Validate(customer);

The Validate method returns a ValidationResult object. This contains two properties:

IsValid - a boolean that says whether the validation succeeded. Errors - a collection of ValidationFailure objects containing details about any validation failures.

The following code would write any validation failures to the console from your controller or even from your service or repository:

using FluentValidation.Results; 

Customer customer = new Customer();
CustomerValidator validator = new CustomerValidator();

ValidationResult results = validator.Validate(customer);

if(! results.IsValid) 
{
  foreach(var failure in results.Errors)
  {
    Console.WriteLine("Property " + failure.PropertyName + " failed validation. Error was: " + failure.ErrorMessage);
  }
}

You can also inject the validator inside Program.cs , read here : https://docs.fluentvalidation.net/en/latest/di.html

Upvotes: 1

Andriy Tolstoy
Andriy Tolstoy

Reputation: 6090

Manual model validation:

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

class ModelValidator
{
    public static IEnumerable<ValidationResult> Validate<T>(T model) where T : class, new()
    {
        model = model ?? new T();

        var validationContext = new ValidationContext(model);

        var validationResults = new List<ValidationResult>();

        Validator.TryValidateObject(model, validationContext, validationResults, true);

        return validationResults;
    }
}

Upvotes: 4

Parveen Sachdeva
Parveen Sachdeva

Reputation: 1019

Suppose you have defined models in Product class like :

namespace MyApi.Models
{
    public class Product
    {
        public int Id { get; set; }
        [Required]
        public string Name { get; set; }
        public decimal Price { get; set; }
    }
}

and then inside controller just write:

 public class ProductsController : ApiController
    {
        public HttpResponseMessage Post(Product product)
        {
            if (ModelState.IsValid)
            {
                 return new HttpResponseMessage(HttpStatusCode.OK);
            }
         }
    }

Upvotes: 3

Related Questions