Quantcast
Channel: Fluent Validation for .NET
Viewing all articles
Browse latest Browse all 1917

New Post: Help with customizing extensions for .WithMessage()

$
0
0
I'm working on something where I have multiple levels of items, and I'd like to display the current item's parent's information in the error message without having to add tons of parameters to WithMessage.

I've tried writing this extension myself, but have been unsuccessful so far.

Please keep in mind that this just a simple example which may be a bit of a stretch, but hopefully illustrates the basics of what I'm hoping to accomplish.


Instead of:
RuleFor(person => person.Email)
  .NotNull()
  .WithMessage("Person Id:{0} Name:{1} must have an email", person => person.Id, person => person.Name);
How difficult would it be to do something like:
RuleFor(person => person.Email)
  .NotNull()
  .WithMessage(person => "Person Id:" + person.Id + " Name:" + person.Name + "must have an email");
Example:
public class Parent
{
    public string Id { get; set; }
    public string Name { get; set; }
}

public class Child
{
    public string Id { get; set; }
    public string Name { get; set; }
    public Parent Parent { get; set; }
}

public ParentValidator : AbstractValidator<Parent>
{
    public ParentValidator()
    {
        RuleFor(parent => parent.Id)
            .GreaterThan(0);
            .WithMessage(GetMessage("The Parent does not have an Id"));

        RuleFor(parent => parent.Name)
            .NotNull;
            .WithMessage(parent => GetMessage(parent, "does not have a Name"));
    }

    private string GetMessage(Parent parent, string message, params object[] parameters)
    {
        return GetMessage("Parent Id:" + parent.Id, + " - ", string.Format(message, parameters)); 
    }
}

public ChildValidator : AbstractValidator<Child>
{
    public ChildValidator()
    {
        RuleFor(child => child.Id)
            .GreaterThan(0);
            .WithMessage(child => GetMessage(child.Parent, "has a child that does not have an Id"));
            
        RuleFor(child => child.Name)
            .NotEmpty();
            .WithMessage(child => GetMessage(child.Parent, child, "does not have a Name"));
    }
    
    private string GetMessage(Parent parent, string message, params object[] parameters)
    {
        return GetMessage("Parent Id:" + parent.Id, + " - ", string.Format(message, parameters)); 
    }
    
    private string GetMessage(Parent parent, Child child, string message, params object[] parameters)
    {
        return GetMessage("Parent Id:" + parent.Id, + " (", parent.Name + ") - Child Id:" + child.Id - ", string.Format(message, parameters)); 
    }
}
So given the following example:
var parent = new Parent { Id = 123, Name = "Dave"; }
var child = new Child { Id = 456, Name = null; Parent = parent; }

var childValidator = new ChildValidator<Child>();
childValidator.Validate(child);
The error message would be: "Parent Id:123 (Dave) - Child Id:456 - does not have a Name"
.WithMessage(child => GetMessage(child.Parent, child, "does not have a Name"));
vs
.WithMessage("Parent Id:{0} ({1}) - Child Id:{2} - does not have a Name", child => child.Parent.Id, child => child.Parent.Name, child => child.Id);
Currently, I have four layers of objects, and an extension like this would give me the detailed messages I want.

Any thoughts on how rough this would be to implement?

Viewing all articles
Browse latest Browse all 1917

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>