I am looking for examples of configuration based validation using Validation Application Block. I've found this
I want to ask if someone has an alternative solution to using EL VAB 5.0 to achieve configuration based validation. I've started with DataAnnotations but soon found out that some properties will need different types of validation depending on who is using the application.
Also if anyone has more examples for configuration with VAB and any advice as to what I might run into, please share.
There are several paths you can walk to achieve this. First of all you can (ab)use rulesets for this. You can create a 'base' ruleset with rules that hold for everybody and you can make a ruleset per role in the system and perhaps even a ruleset per user, but of course that would be cumbersome.
Another option would be to create an IConfigurationSource implementation that is able to return a ValidationSettings instance, based on the logged in user. Now there are several ways that you can build a ValidationSettings object. Here are a few examples:
You can load multiple configuration files from disk using the FileConfigurationSource based on the role. Something like: return (new FileConfigurationSource('validation_' + role + '.config')).GetSection(sectionName);
You can build up the ValidationSettings instances dynamically (and cache them). You can store this definition in the database and load them (this would be a lot of work) or define them in code (perhaps separated by assembly). Here is an example of a code based configuration.
Also to prevent having to duplicate parts of your configuration, you can do the following:
Merge multiple configurations together. You can for instance merge the base line validation with the role specific validation. This saves you from having to manually validate according to the base line and do a second validation for the role specific validation. While this is not supported out of the box, I wrote about how to do this on my blog here.
You can merge rules based on type inheritance. While VAB only supports validator inheritance for attribute based validation out of the box, I've wrote about this on my blog, here.
I hope this helps.
Related
I'm working in a spring-cloud environment. The company has decided to pull all common code into a common module (.jar) to be added as a dependency to all applications. All the applications are consumers of a common message. I have been tasked with coming up with a way to validate this message on each individual application, because the message will have different validation requirements depending on which application receives it. For example, let's say we have a message for automobiles. If the automobile in question is a Ford F-150, it will have validation requirements for towing capacity, while the Honda Civic will have validation requirements for fuel savings. So the message coming in will be placed on an object in the common module, is there a way to create custom class-level validation specific to each individual application? The problem I'm running into now is that I am unable to declare the validatedBy class on the #constraint annotation at runtime. Has anyone ever faced this issue? Does anyone know how to create custom validation for an object in a common jar file? Thanks in advance.
Some additional information. I should also mention, the reason I'm looking at doing it this way is because the team that controls the validation for one vehicle, will not always be the team that controls the validation for another. That is why I'm trying to find a way to keep the validation living in the specific applications and not the common included jar.
I ended up using spring-AOP to implement the validation. Just in case anyone runs into this issue, that is how I got this working.
I am using ASP.NET WebAPI with the built in authentication and identity services that come with the Visual Studio template. I now have it that a user can access the system and be authenticated.
The next logical step is to allow the user to create records. Lets say the user can have a "Project". How can I associate the user with a project at the point the project is created? It seems logical that the project table will just store the user_id provided by User.Identity.GetUserId().
Now, say that a project consists of Tasks. By default the WebAPI will create a Tasks controller, where I post a task. I think I would need to inject some additional information (such as the project id) at the point of creating the task.
But, say someone wants to add a task a project that doesn't belong to them. I need to verify this by loading the project, and checking the user_id field. Now I am adding two repositories to my controller. This seems like a lot of work.
Is it my own laziness that makes this seem hard???
I think this might be a related question, as it seems like you are looking for record-level authorization.
MVC / ASP.Net Best Practice for Record-Level Authorization
There is merit also in using multiple repositories. See here for an example of use.
http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
Here, you would wrap the multiple repositories up within the UnitOfWork class.
I hope this points you in the right direction.
While reading "The Definitive Guide To Grails", I am a little confused as to Command Objects. They seem to be a wrapper around domain classes to assist with validation but that is functionality already available in domain classes via built in constraints and further via custom validators so then what does a command object do really and what motivates us to need it?
The book starts the discussion on command objects by stating that
"Sometimes a particular action doesn’t require the involvement of a
domain class but still requires the validation of user input."
However, then it demonstrates the declaration of and the usage of a command object with regards to an Album domain class. So, it seems whatever a command object does is still closely related to domain classes. I'm sure my confusion is completely a result of my lack of understanding and so I wish to seek any clarification. Thanks.
They seem to be a wrapper around domain classes...
You can use command objects that way, but that isn't their primary use.
Command objects are useful when you want to encapsulate a group of request parameters and do something with them together. That something might or might not have anything to do with domain classes.
For example, you could have a Grails app which doesn't have any domain classes at all and command objects could still be really helpful. Imagine a Grails app that is just a service layer that receives request from web forms or REST requests with a JSON body or whatever and the Grails app is going to receive those requests, validate the inputs, maybe do some math or anything at all and then make a REST call to some other backend process that might store them in a database or generate reports or whatever. In a situation like that, there are a lot of reasons that you might want to use command objects even though no domain classes are involved at all.
Don't get bound up thinking that command objects have to be tied to domain classes. Sometimes they are, but don't limit your thinking of them to that context. Use command objects when you want to relate a group of request parameters together and do something with them.
I tend to use command objects that match what is happening in the UI layer, form submits can be validated with command objects then passed into services that do the work of persisting them. It many times makes sense to have your domain model be different then the UI flow you are working with.
My domain layer may also have looser constraints than some of the command objects if I want to require certain flows provide enough information.
Several of our apps use multiple databases from the example below - each in their own separate DBML file. The problem is, MVC by convention puts them all in namespace AppName.Models causing class name conflicts.
Which of the two options is the better fix and why:
1.) Putting them in separate namespaces. To keep stylecop/resharper happy, they would go in their own subfolder:
/Models
/Live
Live.dbml
LiveDataContext.cs
/Crm
Crm.dbml
CrmDataContext.cs
**but now in code, all uses of them have to be Live.Customer and Crm.Customer to differentiate between objects.
EDIT: The other main downside of this, is that I see no other sample code from experts that use sub folders in the Models folder. On top of that, in order to keep the same naming for Helper file code reuse - even apps that only use one database would need a subfolder in Models, which I certainly never see people doing in MVC
2.) Prepending all object names in one or both DBML designers with a prefix. This is my current approach. The Live database has Customer and Order objects, while the Crm database has CrmCustomer and CrmOrder. They all stay in the same namespace and /Models folder. This, however has two main drawbacks:
Quite a bit of prefix redundancy in accessing child objects: CrmCustomer.CrmOrders.First().CrmOrderType Marsha Marsha Marsha
In other apps which only use one database, we often omit the prefix - and then during code reuse or Helper files we have to do a lot of find/replace. This is particularly evident in Helper files that get added to every app like error/activity logging.
So I'd like to hear from other experts which of the two strategies they use, or something else entirely. It seems like a pretty common occurrence to have at least some name conflicts between databases. Thanks
Example table names:
Live Database:
Customer
Order
Address
Phone
Log
20 other tables
Intranet Database:
Customer
Order
Address
Phone
Log
20 other tables
CRM Tool Database:
Customer
Order
Address
Phone
Log
400 other tables
If I understand your problem correctly, you have two additional possible solutions:
You can modify the namespace of the entities generated by the DBML. Assuming you use T4 templates to generate them, you can right-click on the *.tt file, and go to properties. There is a namespace property that you can set to your own custom, and therefore unique, namespace:
MyCompany.MyProject.DataModels.Live
MyCompany.MyProject.DataModels.Intranet
MyCompany.MyProject.DataModels.CRM
A second, similar option would be to have each dbml and the generated classes be contained in their own project, and their own namespace associated with it. So in this case you would have three new projects:
Data.Live
Data.Intranet
Data.CRM
You would then add a reference to the projects when you want to consume them.
The benefit to this, in my opinion, is that it is very likely that tomorrow you could have a project that needs to reference Live, CRM, and a brand new database. In this case you would simply take a dependency on the projects you've already created (binary, or code -- my preference is binary, but YMMV), and that part of this 2nd project is complete.
In my opinion, do not decorate you classes (your option 2). That will be very difficult to maintain.
There is nothing inherently wrong with your option 1, and I have done that as well, but for most of my current solutions I create projects for the reusability factor.
So, I question the design that leads you to needing two identical databases in code. That aside, I think option 1 is better. Here is my reasoning:
The code is more reusable. If you ever need to seperate either model into another project, or remove one, you don't have to remove the prefixes anywhere. This offers clean separation.
Option 2 requires you to specify as well, you aren't avoiding this. However, if any class needs to access only one namespace, you only need to specify at the using level, and not in every single reference to the code. In classes that need both, you aren't avoiding the prefixses in either case. So option #1 wins out in the only case that matters.
I generally avoid type-prefixes as a rule. They are ugly.
Grumble, grumble, database design
I am using DataAnnotations and MetadataType in ASP.Net MVC to validate the creation of one of my custom objects through a form on our www site. It's working really well.
But now we also need to be able to create the same object through a form in our internal admin site.
However, the validation rules are slightly different in that some fields are mandatory on the www site that are not mandatory when we complete the form ourselves through our internal admin system..
Further, I'd like to be able to give the same field different DisplayNames and different validation messages depending on which site/form the data is being collected from etc.
How can I essentially have two different MetadataType's and specify which one I wish to use when validating within the admin site, versus the www site.. I.e. two different sets of validation rules and the ability to specify which one I am validating against..
I have employed my MetadataType's using Buddy (partial) classes, as my objects are auto-generated by LINQ to SQL.
This might be of some help:
http://andrewtwest.com/2011/01/10/conditional-validation-with-data-annotations-in-asp-net-mvc/
I have been in the same situation before. I searched around at the time but found that there was no solution that would give you two sets of validation rules on the same class.
The way I tackled it was to use the view models. You have your "core" model classes and you want different UI's (in this case web and admin UI's) to have different validation rules. You wouldn't need buddy classes for your model classes in this case as you don't want to apply validation rules on the model class itself, instead you will need to inherit from your model class to create two view model classes, one for web and the other for admin interface, and apply the validation rules using DataAnnotations differently on those classes as per your needs. You can also "enhance" your view model classes with any extra, UI specific, attributes.
I know this solution is not perfect as you will have your validation rules on two different places and it's usually not advisable but it works and it's not that bad practically especially if the application isn't very large. The only other solution is to check manually the place user is using is coming from (web or admin) and then adding model state errors according to that. But I wouldn't recommend doing it that way.
I would love to hear if somebody has a better solution for this.