2

I am developing an MVC 5 app using EF 6 database first approach. I have a certain validation which is required for fields in many of my models. I am using remote validation for validating them. Since it was being used in a lot of models so I am trying to go for a generic method.

For that matter I made an Interface named IEntity which includes all properties being used in my models. Then I did the following for my Validation method:

[HttpPost]
public JsonResult UniqueCheck<T>(T code) where T : class, IEntity
{
    MyEntities db = new MyEntities();
    if (db.Set<T>().Any(x=>x.S1 == code.S1))
    {
        return Json("Already Exists!");
    }
    else
    {
        return Json(true);
    }
}

And following is how I am calling the validation on properties in models:

[Remote("UniqueCheck", "Rules", HttpMethod = "POST")]

public string S1 { get; set; }

But the problem is that the validation is not working and when I checked in the browser console I got that the validation is actually going into the method but there was a 500(Internal Server Error) returned.

I know that the problem is with T written with method name because when I removed the generics and hardcoded my model name, it works fine.

I only want to use MVC's remote validation and I would be very happy to get this generic method working because otherwise it would be a copy/paste on a lot of locations.

Awais Mahmood
  • 1,308
  • 4
  • 21
  • 51
  • 1
    Do you have a stacktrace of the 500 ISE call? Knowing where it happened (e.g. ModelBinder, or routing or the method body itself) would help. – Tomas Grosup Oct 29 '15 at 14:37
  • I didn't get the stack trace.. I have seen the ISE call in the console window of browser.. I didn't even know that there was an error because VS was not showing any error. It wasn't just going into the validation. When I Go to "Inspect Element" in Chrome, I saw the error in console – Awais Mahmood Oct 30 '15 at 05:09
  • Bit unclear what your trying to achieve. The `RemoteAttribute` makes an ajax call and sends the name/value pair of the property to the controller method, in the case of property `S1` it sends `S1:someValue` so you method nedds a parameter `string S1` It does not send any other information (except the name/value pairs specified in `AdditionalFields` if you use it) so `T` is unknown. –  Oct 30 '15 at 06:00
  • I wanted to make a generic validation so that all my model properties S1 can use it. The error in console is "Failed to load resource: the server responded with a status of 500 (Internal Server Error)" – Awais Mahmood Oct 30 '15 at 06:34
  • Because `T` is undefined. The `RemoteAttribute` does not pass a `class` or `interface` to the method - just the name/value pair of the property. –  Oct 30 '15 at 06:36
  • how can i make it working?? or should i go for copy/paste it for each model? – Awais Mahmood Oct 30 '15 at 06:39
  • Make one method for each model. The only way you could make you generic method work would be to use `AdditonalFields` and render a hidden input in every view to store the class name then use reflection to initialize the class in your controller. Far more work than its worth. –  Oct 30 '15 at 06:43
  • 1
    Proposal: You can make a generic controller with the validations you want (generic type T on class level, not method level). Then you would create concrete versions just by inheritance (those would be basicaly empty classes). In the end, there would be one RulesController and several empty children, e.g. UserRulesController, AdminRulesController and so on. – Tomas Grosup Oct 30 '15 at 08:37

0 Answers0