MVC provides a lot of validation attributes which can be used as data annotations to perform simple server-side validations.
However, if I want to do some custom validation using my own business logic, I need to create a custom validation attribute, derived from ValidationAttribute, and override the IsValid method.
So far so good.
However, if I want to perform the same validation on client side, I need to implement the IClientValidatable interface in my validation attribute class, and implement the GetClientValidationRules method, which will tell my application that this validation has to be performed on the client-side too.
The contentious issue however, is that I need to write the logic for this client-side validation as separate JavaScript using jQuery. This is exactly the same logic I already wrote in C# (or VB) when overriding the IsValid method.
Why do I have to write the same logic twice, albeit in different languages? Doesn't this violate the DRY principle? I would have expected MVC to generate the JavaScript for the validation logic itself.
Example illustrating what I am talking about: http://www.c-sharpcorner.com/UploadFile/abhikumarvatsa/enabling-client-side-validation-on-custom-data-annotations-w/
EDIT:
Also, what if my validation logic requires data from the application config file or application cache? How do I use that in the jQuery method I write for client-side validation? If I can't, is there any other way to do client-side validation, the logic for which uses application data?
Yes, but it's often worth it.
The benefits of client side validation are speed and less server load. The benefit of server validation is security. Implementing both gains the best of both worlds.
DRY is a good rule of thumb, but as with all rules of thumb there are situations in which the rule should be violated.
EDIT to answer your follow up question
If your jQuery needs values from server side config you need to pass that to the client as part of the JavaScript. For example, you could define a variable in your view which holds the server side value.
Related
I am trying to use fluentvalidation in my WebAPI projects for an asynchronous rules validations (e.g. check username duplication). (respecting the avoidance of manual use inside controllers, I want to validating before accessing the controller)
The documentation provided by the library saying that:
You should not use asynchronous rules when using automatic validation with ASP.NET as ASP.NET’s validation pipeline is not asynchronous. If you use asynchronous rules with ASP.NET’s automatic validation, they will always be run synchronously.
I know it is possible to use manually the validation from the controller. However, I feel it breaks the clean architecture and coding convention in my App. I am trying to keep controllers free from any type of validation and I found it easy when validation does not necessitate database access. However, the need for rules validation Asynchronously will change the situation.
To Sum up:
I need to validate some rules asynchronously for some BM(s)
Documentary advise to use it manually and avoid using auto validation pipeline
I don't want to validateAsync inside the controller
Do you think the utilization of interceptor will make a sense?
I want to know if and how it is possible to use an other client-side validation framework (than jquery validate, eg. Parsley) in asp.net mvc?
I just looked into the mvc sourcecode and it seems to be hard-wired.
This class creates the attributes, which will be added to the control later.
Maybe there is a way to inherit from a class and configure it somehow to be used as default. It seems that asp.net mvc have too many static classes (e.g. HtmlHelper) which makes it nearly impossible to extend some functionality without rewriting a lot of framework-code?
The power of common data annotations is cool to descibe meta information about the data. It's used by Entity Framework and MVC,
but the client-side validation should be limited to jquery validate?
I know, that I can configure client-validation frameworks like parsley to get used with an other prefix like the "data-val-" (of jquery validate) instead of "data-parsley-", but not all features can be used this way and conflicts are possible.
Hope anyone have an answer for me ;-)
You can use any client side validation you want to use. Asp.net provides server code that is translated into client code but that's not the only option. You can use any client side code you want independent of the server code framework. Just include the appropriate client side code on the pages you wish and it'll work.
I have a validation.xml file from Struts, and am going to implement a server-side validation in .NET based on it. The validation.xml file is accompanied with a validationMessages.properties file. Are there any .NET libraries which are capable of performing a validation based on a Struts validation file?
In case this has never been done I'll have to either create such a class, since the validation file is too long and complex to be implemented as mere C# logic. Which begs the question: How would I even begin?
The end-goal is to be able to populate a C# class with properties for all fields, execute a validation method with that class as a parameter and have it return a list of validation error messages (or no errors in case of success).
I'd be surprised if anything like that existed; it's relatively unusual to move from Java -> .NET.
First, see if there are any custom validators. That code would need to be duplicated.
Then pick apart the different forms (or actions, depending on how they did validation). Put each of those into a C# class (but see below) rather than one giant one. I'm not sure what you mean by "A C# class with properties for all fields"; personally I'd go more granular.
Or just use an existing C# validation package and do a translator from Apache Commons Validation to the C# configuration (or code).
It should be a relatively straight-forward process since the validation config is well-known and documented, and all the code is available.
I have model based on existing database and I have written metadata class and custom attribute class, Now I want to convert all custom attribute logic into Jquery or Javascript custom function, Please guide me simple or any available free tool for the same.
rcdmk and Scott Selby have provided excellent resources for how to implement the IClientValidatable interface to integrate with jquery unobtrusive validation. As an alternative, if you don't want to maintain javascript versions of your validation logic, you could use the RemoteAttribute class to instruct the unobtrusive validation to perform an ajax request to validate the data (in fact in some cases this would be the only proper way to validate something - such as username availability).
RemoteAttribute Class
How to: Implement Remote Validation in ASP.NET MVC
To this moment, there's not a tool for converting custom validator in c# to custom client side validator in JavaScript [that I know of].
I advice you to look for custom validators already built on the web, like http://foolproof.codeplex.com/. Some of them may have what you need and if you can't find one that suits your requirements, follow some tutorials on how to build your own and, maybe, start your own open source project. Since you needed it, others may need it too.
Some tutorials on how to build your own custom validators may get you where you want:
http://blogs.msdn.com/b/simonince/archive/2011/02/04/conditional-validation-in-asp-net-mvc-3.aspx
http://www.codeproject.com/Articles/301022/Creating-Custom-Validation-Attribute-in-MVC-3
And this is one of my favorite references:
http://anthonyvscode.com/2011/07/14/mvc-3-requiredif-validator-for-multiple-values/
With all this in hand I'm sure you will succeed in create your own client side validators.
You should definitely look at unobtrusive validation in MVC. It adapts MVC to work with Jquery and Jquery validate plugins using data attributes within HTML markup. Once you add a Custom Validation Attribute you must also inherit and implement IClientValidatable. See the following links for more information.
http://bradwilson.typepad.com/blog/2010/10/mvc3-unobtrusive-validation.html
http://www.codeproject.com/Articles/275056/Custom-Client-Side-Validation-in-ASP-NET-MVC3
I don't know what your requirements are for your validation , but jQuery validate plugin
should handle it. It validates for a lot of common needs automatically (phone number, number, empty text, email) it is also very easy to add custom validation if needed.
I usually write use cases for all the software that I develop. For each use case I generally write a controller which directs the flow (implements a use case).
I have recently started developing web apps using Asp.net MVC. One of the best practices of Asp.net MVC is to keep very less logic in the controllers. I am not able to figure out how will I change my design to reflect this.
I basically want a way to encapsulate my use cases.
I think having a fat model and skinny controller is generally a good practice in any language and not specifically .NET MVC. Checkout this nice article that goes through a sample scenario showing the advantages of a fat mode in Ruby on Rails (but the ideas apply to any language).
For representing the use-cases in your code, I think a much better place for them is in test-cases rather than the controller.
Push as much business logic to your models and helper classes as possible, and use controllers mainly for handling URL calls and instantiating the relevant models, retrieving data from them, and pushing data to the views. Views and controllers should have as few decisions to make as possible.
Create a business component to encapsulate use cases. For instance if you have a leave management system you would have use cases like apply for a leave, approve a leave request, reject a leave request, etc. For this you can create a business component (class) called Leave Manager with methods (functions/operations) like "Apply", "Approve", "Reject", etc. These methods will encapsulate your use cases. These methods would take your business entities and data store classes as input and execute the use case.
class LeaveManager{
int Apply(from, to);
bool Approve(leaveApplicationId, approverId);
bool Reject(leaveApplicationId, approverId);
}
You can then use this business component in your controllers to execute the use case by supplying the required parameters.