I am creating a web app in asp.net-mvc in which I am sending a Required ErrorMessage from my model, but the problem is, I want to translate the message as per user's preference,
so I did something like below
[Required(ErrorMessage = convertErrorMessage("Text to translate"))]
public string Reviews { get; set; }
public string convertErrorMessage(string text)
{
//convertingText in different language
return convertedText;
}
but I am getting the below error
an object reference is required for non static field
on the below line
[Required(ErrorMessage = convertErrorMessage("Text to translate"))]
what can I do, if I want to achieve this?
You cannot call methods to initialize attributes, because these values have to be known at compile time. There are two possible other ways though:
ASP.NET MVC supports standard ways to doing localization, which is the recommended way to go. It is a very broad topic, so I can only leave a few links [1], [2] here. Notice that even the RequiredAttribute you are using has properties ErrorMessageResourceName and ErrorMessageResourceType - these are strong hints that you should be using standard tooling for standard tasks.
If you still want to stick to what you have, define your own attribute and implement your custom logic in there:
class RequiredLocalizedAttribute : RequiredAttribute {
// override ErrorMessage get
// or ErrorMessageString get
}
However, I would strongly advise looking into option 1 instead. You may need a bit more time to learn and implement this, and that won't be time wasted, and may save you lots of headache as you application grows
The user sometimes should be warned about an input but the input is not technically invalid.
I want to implement something like this:
[Range(5, 2147483647, "It's best if you enter a lower number")]
public int duration { get; set;}
PS - I have seen this How to provide warnings during validation in ASP.NET MVC?
but I don't really understand it.
If you want to do it during form input- without posting the form back, you should use Javascript for the task, not C#.
Your Range attribute only works in backend code.
You can use some ready to use javascript libraries. For example jqueryvalidation
I Have a MVC 5 application whose back-end is web API. For each request to my server I need to provide user-agent which I can get in controller action method like var UserAgent = Request.UserAgent.ToString(); and pass subsequently in other class like (Controller => Service => HttpRequester => XXXHttpClient) and finally use in actual request in XXXHttpClient class but I think there could be a better way to achieve the same. I tried to google it but didn't find anything relevant so can anyone guide me what would be the best practice If I want to get user-agent directly in XXXHttpClient class instead of passing subsequently.
Little bit of a broad question with a lot of possible answers.
Passing the data through all the layers is usually not a good thing.
What I would do is make an MVC action filter that grabs the user agent and sets it to an object. The object class could be like this:
public class RequestContext
{
public string UserAgent { get; set; }
}
Use your dependency injection framework to inject this once-per-request. Then the action filter and the layer that depends on the data would use the same instance, allowing you to get the data to any layer that needs it.
Another option which uses a static property:
HttpContext.Current.Request.UserAgent
Greater performance, easier to read, but lower testability :)
Background
We've been migrating a large amount of legacy code & systems to ASP.NET MVC forms. I've already coded up a number of CRUD type interfaces with MVC 4, using model binding, validation, attributes etc., so I'm fairly familiar with that whole paradigm. So far, all of these forms have been on our backend administration & management applications, where it pays to have very strict input validation. We are launching our first consumer facing application in MVC and are faced with a different type of problem.
The Problem
Our legacy forms in this area are the main revenue engine for our company. Usability of the consumer experience is the rule of the day. To that end, we want our forms to be as lenient as possible - the legacy system did a number of things to automatically correct user input (in entirely custom, non standard ways each time, of course). To that end, we don't so much want input validation as we want sanitation.
Examples
We ask the user for numerical inputs which have a unit of measure implied. Common ones are currency amounts or square footage. The input label is clear that they don't need to provide these formats:
What is the approximate square footage? (example: 2000)
What is your budget? (example: 150)
People being people, not everyone follows the directions, and we frequently get answers like:
approx 2100
1500 sq. ft.
$47.50, give or take
(Okay, I exaggerate on the last one.) The model that we are ultimately storing into our business logic accepts numeric input type for these fields (e.g. int & float). We can of course use datatype validator attributes (example [DataType(DataType.Currency)] for the budget input, or just having the field type be an integer for the square footage) to clearly indicate to the user they are doing it wrong, providing helpful error messages such as:
The square footage must be numbers only.
A better user experience, however, would be to attempt to interpret their response as leniently as possible, so they may complete the form with as little interruption as possible. (Note we have an extensive customer service side who can sort out mistakes on our system afterwards, but we have to get the user to complete the form before we can make contact.) For the square footage examples above, that would just mean stripping out non-digit characters. For the budget, it would mean stripping out everything that's not a digit or a decimal point. Only then would we apply the rest of the validation (is a number, greater than 0, less than 50000 etc.)
We're stuck on the best approach to take to accomplish this.
Potential Solutions
We've considered custom attributes, custom model bindings, and a separate scrubber service class that would live between the model and the database. Here are some of the considerations we've taken into account trying to decide upon the approach.
Custom Validation Attributes
I've read a number of helpful resources on this. (They have varying degrees of relevancy and recency. A lot of stuff I found searching for this was written for MVC2 or MVC3 and is available with standard attributes in MVC4.)
Extending ASP.NET MVC’s Validation
Custom Validation Attribute in ASP.NET MVC3
A lot of questions & topics on input sanitization which were focused on Cross-site scripting attacks or database injection.
What I haven't found is anyone doing what I want to do, which would be changing the model value itself. I could obviously create a local copy of the value, sanitize it and provide a pass/fail, but this would result in a lot of duplicate code. I would still have to sanitize any input values again before saving to the database.
Changing the model value itself has 3 benefits:
It affects subsequent validation rules, which would improve their acceptance rate.
The value is closer to what will be put into the database, reducing the additional prep & mapping overhead needed before storage.
In the event of the form being rejected for another reason, it gently suggests to the user "You're trying to hard on these fields."
Is this a valid approach? Is there someone out there who has used validation attributes in this way that I just missed?
Custom Model Binding
I read Splitting DateTime - Unit Testing ASP.NET MVC Custom Model Binders which focuses on custom date time input fields with custom validation & parsing done at the model binding layer. This lives a lot closer to the model itself, so it seems like a more appropriate place to be modifying the model values. In fact, the example class DateAndTimeModelBinder : IModelBinder does exactly that in a few places.
However, the controller action signature provided for this example does not make use of an overall model class. It looks like this
public ActionResult Edit(int id,
[DateAndTime("year", "mo", "day", "hh","mm","secondsorhwatever")]
DateTime foo) {
Rather than this
public ActionResult Edit(
MyModelWithADateTimeProperty model) {
Shortly before that, the article does say
First, usage. You can either put this Custom Model Binder in charge of all your DateTimes by registering it in the Global.asax:
ModelBinders.Binders[typeof(DateTime)] =
new DateAndTimeModelBinder() { Date = "Date", Time = "Time" };
Would that be sufficient to invoke the model binding for the date time field on the single-parameter model example MyModelWithADateTimeProperty?
The other potential draw back that I see here is that the model binder operates on a type, rather than an attribute you can apply to the standard data types. So for example, each set of validation rules I wanted to apply would necessitate a new, custom type. This isn't necessarily bad, but it could get messy and cause a lot of repeated code. Imagine:
public class MyDataModel {
[Required]
public CurrencyType BudgetRange { get; set; }
public PositiveOnlyCurrencyType PaymentAmount { get; set; }
[Required]
public StripNonDigitsIntegerType SquareFootage { get; set; }
Not the ugliest model code I've ever seen, but not the prettiest either.
Custom, External scrubber class
This has the fewest questions for me, but it has the most drawbacks as well. I've done a few things like this before, only to really regret it for one of the following reasons:
Being separate from the controller and model, it is nigh impossible to elegantly extend its validation rules to the client side.
It thoroughly obfuscates what is and what isn't an acceptable input for the different model fields.
It creates some very cumbersome hoops for displaying errors back to the user. You have to pass in your model state to the scrubber service, which makes your scrubber service uniquely tied to the MVC framework. OR you have to make your scrubber service capable of returning errors in a format that the controller can digest, which is rather more logic than is usually recommended for a controller.
The Question
Which approach would you take (or, have you taken) to accomplish this type of sanitization? What problems did it solve for you? What problems did you run into?
I would take ModelBinder approach.
When form data comes in - it goes to model binders infrastructure. There you can override decimal model binder to refine input. After that you can send it to validation routines without neeed to write specific validation attributes or something like that.
Also you can use one intelligent model binder that will do type switch internaly or override ModelBinderProvider, so your code wont be bloated with ModelBinderAttribute. Here is Jimmy Bogart article about this. Also you will get some flexibility, because you can use attributes to declare if model uses strict or adaptive binding.
In overall, IMHO, validation attributes are not suposed to alter input. They should validate it. Model binders are in fact responsible for converting all weird stuff that comes in into something usable in your system and your third approach duplicates Model binder functionality)
Hope this helps and sorry for my english)
For instance, I'd like to be able to send my.url/movie?title="a"&rating="b" and create a new row in the movie table with the appropriate data.
Is this possible?
One method I've attempted is creating movie.aspx which has movie.aspx.cs and movie.cs as well which can parse the information. Could I then send a post request with the relevant information, maybe?
I'm incredibly new to asp.net, mvc, and c#.
Certainly, in the controller that is fired with the example URL, build a handler for Movie that looks like this:
public ActionResult Movie(string title, string rating)
{
// do your work here
return View("SomeViewHere");
}
where SomeViewHere is the view you want to redirect to when you're done.
You can do this as Michael Perrenoud mentions, but I would strongly recommend against it. This opens you up to all kinds of attacks, including memory attacks where a malicious user could just hit permutations of words in your URL to pollute your database with millions and millions of rows in an effort to make it crash due to running out of space. I would highly recommend against this in any public-facing environment.