umbraco mvc form model validation markup not showing - asp.net-mvc

Running Umbraco 6.05, I have a custom model class with Data Annotations like:
[Required, StringLength(100), DataType(DataType.EmailAddress), DataType(DataType.MultilineText)]
and I pass the model to the view like so:
#inherits Umbraco.Web.Mvc.UmbracoViewPage<test.local.Models.ContactForm>
<script src="~/Scripts/jquery-1.7.1.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>ContactForm</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
...
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
But when it renders, the "data-val" attributes are missing, though interestingly the DataType EmailAddress/MultiLine work fine by inserting 'type="email"' and creating a 'textarea' appropriately.
Any ideas what I might be doing wrong?
Cheers

Answer found here:
http://our.umbraco.org/forum/developers/extending-umbraco/36898-Enable-unobtrusive-validation-for-mvc-forms
Turn on client side validation in your web.config

Related

can i insert html code and Razor code in same cshtml page

Can I insert html designing/code with this Razor CSHTML code in same page?
#model project_final.Models.Bike
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
#<legend>Bike</legend>
#<div class="editor-label">
#Html.LabelFor(model => model.Id)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Id)
#Html.ValidationMessageFor(model => model.Id)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Color)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Color)
#Html.ValidationMessageFor(model => model.Color)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
Yes, you can.
Just beware of what is the code that need to have # in Razor engine, and what is html tag don't need the # like what #Stephen Muecke mentioned.
#Bike does not need the # in front of it because is html tag. Or I make a simple statement that
# never stick with <, if you found #< in your ASP.Net View, it must be a
mistake
Read the Introduction to ASP.NET Web Programming Using the Razor Syntax (C#), may be you can know more things about Razor.
By the way , you might need to read the post How can I add a class attribute to an HTML element generated by MVC's HTML Helpers? to modified the class of the HTML helper such as #Html.LabelFor
#Html.LabelFor(model => model.Id, new { #class = "col-md-2 control-label" })

Want to show masked input with current year after backslash in mvc view(razor)

Masking is working fine but I want to Auto generate year section by default like : 123-1234/(currentyear).
View.cshtml
<fieldset class="CreateEditfieldset Seconfieldset">
<div class="editor-label">
#Html.LabelFor(model => model.DONO)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.DONO)
#Html.ValidationMessageFor(model => model.DONO) // format : 123-1234/2014
</div>
</fieldset>
<script type="text/javascript">
$("#DONO").mask("999-9999/9999");
</script>
It's editorfor Id is "DONO" and masking is working fine I repeat.
One possible (hack-ish) way is to do this on the server:
$("#DONO").mask("999-9999/#DateTime.Today.Year");

MVC Partial View to Create/List Items and Redirect

What I'm trying to achieve is essentially have a view that at the top displays a form to enter new post, then below the form it will display a list of posts that already exist. Also I'm trying to make this view somewhat generic so that it can show different type of posts.
To be clear, by post I mean something like a facebook status post and not a Http-Post.
Imagine you have home page that displays all the posts, and then you have a profile page that displays only the posts connected to that profile.
So I have my _Posts partial view which looks like this:
#model IEnumerable<Post>
#Html.Partial("_CreatePost", new Post())
#foreach (var item in Model)
{
<div class="Post">
<h5>#item.Title</h5>
<p>#DateTime.Now.Subtract(item.Date).ToString("mm") minutes ago</p>
<p>#item.Content</p>
</div>
}
The code for the partial view is:
#model MVC_Test_CRUD.Models.Post
<script src="~/Scripts/jquery-1.7.1.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
#using (Html.BeginForm("Create","Post")) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Post</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Title)
#Html.ValidationMessageFor(model => model.Title)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Content)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Content)
#Html.ValidationMessageFor(model => model.Content)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
And I successfully display a list of posts and I'm able to create new posts as well.
I also have a standard Create Action in my controller, which results in
return RedirectToAction("Index")
if the creation was successful. So my question is how can I send additional parameter to the controller about where to redirect (home/index or profile/index or somewhere else) depending on where
#Html.Partial("_CreatePost", new Post())
was inserted.

In this ASP.NET MVC 3 app, what am I missing to get unobtrusive client-side validation?

I need help figuring out how to succeed in implementing unobtrusive client-side validation of a field in my ASP.NET MVC 3 app. I can see that unobtrusive client-side validation is basically enabled, since MVC generates related HTML.
What I want to achieve in this case is to have validation of input to the Bugs editor (i.e., the corresponding <input> element) as I type, for testing purposes I've set the property's max length to 2. When I test, I can tell that validation does not currently take place, so something is at least missing. So, the success criteria for this question is working client-side validation of the Bugs form field.
I can see one possible problem in the generated HTML: The Verbose property is not marked as Required in the model, but its corresponding <input> still gets the dataval=true attribute for instance, whereas the <input> for Bugs does not. Shouldn't it be the other way around, as fields with validation rules should get dataval=true, to enable unobtrusive validation?
The code that should be relevant to understanding the case follows, please let me know if more info is required:
Options.cs:
public class Options
{
[Required, StringLength(2)]
public string Bugs;
public bool Verbose;
}
Options.cshtml:
<script src="#Url.Content("~/Scripts/jquery-1.6.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>
<div id="options-form">
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Options</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Bugs)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Bugs)
#Html.ValidationMessageFor(model => model.Bugs)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Verbose)
</div>
<div class="editor-field">
#Html.CheckBoxFor(model => model.Verbose)
#Html.ValidationMessageFor(model => model.Verbose)
</div>
</fieldset>
}
</div>
The two editors (for Bugs and Verbose) are rendered as follows:
<div id="options-form">
<form action="/Options" method="post">
<fieldset>
<legend>Options</legend>
<div class="editor-label">
<label for="Bugs">Bugs</label>
</div>
<div class="editor-field">
<input class="text-box single-line" id="Bugs" name="Bugs" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="Bugs" data-valmsg-replace="true"></span>
</div>
<div class="editor-label">
<label for="Verbose">Verbose</label>
</div>
<div class="editor-field">
<input data-val="true" data-val-required="The Boolean field is required." id="Verbose" name="Verbose" type="checkbox" value="true" /><input name="Verbose" type="hidden" value="false" />
<span class="field-validation-valid" data-valmsg-for="Verbose" data-valmsg-replace="true"></span>
</div>
</fieldset>
</form>
</div>
Bugs and Verbose are public fields in this code, not properties. Make them properties and that should fix it.
Define get; and set; for both Bugs and Verbose properties. That will not just correct(add) validation, but in the future, model binder will be able to bind models back from form fields on server.
And regarding required attribute for Verbose. That is because of implicit required validation for value types taking place. string is nullable, so it is not required if you do not set Required attribute on it explicitely - so Bugs stays without required. But bool cannot be null by nature of c#, so mvc automatically adds Required attribute to it. You can control that with
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
I experienced the same problem recently (unobtrusive client-side validation didn't work in IE but worked in the other browsers though). The reason was in jQuery version. I rolled back from jQuery 1.6.x version to the version 1.5.2 an it started to work.

Why doesn't ASP.NET MVC 3 enable client-side validation in this case?

I'm trying to integrate unobtrusive client-side validation in my ASP.NET MVC 3 project, as per Brad Wilson's recipe. However, it does not get enabled in the rendered view. For example, my <input> elements (i.e., editor fields) do not receive a data-val attribute as prescribed.
I have done the following to enable unobtrusive client-side validation:
Web.config:
<configuration>
<appSettings>
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
</configuration>
Options.cs:
public class Options
{
// Annotate with validation rules, in order to generate client-side validation code
[Required, StringLength(60)]
public string Bugs = "";
}
_Layout.cshtml:
<head>
<script src="#Url.Content("~/Scripts/jquery-1.6.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>
</head>
Options.cshtml:
#model MyProject.Models.Options
<div id="options-form">
#Html.ValidationSummary(true)
<fieldset>
<legend>Options</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Bugs)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Bugs)
#Html.ValidationMessageFor(model => model.Bugs)
</div>
</fieldset>
</div>
This HTML gets generated for the editor field:
<div class="editor-label">
<label for="Bugs">Bugs</label>
</div>
<div class="editor-field">
<input class="text-box single-line" id="Bugs" name="Bugs" type="text" value="" />
As you can see, no data-val attribute :(
You forgot to use form. Surround your fieldset with Html.BeginForm
<div id="options-form">
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Options</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Bugs)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Bugs)
#Html.ValidationMessageFor(model => model.Bugs)
</div>
</fieldset>
}
</div>
This will initialize FormContext and your inputs will receive data-val-* validation attributes

Resources