Are DataAnnotations attributes cached? If so, how to switch between different cultures? - c#

I have a site that supports both US and Canada. My zip code validation uses a custom RegEx attribute that I created to allow my RegEx pattern to be localized:
public class RegularExpressionAttribute : System.ComponentModel.DataAnnotations.RegularExpressionAttribute
{
public RegularExpressionAttribute(Type patternResourceType, string patternResourceName)
: this(ResourceHelper.GetString(patternResourceType, patternResourceName))
{
this.PatternResourceName = patternResourceName;
this.PatternResourceType = patternResourceType;
}
}
The problem is, if the client switches from one country to the other, it holds onto the RegEx pattern from the first country. So if they load it in US, it keeps the US zip pattern when they switch to Canada, and vice versa.
How can I get this to always use the proper culture?
Thanks in advance.

I found the answer. Create a custom DataAnnotationsModelMetadataProvider. It's really easy. You just need to override a single method. This gets called every time a property attribute is required. There's quite a few samples on the web for this, eg: http://bradwilson.typepad.com/blog/2010/01/why-you-dont-need-modelmetadataattributes.html and http://www.freewebdevelopersite.com/2011/07/10/custom-metadata-providers-in-asp-net-mvc/.
Cheers

Related

.Net Core Binding to a Specific Model given a Specific QueryString Value

I'm in the middle of refactoring an analytics api which needs to allow clients to send events as HTTP GET requests, with their "Hit" data encoded in the URL's QueryString Parameters.
My API's job is to recieve these events, and then place the "valid" events onto a queue in another part of the system for processing.
Some Hits have the same shape. The only thing that makes them different is the value of the type parameter, which all events must have at a minimum.
The problem I've encountered is that based on the Hit type, I'd like to be able to assume the type of each field given to me, which requires model binding. Of course. Currently, I can only find out what model to validate against after checking the value of type - which risks making the API excessively "stringly typed"
An example route would be:
GET https://my.anonymousanalytics.net/capture?type=startAction&amount=300&so_rep=true
Therefore, my Hit would be:
{
type: "startAction",
amount: 300,
so_rep: true
}
Which, hypothetically, could be bound to the Model StackOverflowStartHitModel
class StackOverflowStartHitModel {
public string type { get; } // Q: Could I force the value of this to be "startAction"?
? public int amount { get; }
public boolean so_rep { get; }
}
Why am I asking this here? Well I'm normally a JavaScript developer, but everyone who I'd normally turn to for C# wisdom is off work with the flu.
I have experimented with the [FromQuery] attribute decorator, but my concern is that for Hits that are the exact same shape, I might not be able to tell the difference between whether it is a startAction or an endAction, for example.
you're going to need to have a validation engine of some sort, but do not confuse this with your UI model validation. It sounds like you really have one model with a number of valid states which really is business logic.
Your model looks like this:
public class StackOverflowModel
{
public string type { get; set;}
public int amount { get; set; }
public bool so_rep { get; set;}
}
it doesn't matter what value your type field has and you don't need to hard-code it either, it will be captured as is and then it can be checked against valid states.
There are a number of ways to do this, that I can think of.
One option would be to create a list of valid rules ( states ) and then simply check if your input model matches any of them. One way to implement something like this could be with a library like FluentValidation. You can see an example here: Validation Rules and Business Rules in MVC
Another option would be to use some sort of Pattern Matching techniques like described here: https://learn.microsoft.com/en-us/dotnet/csharp/pattern-matching
Whichever option you go with, make sure you put this validation stuff in a separate class, maybe even a separate project. You can then add tests for each rule that you have to make sure everything works. This will also keep your controller light.
You haven't given examples of valid and invalid states, but I am guessing you're really talking about variations of those 3 parameters such as, when type is "something" then amount can only be < 200 and so_rep can only be "whatever". This can be done quite nicely with the FluentValidation library.

Identify implementations of base class in an array

I have the following problem: I have a set of engines which automaticly (listening to events) controls my model. The following picture shows in general the class diagram:
Now I have a client which knows the EngineFacade and i want to set the property Active from Engine2 from the client, but neither the client nor the EngineFacade knows which of the three engines is Engine2.
There are two ways, but I dont like any of them:
Check if one of the engines is of type Engine2 - if there is another class which does the same task but is named different I have to change it in the EngineBuilder AND in the EngineFacade.
Check with an identifier string - I dont really like magic strings.
What I know on the client site is that there is or should be an engine which handels the grid. But I dont know more.
Maybe I have to choose between the two devils, but maybe one of you has a better solution.
You could use an attribute on the implementation of Engine2, like so:
[AttributeUsage(AttributeTargets.Class)]
public class HandlesGridAttribute : Attribute { }
Which you then apply to your derivation:
[HandlesGrid]
public Engine2 : EngineBase { ... }
Then, in your client, check for the attribute:
IEnumerable<EngineBase> bases = ...;
// Get all the implementations which handle the grid.
IEnumerable<EngineBase> handlesGrid = bases.
Where(b => b.GetType().
GetCustomAttributes(typeof(HandlesGridAttribute), true).Any());
// Set the active property.
foreach (EngineBase b in handlesGrid) b.Active = true;
The major drawback here (which may or may not apply to you) is that you can't change the value at runtime (since the attribute is baked in at compile time). If your engine is not dynamic in this way, then the attribute is the right way to go.
If you need to change whether or not a derivation can perform this action at runtime though, then you have to fall back to your second option, code constructs that identify what the attributes of the engine are. Mind you, it doesn't have to be a string (and I don't like that either), but it can be something that is more structured that will give you the information you're looking for.

Custom editortemplate when property has some attribute on it

This is what the implementation would look like
public class Product
{
public integer id {get;set;}
[MultiLangual]
public string name {get;set;}
}
In the database, name would contain something like:
{en:Pataoto, nl: Aardappel, de: Patat, fr: pommes de terre}
This would contain all the translated fields, that a client has given to his own product.
(in this case: a patato).
In the frontend, this would appear as multiple html elements, which i (somehow) detect which language it is, on submitting the form.
My question is, how would i do this? I'm always stuck on creating the attribute and don't know where to continue...
In my attribute, i shouldn't do a lot, just something like this (i think):
public class MultiLangualAttribute : Attribute
{
public MultiLangualAttribute() : base()
{
}
public override string ToString()
{
return base.ToString();
}
}
But how would i detect everything in my views and create a custom layout for it (this should work with and .
It would only contain text.
Any ideas or a better implementation of above, would be VERY usefull :)
I think the better (arguably) implementation is standard way of application localization.
You define your resources and strings under App_GlobalResources folder you will have to create.
For example you will create file Fruits.resx with all your fruits you want to translate in your system language.
Afterwards you will create Fruits.de.resx, Fruits.es.resx etc, with all the languages you want to have in your website.
It is also possible to update the resources at runtime.
Its too much to describe all the approach in this answer, I would rather provide a link or two with detailed tutorial on MVC application localization:
This is classic ASP.NET MVC localization explanation:
Globalization And Localization With Razor Web Pages
Another explanation of the same thing, little more detailed is here:
ASP.NET MVC Localization: Generate resource files and localized views using custom templates
This should be enough for you to localize your app the standard way.
This is a little more advanced approach, when they use language as part of the URL you accessing.
es.yourdomain.com will be in Spanish, fr.yourdomain.com will be in French:
Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
With regards to your approach (storing different languages in the database) here's link to microsoft approach for this. Its much more involved and complex, and I am not sure if benefitting you by its complexity, since you end up using database to fetch every single string in your app. Not the most efficient, but possible approach as well:
Extending the ASP.NET Resource-Provider Model
Hope this all will be of helps to you & good luck

Validation in ASP.MVC 3.0

I have a model class :
public class YearlyChageRate
{
public int Year { get; set; }
public double Rate { get; set; }
}
and I want to check that Yeae is unique or no and in condition Year is not unique application show an error message to users.How can I check the Year filed is repeated or not?
Here is a good example:
http://tugberkugurlu.com/archive/asp-net-mvc-remote-validation-for-multiple-fields-with-additionalfields-property
And here too: MVC validation for unique
You can use Remote attribute in your model to perform check for unique value in database.
This is official example of Remote attribute: http://msdn.microsoft.com/en-us/library/gg508808(v=vs.98).aspx
And one more: http://www.a2zdotnet.com/View.aspx?Id=198
You could use the [Remote] validation attribute on your view model.
Although you can use DataAnnotations attributes for validation and the [Remote] attribute for checks against the DB, it's not a very good design choice.
Let me explain:
data access is a data-layer matter
validation is a business-layer matter
user input and feedback is a ui matter
With DataAnnotations, you're mixin 3 in 1. It can be faster, but surely not well designed.
You could try a more disciplinate approach, like this:
Have a method at business level that will take your object as a parameter, perform validation internally using a validation framework of your choiche;
This method will call the data access to persist the object only if the validation passed;
This method will always return to the UI the validated object, plus a collection of fields/errors if anything didn't validate;
When you read the output of the method in your ui, you can either display a success page if there were no errors, or redisplay the form with the validation errors returned. To do this, the use of the PRG pattern is highly recommended, as you should never display a page on a POST method. Google for the PRG pattern to learn more about it. MvcContrib has a nice ActionFilter called ModelStateToTempData to make the implementation of the PRG pattern something trivial.

Is there an equivalent of Java's Spring MVC style url mapping for C#/.NET?

I am looking for the C# equivalent of Spring MVC's url mapping using annotations, i.e in Java I can write:
#Controller
#RequestMapping("/some-friendly-url/")
class MyController
{
#RequestMapping(value = "/{type}/more-seo-stuff/{color}", method = RequestMethod.GET)
public List<SomeDTO> get(#PathVariable String type,
#PathVariable String color,
int perPage) {
...
}
#RequestMapping(method = RequestMethod.POST)
public String post(#RequestBody SomeDTO somethingNew) {
...
}
}
It's actually much more powerful than this simple example as anyone familiar the the concept knows.
I've tried to search on how to achieve the same with either ASP.MVC 3 or with MonoRail and both frameworks seem to be based on RoR's convention-over-configuration "//" philosophy and it would be hard to achieve the above with them and require a lot of bespoke routing entries outside the controller class with only a small subset of the functionality available via attributes. Spring.NET does not seem to address this either stating that ASP.MVC's routing functionality is sufficient.
Is there anything out there in the C# world that provides this type of functionality? I was just about to start looking into writing something of my own to address this, but I was hoping not to have to do that.
Edit: Finally found the "AttributeRouting" project which is available on NuGet as well: https://github.com/mccalltd/AttributeRouting/wiki/1.-Getting-Started. Works perfectly. Doesn't support to full range of features that Spring MVC does, but supports most of it.
Also Akos Lukacs pointed to another good library below by ITCloud. However that one unfortunately is not available on NuGet.
Sure, you can use Spring.NET:
http://www.springframework.net/
I Eventually used https://github.com/mccalltd/AttributeRouting/wiki/1.-Getting-Started. Posting this only now for the sake of keeping the question complete.

Categories