0

I am trying to use fluent validation for my models on Web API project. I have two classes name OrderHeader and Items . And i have property name as OrderQty on Items class which is an integer and i have applied a rule for OrderQty as it should be number only (i.e. 0-9) . whenever i get the JSON request for OrderQty as alphanumeric (like 1A) i cannot serialize the JSON and could not get the errormessage from fluent validation on Modelstate . How to achieve this could someone help me on this please ? Thanks in advance !!!

I have tried to convert the OrderQty to ToString() and applied rule but i could not get the errormessage while serialiaing the JSON .

My modal classes :

public class OrderHeader
{
    public string OrderNumber { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
    public string Phone { get; set; }
    public string Created { get; set; }
    public List<Items> Items { get; set; }
}

public class Items
{
   public string ItemNumber { get; set; }
   public string Description { get; set; }
   public int OrderQty { get; set; }
   public double Weight { get; set; }
   public double Price { get; set; }
   public string Status { get; set; }
}

Fluent Validations

public class OrderHeaderValidator : AbstractValidator<OrderHeader>
{

    public OrderHeaderValidator()
    {
        RuleFor(x => x.OrderNumber.Trim()).NotEmpty().WithMessage("OrderNumber : cannot be blank.").Length(1, 6).WithMessage("OrderNumber : cannot be more than 6 characters.").Matches("^[0-9]*$").WithMessage("OrderNumber : must contains only numbers");
        RuleFor(x => x.Items).SetCollectionValidator(new ItemValidator());
    }
}


public class ItemsValidator : AbstractValidator<Items>
{

    public ItemsValidator()
    {
        RuleFor(x => x.OrderQty.ToString()).NotNull().WithMessage("TotalOrderQuantity : cannot be blank").Matches("^[0-9]*$").WithMessage("TotalOrderQuantity : must contains only numbers");
        RuleFor(x => x.Status.ToUpper()).NotEmpty().WithMessage("Status : Provide the Status").Length(0, 1).WithMessage("Status : cannot be more than 1 character").Matches("O").WithMessage("Status : Must be 'O'");

    }

}

Serializing and getting error message :

 string errors = JsonConvert.SerializeObject(ModelState.Values
                .SelectMany(state => state.Errors)
                .Select(error => error.ErrorMessage));

I expect the output should be if the value for is 1A from JSON request then it displays the error message as:

TotalOrderQuantity : must contains only numbers

0

1 Answer 1

1

You can't deserialize 1A into int OrderQty. Use string OrderQty instead and check .Must(x => int.TryParse(x.OrderQty, out _)) in validator.

It's OK that your API has specification like OrderQty must be integer - int OrderQty. If someone tries to send string instead of integer - you can catch deserializion exception and reject the request with message like invalid request: ...

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

10 Comments

I used like RuleFor(x=>x.OrderQty).Must(validateint).WithMessage("Must be integer"); And my validateint function is like public bool validateint(string value) { int number; bool a = int.TryParse(value, out number); return a; } Its works great !!! but how can i show the errormessage as which item having an invalid OrderQty in a list of items in the model
Like how can i append the ItemNumber in Error Message . I tried below, RuleFor(m => new { m.OrderQty, m.ItemNumber }).Must(x => validateint(x.OrderQty, x.ItemNumber)) .WithMessage(string.Format("A {0}",x.ItemNumber)); But i could not make it success
@Vicky Try this .WithMessage(x => $"A{x.ItemNumber}")
I am getting the compile time errors like Unexpected character '$' and some errors
I uesed like this RuleFor(m => new { m.OrderQty, m.ItemNumber }).Must(x => validateint(x.OrderQty, x.ItemNumber)).WithMessage(x => $"A{x.ItemNumber}");
|

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.