MVC 5 How to Validate Nullable Integers - c#

This has been asked and answered numerous times, but I have a special situation where I have nullable integers in my model.
Model:
[Range(0, int.MaxValue, ErrorMessage = "Please enter valid integer number")]
public int? Jan { get; set; }
In my edit form, if enter "x", then the browser default error pop-up with "Please enter a number" appears. My own client-side validation doesn't appear to be kicking in. If I enter nothing, then it blows up server-side because a parameter was expected in my repository code.
I need it to validate non-integers on the client and I also need it to handle nulls, when someone tries to submit the form with an empty value. I cannot resort to a Required data annotation, because if I do, no data will be loaded. This is a conversion from legacy code to MVC.
UPDATE - CLARIFICATION:
I'm dealing with a lot of nullable ints. The decision to try and make them required was mine - am open to alternative options. I cannot change the int? in the model for various reasons. So, I need to validate against nulls on the client and server to ensure that integers are entered.

You can use the HTML5 required attribute client side to prevent empty values from being entered. If you really want to ensure no empty values are sent to the server, I believe you are going to need to do some server side validation as well.
HTML5 Required Attribute

Related

Is it ok to expose messages from the `IdentityError` class?

I'm quite new to the asp.net core identity framework. Many tutorials, articles and guides seem to handle an IdentityError in the same way. They expose the description of the error to the user, i.e. they add the description of the error to the ModelState.
It's been drummed into my head that exposing errors to the user is a terrible idea as it empowers attackers.
So I thought, It must depend on what kind of information is available in the description. For example, if the error is "Your password is too weak" or "You need to enter in a valid e-mail address". That type of information is valuable to the user and should be ok to display. However a "The data source took too long to respond" is already too much information and offers little value. I'd rather catch that type of error and replace it with some generic 500 error.
So my question: Is it safe to show the raw Identity Error to the user? If not how can I filter what I should and Should not show to the user?
I tried looking at the MSDN docs to understand all the possible codes that I could receive. But those docs offer very little information.
I am specifically working with
var userCreationResult = await userManager.CreateAsync(newUser, password);
But it applies to any instance when an IdentityError might appear.
Many software quality and security regulations have audit requirements for this (no error message presented to end users may contain information that is secret or would enable users with malicious intent to compromise the system or access sensitive data), so this is an important question. If there is a documentation or article specifically addressing this, then it is well hidden.
The possible values that the two members of the IdentityError class can assume, are baked into the framework. So it looks like you can be sure that it will always be one of those, unless you obtain an instance of IdentityError from anything else than a UserManager.
The Code field is assigned from nameof of the error method, and the associated Description text is read from core framework resources, so those will be localized.
Source Code
en-us Descriptions
List of errors in current implementation (version 3.0.0):
DefaultError
ConcurrencyFailure
PasswordMismatch
InvalidToken
RecoveryCodeRedemptionFailed
LoginAlreadyAssociated
InvalidUserName
InvalidEmail
DuplicateUserName
DuplicateEmail
InvalidRoleName
DuplicateRoleName
UserAlreadyHasPassword
UserLockoutNotEnabled
UserAlreadyInRole
UserNotInRole
PasswordTooShort
PasswordRequiresUniqueChars
PasswordRequiresNonAlphanumeric
PasswordRequiresNonAlphanumeric
PasswordRequiresLower
PasswordRequiresUpper
Most of these are static strings and do not disclose any variable information.
The following do disclose variable information. This is data previously supplied by the user anyway in the first eight cases, and the value of a server configuration property in the last two cases, minimum required password length and minimum number of unique characters required in a valid password:
InvalidUserName: the user name
InvalidEmail: the email address
DuplicateUserName: the user name
DuplicateEmail: the email address
InvalidRoleName: the name of the role
DuplicateRoleName: the name of the role
UserAlreadyInRole: the name of the role
UserNotInRole: the name of the role
PasswordTooShort: the minimum password length
PasswordRequiresUniqueChars: the number of unique chars required
If that qualifies as "safe" within the constraints and specifications of your project, then the answer is yes.
Regarding your second question on how to do, you could do the following to filter out
a duplicate username as you loop through errors
if (error.Code == _userManager.ErrorDescriber.DuplicateUserName(user.UserName).Code)
{
//Hide info to user by, e.g. redirecting to a page for a registration flow, or display an invalid login attempt for a login flow
}

Is it possible to Display validation errors when page loads in MVC - 4 (with model validations)

Is it possible to trigger validation error message on page load based on model validations for example.
[Display(Name = "Quantity")]
[Required(ErrorMessage = "Please enter Quantity")]
[Range(1, 1000, ErrorMessage = "Please enter Qty between the range of 1 to 1000")]
[RegularExpression("^([0-9])*$", ErrorMessage = "Please enter valid Qty")]
public int? QTY { get; set; }
If saved value for Qty is 0(zero) in database and I want to fetch it & display on screen which is invalid as per model validation.
So is it possible to trigger that message without any value checks in controller.
Information given is bit scarce but I'll try.
If you're using jQuery Validate on your client, and you which to show error error messages of the said library. you can try to use something like:
$("#myform").validate();
If however you which to show the automatic ajax error message block. I recommend going with what Stephen Muecke proposed in comment.
If you wish for more specific response try to specify all the tools and libraries you have in use regarding validation. Or even simply showing your display solution for form would give ques to what libraries and tools you use.
PS. Try studying the client side solution on showing the wanted error message. If you learn what triggers the message. You should be be able to trigger the same event at ease using an script language etc.
Hope this helps :)

How to change EF decimal truncation behaviour

In entity framework, if you set the precision on a decimal column in your database to say 10,2, and update it in your EDMX, it will automatically truncate any decimals to 2 decimal places, correct?
I would prefer that it blow up in my face with an exception if I give it a number with a bunch of decimal places than have it silently truncate it, because it means I've not validated my data properly.
Is there a setting that I can set this? or am I going to have to attach to the savingchanges method and do some reflection?
To clarify with an example:
If I had a table called Invoice with a column called Amount. In my database this is a decimal(10,2) column, this is reflected in the EDMX, my entity says that this has a precision of 10 and a scale of 2.
Then in my code, lets say the user creates an invoice and they enter 10.23456 as the amount, I've forgotten to add some sort of clientside validation for this, so the amount gets sent to the server, my controller then saves an invoice with an amount of 10.23456. Entity framework will truncate this to 10.23 and be done with it.
What I want is this:
If I were to try and save an invoice with 10.23456 as the amount, EF sees that I have got a more precise value than my entity allows, and throws an exception. So this way my failure to validate inputs properly is discovered straight away.
You can«t make this configuration on the Entity Framework. But if you override your class and add some validation metadata on the properties, it will blow on you face with the validation error.
For example
[RegularExpression(#"^([\w-\.]+)#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$",
ErrorMessage = "ERROR MESSAGE")]
public string Email { get; set; }
OR
[StringLength(255, MinimumLength = 0, ErrorMessage = "ERROR MESSAGE")]
public string FriendlyName { get; set; }

Validation spanning a group of text boxes

I'm trying to achieve the following:
Where:
Surname is always required
NI Number OR Reference Number is required
Is this beyond the scope of the ASP.NET Validation Controls? The only solution I can think of is writing some bespoke javascript (for client side) and backing that up with some server side code.
One thing you can try is to have a CustomValidator(see here) check that both textboxes are not
empty. Then validate both textboxes with a regular expression. The expression should check for either a valid entry OR a blank field.
You can create a CustomValidator and handle it there
http://msdn.microsoft.com/en-us/library/aa479013.aspx#aspnet-validateaspnetservercontrols_topic7

How YOU parse user input?

Consider the following scenario:
http://www.yourdomain.com/Default.aspx?p=2
Now we ofcourse want to check if the querystring parameter p doesnt contain errors.
I now have this setup:
1) Check if p exists
2) Filter out html from p's value
3) htmlencode p's value
4) check if p is integer
5) check if p's integer exists in db
This is how I usual do it, though step 5 is ofcourse a performance hit.
Kind regards,
Mark
My view: Generally a querystring parameter of this kind isn't really "entered" by users but is submitted as a link. So over-complex slow validation isn't really necessary.
So I would just pass this through to the persistence / data layer and handle any errors that come back as a regular 404 Not Found or 500 Internal Server Error depending on the kind of system I'm working with.
If your intent is to use the parameter to retrieve something from the database, why filter out html or encode it? It's not like you're going to store it in the database, or display it on the front end. Just immediately throw it to the DAL if it exists. You're DAL should be smart enough to tell you if it failed to retrieve a record with that ID, or if the ID couldn't be parsed, etc..
If you are going to convert the input to an integer anyway, then steps 2 and 3 are not needed - just use int.TryParse to see what you have. I would encode and test the input for html only if you are expecting a string which you will use in a dynamic sql statement, or will be displaying on your site
What about:
int p = 0;
if(!Int32.TryParse(Request.QueryString["p"], out p))
throw new ArgumentOutOfRangeException("p");
Quite simple. For most data types (integers, decimals, doubles, dates and booleans) there is a very strict format. If the value does not parse under the strict format, it's an error.
Strings sometimes have a strict format, like an email address or a phone number. Those can be validated with a simple regexp. If it conforms, use it, otherwise it's an error.
Most of the time however strings will simply need to be persisted to the DB and later displayed again. In that case no processing is needed, aside from escaping when inserting into DB (unnecessary as well if you used parametrized queries)k, and HTML-encoding when rendering to the display.
This way any and all data is validated, and there is no risk of any injections whatsoever.
The rare exception of a loose format for a string is, well... rare. I can't think of any right now. For that you can afford some more extensive parsing and processing.
Added: Oh, yes, checking whether IDs (or other values) are valid in respect to a DB. You're doing it right, but think if you always need it. Quite often you can put the check into some other query that you have to do anyway. Like when you select data based on the ID, you don't need to explicitly check that it exists - just be ready that your query can return no data.
Sometimes you don't need to use the value at all, then you can simply ignore it.
But, of course, there are other times, like when inserting/updating data, that you indeed need to explicitly check whether the data exists and is valid in the current context.

Categories

Resources