0

I have this viewmodel:

public class VM
{
    [Required]
    public int Int1 { get; set; }
    [Required]
    public int Int2 { get; set; }
}

In the view, these two ints are chosen via dropdowns. I would like the unobtrusive validation to fail if the same value is selected from both dropdowns (e.g. assume Int1 and Int2 can take values ranging 1-10 and the user chooses 9 for both, validation should fail). I am looking to achieve this with data annotations instead of writing Javascript in the frontend.

I can't find a built-in validation attribute, I found [Compare(string otherProperty)] but I am essentially looking for the negation of Compare.

globetrotter
  • 997
  • 1
  • 16
  • 42
  • 1
    Can't you use 3rd party validation like fluent validation and check values..? – Vinit Patel Jun 10 '19 at 12:37
  • Please check this : https://stackoverflow.com/questions/8786251/opposite-of-compare-data-annotation-in-net – Claudio Corchez Jun 10 '19 at 12:40
  • @VinitPatel yes I can I guess, does it also support front-end (unobtrusive) validation? – globetrotter Jun 10 '19 at 13:22
  • 1
    Aside from a third-party library with this particular functionality built-in, your only good option is to create a custom validation attribute along with the corresponding client-side validation, if you want that. The docs have a guide for that: https://learn.microsoft.com/en-us/aspnet/core/mvc/models/validation?view=aspnetcore-2.2#custom-attributes. There's a section further down the same page for custom client-side validation. – Chris Pratt Jun 10 '19 at 13:28
  • Without javascript, I can suggest you do it in controller `if(int1==int2){return View();}` – Mhsn Jun 10 '19 at 13:54
  • I agree with @VinitPatel . You can achieve this fairly easily with Fluent Validation. It also has front end validation (you may have to enable jquery validate on the front end but works good). Claudio's answer is a way also but you will have much more control without having to make extensions using fluent validation. Reach out if you need help writing the class. You will use conditions to accomplish [this](https://fluentvalidation.net/start#conditions). – akasoggybunz Jun 10 '19 at 14:57
  • 1
    You could try [Remote] attribute. Put it on Int1 and use the 'AdditionalFields' parameter to send it the value of Int2. Then you right a method in your controller that compares the two. return false if they match. – BattlFrog Jun 10 '19 at 20:19

1 Answers1

1

You need to implement your own logic.

  1. Remote validation Controller

    public class NotEqualController : Controller
    {
            [AcceptVerbs("Get", "Post")]
            public IActionResult Verify()
            {
            string firstKey = Request.Query.Keys.ElementAt(0);
            string secondKey = Request.Query.Keys.ElementAt(1);
            string first = Request.Query[firstKey];
            string second = Request.Query[secondKey];
            if (string.Equals(first, second))
            {
                    return Json(false);
                    //return Json(data: $"Values for these two fields should not be same.");
            }
            return Json(data: true);
            }
    }
    
  2. Model Configuration

    public class Product
    {
            public int Id { get; set; }
            [Remote(action: "Verify", controller: "NotEqual", AdditionalFields = nameof(UserImage), ErrorMessage = "Are Same")]
            public string Name { get; set; }
            [Remote(action: "Verify", controller: "NotEqual", AdditionalFields = nameof(Name), ErrorMessage = "Are Same")]
            public string UserImage { get; set; }
    }
    

    Since you may use this logic for many different model and fields, I implement the logic to use the fields from querystring instead of Verify method parameter.

Edward
  • 28,296
  • 11
  • 76
  • 121