I making a MVC2 project
View:
<%= Html.DropDownListFor ( m => m.CategoryId, Model.CategoryList )%>
<%= Html.ValidationMessageFor ( m => m.CategoryId )%>
<br />
<%if ((Html.TextBoxFor(m => m.NewCategory)).Equals("")) %>
<%{ show error msg near the textbox "* field is required"}%>
<% else %>
<%= Html.TextBoxFor(m => m.NewCategory)%>
If textbox is empty then show error msg and let the user to input again, how to do this?? :S
put a " [Required]" condition to the Property of your Model.
public class MyModel {
[Required]
public string NewCategory { get; set; }
}
A complete explained example can be found there: http://www.codeproject.com/Articles/220025/A-sample-on-Asp-Net-MVC-Model-Validation-using-Dat
Related
I have an application in which there is a user and retailer account. I want to implement validation of retailer registration form. I made a model for retailer with Required Connotation but the page still doesn't show any messages for wrong inputs. Any suggestion how I can achieve my goal. Im using Asp.net MVC
[PropertiesMustMatch("Password", "ConfirmPassword", ErrorMessage = "The password and confirmation password do not match.")]
public class RegisterStore
{
[Required(AllowEmptyStrings = false, ErrorMessage = "Store Name is Required")]
[DataType(DataType.Text)]
[Display(Name = "Store Name")]
public string Store_Name { get; set; }
.
.
Similarly other properties ...
.
.
}
The code for View is like
<h2>Create a Store Account</h2>
<p>
Use the form below to create a new account.
</p>
<% using (Html.BeginForm())
{%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Retailer Information</legend>
<div class="editor-label">
<%: Html.LabelFor(model => model.Store_Name) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Store_Name) %>
<%: Html.ValidationMessageFor(model => model.Store_Name) %>
</div>
.
... Similar DIVs for other properties ....
.
.
.
.
<p>
<input type="submit" value="Next" />
</p>
</fieldset>
<% } %>
The code for controller is like
[HttpPost()]
public ActionResult RetailerRegisteration(RegisterStore storeModel)
{
//ViewData["genders"] = Genders;
Debug.WriteLine("Started RetailerRegisteration");
if (string.IsNullOrEmpty(storeModel.UserName))
ModelState.AddModelError(string.Empty, "Please enter Username");
if (string.IsNullOrEmpty(storeModel.Store_Name))
ModelState.AddModelError(string.Empty, "Please enter a store name");
if (!string.IsNullOrEmpty(storeModel.Email) || !storeModel.Email.Contains("#"))
ModelState.AddModelError(string.Empty, "Please enter a valid e-mail address!");
if (string.IsNullOrEmpty(storeModel.Password))
ModelState.AddModelError(string.Empty, "Please enter a Password");
if(! storeModel.Password.Equals(storeModel.ConfirmPassword))
ModelState.AddModelError(string.Empty, "The Passwords must match");
if (ModelState.IsValid)
{
... Create Store Account ....
}
Try <%: Html.ValidationSummary(false) %> to show all errors.
Also, please refer to this question.
Are you using client validation or server-side validation only?
If you're checking server-side, are you checking ModelState.IsValid on POST? The validation won't actually fire until you check this property.
Are you using MVC2 or MVC3? There are subtle differences between the two. In either case, you must include the appropriate jQuery or Ajax validation JavaScript scripts to get client side validation.
ok i've defined a shared editor for string like the following
<%# Control Language="C#"
Inherits="System.Web.Mvc.ViewUserControl"
%>
<%= Html.LabelFor(model => model) %>
<%= Html.TextBoxFor(model => model) %>
<%= Html.ValidationMessageFor(model =>
model) %>
now i'm calling the custom editor like this in another control
<%= Html.EditorFor(model=>model.Username)%>
<%= Html.EditorFor(model=>model.Email)%>
<%= Html.EditorFor(model=>model.Password)%>
my model is like this
[Required(ErrorMessage="Le nom d'utilisateur est requis.")]
[DataType(DataType.Text)]
[DisplayName("Nom d'utilisateur")]
public string Username { get; set; }
[Required(ErrorMessage = "L'email est requis.")]
[DataType(DataType.EmailAddress)]
[DisplayName("Courriel")]
public string Email { get; set; }
[Required(ErrorMessage = "Le mot de passe est requis.")]
[ValidatePasswordLength]
[DataType(DataType.Password)]
[DisplayName("Mot de passe")]
public string Password { get; set; }
The only display that is rendered is the Email field.
The two others are not rendered ?
If i remove the DataType.Text and DataType.Password then all the display fields are rendered ??
Very strange behavior...
Someone knows why ?
You need a ValidationSummary to show the errors from all properties in a model. Otherwise, you will need a ValidationMessageFor for each property in the model.
This will work:
<%= Html.ValidationSummary() %>
Or this:
<%= Html.ValidationMessageFor(model.UserName) %>
<%= Html.ValidationMessageFor(model.Email) %>
<%= Html.ValidationMessageFor(model.Password) %>
DataType controls what type of template is used to render. When you specify Text or Password, then MVC will select the default templates for those (they're built-in) and ignore your template.
Email works because there is no built-in email template, and thus it falls back to string.
EDIT: I think i misunderstood. Are you saying they don't render at all? Do you have blank Password and Text templates in your EditorTemplates folder?
This code:
<%: Html.TextBoxFor(model => model.DonationMessage) %>
Renders an input type=text tag, but I want a textarea. I tried this in my entity but it didn't make a difference:
[DataType(DataType.MultilineText)]
public string DonationMessage { get; set; }
Any idea?
<%: Html.TextAreaFor(model => model.DonationMessage) %>
if u want your DataType attribute to be at work you can use EdiotrFor method instead
<%: Html.EditorFor(model => model.DonationMessage) %>
this will take into account your DataType attribute plus there are dozen other things that you can do with Editor Templates
I want to create a MVC 2 editor template for a value type i.e. int , has anyone done this with the preview 1 bits?
Many thanks
Will Nick Clarke's answer work when you submit the values on postback?
In MVC2 preview 2, calling Html.Textbox("abc", Model.ToString())
will render a textbox with ".abc" appended to the name, e.g.
<input id="StartDate_abc" name="StartDate.abc" type="text" value="02 Feb 09" />
which will cause problems when you postback and attempt to UpdateModel().
I did an editor template for a DateTime, the following works for me:
/Views/Shared/EditorTemplates/DateTime.ascx:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<DateTime>" %>
<%= Html.TextBox(String.Empty, Model.ToString("dd MMM yy")) %>
or, to use jQuery's DatePicker for all your DateTimes
add a reference to jQuery and jQueryUI to either your Masterpage or to the View containing the call to EditorFor.
/Views/Shared/EditorTemplates/DateTime.ascx:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<DateTime>" %>
<%= Html.TextBox("", Model.ToString("dd MMM yy")) %>
<script type="text/javascript">
$("#<%= ViewData.ModelMetadata.PropertyName %>").datepicker({ dateFormat: 'dd M y' });
</script>
Update: ASP.NET MVC3, using the Razor syntax:
#model System.DateTime
#Html.TextBox("", Model.ToString("dd MMM yy"))
<script type="text/javascript">
$("##ViewData.ModelMetadata.PropertyName").datepicker({ dateFormat: 'dd M y' });
</script>
And to use it all you need in your View is:
#Html.EditorFor(model => model.DueDate)
-Matt
I have not tried preview 1 yet but they did what you are asking for in this channel9 video:
http://channel9.msdn.com/posts/Glucose/Hanselminutes-on-9-ASPNET-MVC-2-Preview-1-with-Phil-Haack-and-Virtual-Scott/
They do both DisplayFor and EditorFor, starts around 2 minutes.
--Edit--
For value type i.e. int I was able to get it to work in the same way.
Create a model to pass to my view:
public class HomeController : Controller
{
public ActionResult Index()
{
HomeModel model = new HomeModel();
model.message = "Welcome to ASP.NET MVC!";
model.number = 526562262;
model.Date = DateTime.Now;
return View(model);
}
}
public class HomeModel
{
public string message { get; set; }
public int number { get; set; }
public DateTime Date { get; set; }
}
Link view to the model using the new template logic:
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<HomeModel>" %>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<p>
<% Html.EditorFor(c => c.message); %>
</p>
<p>
<% Html.EditorFor(c => c.number); %>
</p>
<p>
<% Html.EditorFor(c => c.Date); %>
</p>
Then create a template for each of the types e.g. Int32:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
Editor For My Int32: <%= Html.TextBox("abc", Model.ToString())%>
I put this in Views\Shared\EditorTemplates\Int32.ascx
I've written a blog post about how to do this by creating reusable templates in MVC 2.
My post also explains the relationship between TemplateInfo and templates.
I have found Brad Wilson's blog to have the best examples and explanations. Part-3 of the series talks specifically about value types (String, decimal, Int32).
Enjoy!
I have the following form in an ASP.NET MVC view:
<%= Html.ValidationSummary() %>
<% var fields = ViewData.Model; %>
<% using (Html.BeginForm("Dynamic", "Candidate")) { %>
<% foreach (var field in fields) { %>
<label for="<%= field.FieldName %>"><%= field.FieldName %></label>
<%= Html.TextBox(field.FieldName, field.Value, new { #class = "short" }) %>
<% } %>
<a class="button green" onclick="$('form').submit(); return false;">Submit</a>
<% } %>
I have a single controller action that loads this form as well as accepts the post, it looks like this:
public ActionResult Dynamic() {
var fields = DataProvider.Candidates.GetAllDynamicFields();
if (Request.HttpMethod == "POST") {
fields.ForEach(f => f.Value = Request[f.FieldName]);
var validation = DataProvider.Candidates.SaveDynamicFields(fields);
if (validation.IsValid)
return RedirectToAction("Index");
ViewData.ModelState.AddErrorsFromValidationResult(validation);
}
return View(fields);
}
My problem is that if any of the validators fail (i.e. the validation object contains errors) then I get an error on view rendering because ViewData.ModelState doesn't contain any keys. Where am I going wrong here? Any clues?
Figured it out. ViewData.ModelState is populated by the params in the response object. So with a dynamically created form you don't know exactly what was passed in the post. So I just recreate my ModelState on the fly:
fields.ForEach(f => ViewData.ModelState.Add(f.FieldName ...
And then we're all good...when the validation is run on the view it can find all the keys in the ModelState and no exceptions...works like a charm.
Asp.Net C# MVC Dynamic Forms (Changing Dom structure and getting data on the server)