MVC how to validate DateTime field with also client validation - asp.net-mvc

In my View Model I have setup a field with this attributes.
All work fine if the user enter the date and time in the correct format.
An error appear if the User do not insert the DateTime in the right format.
I would like have validation also in the client.
Could you tell me how to do it?
[Required]
[Display(Name = "Start DateTime")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy HH:mm}")]
public System.DateTime DateTimeStart { get; set; }

Getting format exceptions from a property of type DateTime is very annoying issue. It is a fairly common issue when working with validation on DateTime.
DataAnnotaions works on server side and to take their full advantage you need to add ModelState.IsValid() in your controller.
public ActionResult Index(MyViewModel model)
{
if(ModelState.IsValid())
{
// valid data received...
}
else
{
// Invalid data, add model error here and return view...
}
}
If you to make these work on client side then you need to include two additional JavaScript files in your code i.e. jquery.validate.js and jquery.validate.unobtrusive.js along with jQuery core library. By Default all of these files comes in basic MVC project and included in Layout.
It is important to note the order of including these files. jQuery core should always be at the top followed by validation libraries.
jquery.js
jquery.validate.js
jquery.validate.unobtrusive.js
Make sure the validation flags are turned on in web.config file of
MVC project. Go to this file and locate the following and set them
true if they are false.
<appSettings>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>
This should setup your validations to work on client side. You can decorate the model property with the RegularExpression.
[Required]
[RegularExpression("^(([0-2]?[0-9]|3[0-1])/([0]?[1-9]|1[0-2])/[1-2]\d{3}) (20|21|22|23|[0-1]?\d{1}):([0-5]?\d{1})$", ErrorMessage = "Invalid date")]
public string DateTimeStart { get; set; }
This will validate the datetime in dd-mm-yyyy hh:mm format.
Besides in this case you can make your property a string type also because regular expression will take care of your date format.
Apart from this, you can also create your custom DataAnnotation.

Firstly, what are you using to allow user to enter a date ?
If you are using Jquery DatePicker, then see this example there is no way the user can enter date in wrong format (except for inspecting the element and changing the textbox value, which can be ignored.)
Sample Code using Jquery Datepicker :
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>jQuery UI Datepicker - Default functionality</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.0/themes/base/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.8.3.js"></script>
<script src="http://code.jquery.com/ui/1.10.0/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<script>
$(function() {
$( "#datepicker" ).datepicker();
});
</script>
</head>
<body>
<p>Date: <input type="text" id="datepicker" /></p>
</body>
</html>
and incase you are not using DatePicker I very strongly recommend you to use it.
Incase you are new to datepicker, you can go through the following listed articles to get started :
Introduction to jquery Date Picker in ASP.NET MVC
jQuery UI. Widgets. Datepicker (Calendar)

Related

Encoding issue asp.net mvc 4

I´m trying to render a dynamic database title in asp.net mvc view. So I have something like this in my view.
#section meta {
<meta name="title" content="#Model.title" />
}
When model has special characters like Misión in spanish it shows in title something like
Misi&#243;n ... I´m using meta charset utf8 in my layout. Is there a special encoding I´m missing ?
How can I render Misión in title page ?
Using #someproperty will assume you're rendering out HTML and make sure it gets encoded to prevent things like cross site scripting. In this instance you want it to render the raw value, in which case you need to use Html.Raw(...) to render your content in it's raw form.
#section meta {
<meta name="title" content="#Html.Raw(Model.title)" />
}
However, just be aware that if the Model.title can come from user generated content (or some other untrusted source), you could be opening yourself up to security issues (for example if your Model.title's value was "test" /> <script ...etc...", a malicious user could use it to inject code into your pages.
Edit: Just including the content of my comment below for future googlers, since it appears that was the actual solution...
If you put the #Html.Raw(Model.title) directly in the page somewhere (i.e. not in the meta tag) and it works correctly there, you may be facing the same problem discussed here, in which case you could work around it by using the slightly uglier:
#section meta {
<meta name="title" #Html.Raw("content=\" + Model.title + "\"") />
}
Approach - 1
string value1 = "<html>"; // <html>
string value2 = HttpUtility.HtmlDecode(value1); // <html> //While getting
string value3 = HttpUtility.HtmlEncode(value2); // <html> //While saving
Approach - 2
Html.Raw("PKKG StackOverFlow"); // PKKG StackOverFlow

Asp.net MVC client validation, no client validation with sub-items?

I'm using asp.net mvc 3 for a project and already using the server and client validation on several pages. It works fine. But this time, I've a special case:
Items in the view are bounds to the model and also to some of its properties.
one example:
public class MyModelView{
[Required]
[StringLength(100, MinimumLength = 2)]
public String Name{get;set;}
public DetailsObject Details{get;set;}
}
public class DetailsObject{
[Required]
[StringLength(100, MinimumLength = 2)]
public String PropertyOne{get;set;}
[Required]
[StringLength(100, MinimumLength = 2)]
public String PropertyTwo{get;set;}
}
and in the view I've "bindings on all elements
#Html.TextBoxFor(m=>m.Name)
#Html.TextBoxFor(m=>m.Details.PropertyOne)
#Html.TextBoxFor(m=>m.Details.PropertyTwo)
The problem is that I don't get any client validations. The server validation is still working fine for all properties.
I've the jquery validate unobtrusive included. How do you manage that?
there are several places you should check
web.config should have those lines
<appSettings>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>
check the javascripts to be included in right order
<script src="/Scripts/jquery-latest.min.js" type="text/javascript"></script>
<script src="/Scripts/jquery.validate.min.js" type="text/javascript"></script>
<script src="/Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.min.js" type="text/javascript"></script>
also as a reminder (as I don't see the whole view file) place ValidationMessageFor helpers to see validation errors

MVC 3 building dynamic meta keywords meta description functionality for multi-culture site

I need to create db driven meta keywords/description. I would store these records in a database, xml format i presume; since it would be per culture.
How would i go about doing this?
any feedback, suggestions, help, greatly appreciated.
thanks
What you need to change is just the call to method that returns the keywork/description
You can use Thread.CurrentThread.CurrentUICulture to determine the user culture.
You need to change at web.config to auto change the culture.
Ex.:
(Web.Config)
<globalization uiCulture="auto" culture="auto" />
(Controller)
ViewBag.Description = GetDescription(pageId, Thread.CurrentThread.CurrentUICulture.Name)
(View)
<meta name="description" content="#ViewBag.Description ">
Make a parent interface for all your model objects. and you could have:
public interface IBaseMasterViewDto
{
int PageId { get; set; }
string Title { get; set; }
string MetaKeywords { get; set; }
string MetaDescription { get; set; }
}
Thus in your master view you could use
<%# Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage<IBaseMasterViewDto>" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
<head>
<title><%: Model.Title %></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta name="keywords" content="<%: Model.MetaKeywords %>" />
<meta name="description" content="<%: Model.MetaDescription %>" />
Hope it helps.
Shane,
I answered a somewhat similar question here on SO a while back. I didn't cover the cultural elements, but fujiy's answer above goes towards that in a way. Also, alexl's interface is a FAR better solution to loose typed viewdata elements (as per my answer in the similar question). anyway, here's what i answered 'on the day' for that question:
MVC and Meta Tags for Search Engine Optimization
1 - Get keywords/description (from your Model) in your controller
2 - Assign them to a Viewbag property
3 - Display the viewbag property in your layout (or view)
OR
Assign your model with keywords/description and give it to your view as a parameter in your controller.
About the culture :
You just have to put it as a parameter in your method controller (and in your route).
After that, you have to give this parameter to your method retrieving keywords/description.

ASP.NET MVC 3 RC 2 client side validation with globalization

My goal is to validate a user input on the client-side, depending on the users' culture.
I have a primitive data-model with the following structure:
public class User
{
public int UserId { get; set; }
[Required]
[StringLength(20,MinimumLength=3)]
public string Name { get; set; }
[Required]
public double Height { get; set; }
}
Furthermore, I want to have client-side validation enabled, checking if it is a valid number. Therefore, I've added the following lines in the <head> section of my _Layout.cshtml.
<script src="#Url.Content("~/Scripts/jQuery-1.4.2.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
Since I want to have the ability to validate the input in another language formats (in this particular context it's German with the decimal number format of 0,75 whereas in the US it would be 0.75), I've added the following lines (jQuery Globalization PlugIn) AFTER the previously mentioned jquery.validate.min.js and jquery.validate.unobtrusive.min.js.
<script src="#Url.Content("~/Scripts/jquery.glob.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/globinfo/jquery.glob.de-de.js")" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$.culture = jQuery.cultures['de-DE'];
$.preferCulture($.culture.name);
});
</script>
In addition, I've added the following line to the web.config in the system.web section just to make sure that the German culture is always selected:
<globalization culture="de-DE" uiCulture="de-DE" />
Now I am experiencing the following behavior:
If I type in 0,1 (note the German 'spelling') in the textbox for the value of "Height", the validation error message The field Height must be a number appears and I'm not able to submit the form.
If I type in 0.1 (English 'spelling'), I can submit the form but the server-side validation returns the following validation error message The value '0.1' is not valid for Height.
So now I am in some kind of dead lock where I can't get out.
Again, my goal is to validate the decimal number input on the client AND server side, based on the users' culture (in this case it's forced to be German). What am I doing wrong?
Any help is highly appreciated! Thank you in advance!
Unfortunately there's a naming conflict between jQuery.validate.format and jQuery.Globalization.format functions. Therefore you'll have to change your code to use the non-jquery Globalization plugin.
I just wrote a blog post about it here.
For you it should look like this:
<script src="#Url.Content("~/Scripts/globalization.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/globinfo/Globalization.de-DE.js")" type="text/javascript"></script>
<script type="text/javascript">
$.validator.methods.number = function (value, element) {
if (!isNaN(Globalization.parseFloat(value))) {
return true;
}
return false;
}
$(document).ready(function () {
$.culture = jQuery.cultures['de-DE'];
$.preferCulture($.culture.name);
Globalization.preferCulture($.culture.name);
});
</script>
That should be enough.
I had to disable the UnobtrusiveJavaScript. The page does not react instantly anymore, but at least it works.
You can disable by default in the Web.Config.
<appSettings>
<add key="enableSimpleMembership" value="false"/>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="false"/>
</appSettings>
And I use the Microsoft scripts for validation:
MicrosoftAjax.js
MicrosoftMvcAjax.js
MicrosoftMvcValidation.js
And also the jquery-1.4.4.min.js & jquery.glob thing, but I think I use them internally. The validation is being done by the MS scripts.

JQuery UI button submitting entire content problem in IE 6.0

I have the same problem as posted here
I have a <button> element that triggers "A potentially dangerous request.form value..." error in asp.net MVC. For instance:
<button type="submit" name="logon" value="ok">Confirm</button>
<button type="submit" name="cancel" value="ok">Cancel</button>
And this javascript (with jquery UI 1.8.5)
<script type="text/javascript">
$(document).ready(function() {
$("button").button();
});
</script>
The issue is that I can't remove the name property (as the given solution in the link I posted) because I capture which button is pressed in the controller side this way:
public ActionResult Logon(FormCollection form, string logon, string cancel)
{
if (!string.IsNullOrEmpty(logon))
{
DoLogon();
}
if (!string.IsNullOrEmpty(cancel))
{
Cancel();
}
//etc
}
Is there any workaround for this? Thanks. Note that I don't have this problem in IE8 or firefox.
Have you seen this?
Cause
The .NET framework is throwing up an error because it detected something
in the entered text which looks like an HTML statement. The text doesn't
need to contain valid HTML, just anything with opening and closing
angled brackets ("<...>").
The solution proposed there is to disable the request validation on the server-side:
<pages validateRequest="false" />
Be sure to read through the warnings and explanations as well.

Resources