How to handle nulls in ASP.NET MVC - asp.net-mvc

I have user registration form. It has field Date of birth. It is not compulsory in database also not on UI. But while create when i am goiing to assign it to objects property, i have to convert it in to date format. But if i have not selected it, it will become null in the FormCollection object. like
User.DOB=Convert.ToDateTime(collection["DOB"]);
Now issue is if it collection["DOB"]is null then it throws exception. I can not assign default value here. So how can i handle this situation?

You'll probably be better off using DateTime.TryParse for this.
This way you can check whether you're working with a valid date or not.
DateTime dateOfBirth;
bool isValidDateOfBirth = DateTime.TryParse(collection["DOB"], out dateOfBirth);
if(isValidDateOfBirth)
{
// do stuff
}
else
{
// do some other stuff
}

Related

How do you validate a datatype in umbraco?

I've created a custom data type in umbraco and I would like to check the value before it is saved and provide error messages if it is not ok.
How do you enforce validation rules on a data type?
have you consider using ValidationProperty for this purpose?
Once you added the attribute, you can implement the property by adding your validation logic. This way you can make sure about data validation before you user save the record with new custom datatype.
E.g
[ValidationProperty("HasValidValue")]
public partial class MyDataEditor : System.Web.UI.UserControl,
umbraco.editorControls.userControlGrapper.IUsercontrolDataEditor
In your Custom datatype logic and then has something like following....
public string HasValidValue
{
get
{
if (CheckIfDataIsValid())
return "Valid";
else
return String.Empty;
}
}
This way you can do it at code level.
Thanks,
Jigar

asp.net mvc 3 validation on data type

I am trying to realize valition on data type. I have used DataAnnotations, but for data type it's not showing customized message
for example when I' am trying enter string data into int typed field. How I can customize messages in this case?
If I had to guess, you sound like you want a custom message to display when validating one or more fields in your model. You can subclass the DataAnnotations.ValidationAttribute class and override the IsValid(object) method and finally setting a custom ErrorMessage value (where ErrorMessage already belongs to the ValidationAttribute class)
public class SuperDuperValidator : ValidationAttribute
{
public override bool IsValid(object value)
{
bool valid = false;
// do your validation logic here
return valid;
}
}
Finally, decorate your model property with the attribute
public class MyClass
{
[SuperDuperValidator(ErrorMessage="Something is wrong with MyInt")]
public int MyInt { get; set; }
}
If you're using out-of-the-box MVC3, this should be all you need to propertly validate a model (though your model will probably differ/have more properties, etc) So, in your [HttpPost] controller action, MVC will automagically bind MyClass and you will be able to use ModelState.IsValid to determine whether or not the posted data is, in fact, valid.
Pavel,
The DataAnnotations DataType attribute does not affect validation. It's used to decide how your input is rendered. In such a case, David's solution above works.
However, if you want to use only the built-in validation attributes, you probably need to use the Range attribute like this:
[Range(0, 10, ErrorMessage="Please enter a number between 0 and 10")]
public int MyInt { get ; set ;}
(Of course, you should really be using the ErrorMessageResourceName/Type parameters and extract out hard-coded error message strings into resx files.)
Make sure to let MVC know where to render your error message:
<%= Html.ValidationMessageFor(m => m.MyInt) %>
Or you can just use EditorForModel and it will set it up correctly.
I don't think this has been answered because I have the same issue.
If you have a Model with a property of type int and the user types in a string of "asd" then the MVC3 framework binding/validation steps in and results in your view displaying "The value 'asd' is not valid for <model property name or DisplayName here>".
To me the poster is asking can this message that the MVC3 framework is outputting be customized?
I'd like to know too. Whilst the message is not too bad if you label your field something that easily indicates an number is expected you might still want to include additional reasons so it says something like:
"The value 'asd' is not valid for <fieldname>; must be a positive whole number."
So that the user is not entering value after value and getting different error messages each time.

How to set default value of TextBox empty string instead of null

I may be out of date, but one principle I adhere to is avoid nulls as much as possible.
However what I have found is that for a strongly typed view in which the user inputs the properties of an object I want to save, if some fields are not entered they are assigned as null.
Then when you try to save the changes, the validation fails.
So rather than set each property to an empty string, how can I automatically set each TextBox on a form to default to an empty string rather than a null?
You could put the following attribute on your string-properties in your model:
[DisplayFormat(ConvertEmptyStringToNull=false)]
So whenever someone posts a form with empty text-fields, these will be an empty string instead of null...
To be honest, I'd say your coding methodology is out of date and flawed. You should handle all possibilities, it's not hard. That's exactly what string.IsNullOrEmpty(value); is for.
I'm guessing your validation logic is something like:
if (value == string.Empty) { isValid = false; }
So it doesn't handle the null values. You should replace that check so it also checks for nulls.
string value1 = null;
string value2 = string.Empty;
string.IsNullOrEmpty(value1); // true
string.IsNullOrEmpty(value2); // true
An alternative solution to using attributes on each model property, as described in the accepted answer, is using a custom model binder, see string.empty converted to null when passing JSON object to MVC Controller
I ran across this problem when dealing with an old service that requires empty strings. I created an extension method:
public static string GetValueOrDefault(this string str)
{
return str ?? String.Empty;
}
So you can use this when you want to make sure any strings that are null become empty
yourString1.GetValueOrDefault();
yourString2.GetValueOrDefault();

How to get model binder to leave null strings as null?

My Sql Server database has some nullable nvarchar fields, and no nvarchar fields containing empty strings. I want to keep it this way, but the default MVC model binder seems to turn null strings into empty strings.
When a controller retrieves a null nvarchar database field, the null field turns into null string inside the controller, and from there the view renders them, say as blank text boxes. When the page is posted, the default model binder uses these blank text boxes to update the model, and the formerly null strings are changed to empty strings. When the data is updated back to the database, nulls are overwritten with empty strings.
What is the easiest way to get model binding to leave these nulls unchanged?
I know you are probably looking for something more sophisticated, but the default behavior of the ModelBinder is to convert empty form field values into the default value for the datatype of your model object property. String properties become empty, int properties become 0, etc.
You can obviously create a validation scheme that will check for string.empty and convert to null prior to updating the DB. For int form fields you will need to check for 0, and then convert to null.
Here's a hack I used a few months ago before I found the eden of stackoverflow. :) It's a pain, and doesn't scale well, but it works:
Basically, you override the binding inside of a partial linq object. If there's a value you know should always be null (but never legitimately empty) you can do the following. I used this for a string-based user id (SID).
partial void OnSubProcess_Owner_UserChanged()
{
if (string.IsNullOrEmpty(this.SubProcess_Owner_User))
this._SubProcess_Owner_User = null;
}
James
The right answer might be to override the default Model binder to add this functionality yourself.
Maybe you could have a NullValueAttribute that you could apply to string properties to identify the null value. Then make empty string a null value.
I am experiencing the same problem at the moment and will probably resort to this
I'm posting this answer to follow through on this question. After working with it for a while I came to see this problem as part of the general concern of model integrity. For a while I had implemented a solution inside my update stored procedures to catch empty strings and turn them to nulls, along the lines of mikerennick's answer above. Later I wanted also to make sure fields were trimmed and I happened to move the application to NHibernate (and most of the stored procedures went away). In the end I embedded some POCO logic to trim and check for empty strings (from whatever source) in the setters as so:
public MyClass {
private string _name;
public string Name {
get { return _name; }
set { _name = value.TrimToNullIfEmpty(); }
}
}
public static class StringExtensions {
public static string TrimToNullIfEmpty(this string s) {
string temp = (s ?? "").Trim();
return temp.Length == 0 ? null : temp;
}
}

Default Values in LINQ Modelling

To put it in basic form, my database table doesn't allow nulls for varchars, it must have blanks. My model doesn't allow nulls so it won't insert a record if I leave form fields empty. If an empty form field appears I want a default value of blank to be used instead. I've tried, for example, the following without any luck:
[Column]
[DisplayName("WMD Company")]
[DefaultValue(" ")]
public string WMDCompany { get; set; }
So instead, in my controller action I have to do a check like the following:
if(myModel.WMDCompany == null) myModel.WMDCompany = " ";
Which is plain nasty to me. Is there any way of getting [DefaultValue(" ")] to work?
Cheers
What about something like this:
private string wmdCompany;
public string WMDCompany
{
get
{
if (this.wmdCompany == null)
{
return string.Empty;
}
return this.wmdCompany;
}
set
{
this.wmdCompany = value;
}
}
The DefaultValue attribute is not used. LINQ to SQL has not support for DB defaults unfortunately. That property is intended for use in API extension if I remember, but I don't know of any that use it.
Two approaches to get around this you could use.
First update your data layer, by appropriately controlling the property, and setting it to null. Use a partial class to extend your data class, and implement the OnCreated() partial method, and in this set the value to String.Empty.
partial void OnCreated()
{
MyProp = String.Empty;
}
Secondly, you could change your DBML representation to allow nulls, but in your database, use a trigger to convert NULLs to empty strings.
I'd go with the first approach myself - assuming you can't just use NULLs as suggested by Adrian
Inserting spaces as a placeholder for NULL seems like a very obscure method to me. Why don't you just change your table design to allow NULL values?

Resources