Free verification: setting a custom message during user verification

Scenario

I have a custom rule to confirm the cost of order delivery:

public class OrderValidator : BaseValidator<Order> { private string CustomInfo { get; set; } public OrderValidator() { //here I call the custom validation method and I try to add the CustomInfo string in the message RuleFor(order => order.ShippingCost).Cascade(CascadeMode.StopOnFirstFailure).NotNull().Must( (order, shippingCost) => CheckOrderShippingCost(order, shippingCost) ).WithMessage("{PropertyName} not set or not correct: {PropertyValue}." + (String.IsNullOrEmpty(CustomInfo) ? "" : " " + CustomInfo)); } //this is the custom validation method private bool CheckOrderShippingCost(Order o, decimal shippingCost) { bool res = false; try { /* * check the actual shippingCost and set the res value */ } catch (Exception ex) { CustomInfo = ex.ToString(); res = false; } return res; } } 

In case of an exception, I save the exception information in a private CustomInfo element and add it to the verification message.

Then I run the validator:

 OrderValidator oVal = new OrderValidator(); oVal.Results = oVal.Validate(order); if (!oVal.Results.IsValid) oVal.Results.Errors.ForEach(delegate(ValidationFailure error) { Console.WriteLine(error.ErrorMessage); }); 

Question

Everything works correctly, in case of an exception, CustomInfo is correctly set to ex.ToString (). But in the end, the error message displayed in the console does not display CustomInfo, but only the first part of the message:

  "Shipping Cost not set or not correct: 5.9" 

Question

Why doesn't the custom message contain a CustomInfo string? Can I add exception information to a custom message differently?

+6
source share
1 answer

According to this https://fluentvalidation.codeplex.com/wikipage?title=Customising&referringTitle=Documentation&ANCHOR#CustomError

better to use

 .WithMessage("{PropertyName} not set or not correct: {PropertyValue}. {0}", order => order.CustomInfo); 

which would require your CustomInfo at the level of the Order class, and not your validator class

EDIT

You can use:

 public static class OrderExtensions { private static IDictionary<Order,string> customErrorMessages; public static void SetError(this Order order, string message) { if (customErrorMessages == null) { customErrorMessages = new Dictionary<Order,string>(); } if (customErrorMessages.ContainsKey(order)) { customErrorMessages[order] = message; return; } customErrorMessages.Add(order, message); } public static string GetError(this Order order) { if (customErrorMessages == null || !customErrorMessages.ContainsKey(order)) { return string.Empty; } return customErrorMessages[order]; } } 

with minor changes to your validator

 public class OrderValidator : BaseValidator<Order> { public OrderValidator() { //here I call the custom validation method and I try to add the CustomInfo string in the message RuleFor(order => order.ShippingCost).Cascade(CascadeMode.StopOnFirstFailure).NotNull().Must( (order, shippingCost) => CheckOrderShippingCost(order, shippingCost) ).WithMessage("{PropertyName} not set or not correct: {PropertyValue}. {0}", order => order.GetError())); } //this is the custom validation method private bool CheckOrderShippingCost(Order o, decimal shippingCost) { bool res = false; try { /* * check the actual shippingCost and set the res value */ } catch (Exception ex) { order.SetError(ex.ToString()); res = false; } return res; } } 
+7
source

Source: https://habr.com/ru/post/973360/


All Articles