Override Default MVC Editor Templates Not Working - asp.net-mvc

I've been unable to get default editor templates to work in my MVC 4 Razor web application. I've been unable to find any clues. I want to override String, Password, etc. I've tried UIHints in my model (even though you shouldn't have to for default editor templates), ensured I'm using EditorFor in my view and have placed the Editor Templates under ~/Views/Shared/EditorTemplates. I'm stuck. Any help would be appreciated. Thanks!
public class LoginModel
{
[Required(AllowEmptyStrings = false)]
[StringLength(128)]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required(AllowEmptyStrings = false)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
[HiddenInput()]
public Guid UserEmailAddressId { get; set; }
[HiddenInput()]
public bool IsVerified { get; set; }
}
Part of my view where I'm binding to my model...
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>RegisterModel</legend>
<div class="editor-label">
#Html.LabelFor(model => model.UserName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.UserName)
#Html.ValidationMessageFor(model => model.UserName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PrimaryEmailAddress)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PrimaryEmailAddress)
#Html.ValidationMessageFor(model => model.PrimaryEmailAddress)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Password)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ConfirmPassword)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ConfirmPassword)
#Html.ValidationMessageFor(model => model.ConfirmPassword)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.CultureId)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.CultureId, (IEnumerable<SelectListItem>)ViewBag.Cultures, " -- Select -- ", null)
#Html.ValidationMessageFor(model => model.CultureId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.TimeZoneId)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.TimeZoneId, (IEnumerable<SelectListItem>)ViewBag.TimeZones, " -- Select -- ", null)
#Html.ValidationMessageFor(model => model.TimeZoneId)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
In the Password.cshtml file under ~/Views/Shared/EditorTemplates/Password.cshtml
#Html.Password("", ViewData.TemplateInfo.FormattedModelValue, new { #class = "k-textbox" })
THE EDITOR IS WORKING

Turns out I was looking at the wrong View. The actual View was using #Html.TextBoxFor which is why the Default Editor Template for the password was not rendering. You need to use #Html.EditorFor to invoke the default editor template.

Related

DropDownListFor in MVC 4

I am having a hard time to show dropdownlist for in the view, the values will be populated from database. I am using MS SQL Server as the database.
I want to show a drop down list in ApplyingFor which will be populated from database.
Please help me out.
This is the Model
public class CandidateProfile
{
[Display(Name = "Candidate Name")]
[Required(ErrorMessage = "Provide a Name", AllowEmptyStrings=false)]
[DataType(DataType.Text)]
public string CandidateName { get; set; }
[Required(ErrorMessage = "Provide Your Address",AllowEmptyStrings = false)]
[Display(Name = "Address")]
[DataType(DataType.MultilineText)]
public string Address { get; set; }
[Display(Name = "Phone Number")]
[Required(ErrorMessage = "Provide a Phone Number")]
[RegularExpression("^([07][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | 8[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | 9[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9])$", ErrorMessage = "Enter Valid Mobile Number")]
public string PhoneNumber { get; set; }
[Display (Name = "Email-Id")]
[Required(ErrorMessage="Provide an email-id")]
[EmailValidator]
public string EmailId { get; set; }
[Display (Name = "Applying For")]
public string **ApplyingFor** { get; set; }
[Display (Name = "Experience")]
[Required(ErrorMessage = "")]
public int Experience { get; set; }
[Display (Name = "Present Location")]
[Required(ErrorMessage = "")]
public string PresentLocation { get; set; }
}
public class ApplyingPositions
{
public IEnumerable<ApplyingPositions> ApplyingPosition { get; set; }
}
public class ApplyingPosition
{
public int APId { get; set; }
public string Designation { get; set; }
}
This is the View:
#model Recruitment.Models.CandidateProfile
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>CandidateProfile</legend>
<div class="editor-label">
#Html.LabelFor(model => model.CandidateName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.CandidateName)
#Html.ValidationMessageFor(model => model.CandidateName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Address)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Address)
#Html.ValidationMessageFor(model => model.Address)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PhoneNumber)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PhoneNumber)
#Html.ValidationMessageFor(model => model.PhoneNumber)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.EmailId)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.EmailId)
#Html.ValidationMessageFor(model => model.EmailId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ApplyingFor)
<div class="editor-field">
#Html.EditorFor(model => model.ApplyingFor)
#Html.ValidationMessageFor(model => model.ApplyingFor)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Experience)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Experience)
#Html.ValidationMessageFor(model => model.Experience)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PresentLocation)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PresentLocation)
#Html.ValidationMessageFor(model => model.PresentLocation)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
You need to pass the List of Options from your controller to view. So, before returning View
var listOfPositions = new List<ApplyingPosition>();
listOfPositions = //Call the service to populate the listOfPositions from Database here
ViewBag.PositionsList = new SelectList(listOfPositions, "APId", "Designation");
In your view instead of #Html.EditorFor(model => model.ApplyingFor)
#Html.DropDownListFor(m => m.ApplyingFor, (SelectList)ViewBag.PositionsList, "Select")
populate lstApplyingFor (list) form your DB. and in your controller
ViewBag.ApplyingFor = new SelectList(lstApplyingFor, "Id", "Name");
and in view:-
#Html.DropDownList(m => m.ApplyingFor,"ApplyingFor", "--Select--")
First-
1) You need to create the source for dropdown as-
var listForApplyingFor= db.Table.Select(o=> new SelectListItem{
Value=o.ID,
Text= o.Text
}).ToList();
ViewBag.ItemsApplyingFor= listForApplyingFor
.Cshtml View-
#Html.DropdownListFor(m=>m.ApplyingFor, new SelectList(ViewBag.ItemsApplyingFor,"Value","Text"),"Select...", htmlAttributes:new{ })
Let me know if it helps.

Remote Validation working elsewhere

I have a user registration page where I implemented the remote validation concept for the Username. I basically want to keep each Username a unique value. I was able to achieve it, but now in the login page, when I type the username it prompts a message saying the Username is not available. This was meant just for the registration page and not the login page. Could someone please explain what is the mistake I am doing. I have a Model User which has a Username property; to which I am using the remote validation. I have an Action method called UserNameExsists which gets triggered for the remote validation. And the Registration view which utilities the validation. But the validation is being triggered for the login page as well. Is there a way I could set it up just for the Registration View?
Model:
public class User
{
public int ID { get; set; }
[Required]
[Remote("UserNameExists","User",ErrorMessage="Username not available")]
[Display(Name="User Name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[Required]
[Display(Name="First Name")]
public string FirstName { get; set; }
[Required]
[Display(Name="Last Name")]
public string LastName { get; set; }
[Required]
[DataType(DataType.PhoneNumber)]
[MinLength(10)]
[MaxLength(10)]
[Display(Name="Mobile No")]
public string PhoneNum { get; set; }
}
Controller: (Name is User)
//Remote Validation
public JsonResult UserNameExists(string username)
{
bool user = db.Users.Any(p => p.UserName == username) ? false : true;
return Json(user,JsonRequestBehavior.AllowGet);
}
View:
Registration page view
#model HindiMovie.Models.User
#{
ViewBag.Title = "Register";
}
<link href="~/Content/Site.css" rel="stylesheet" />
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<h2>Register</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>User</legend>
<div class="editor-label">
#Html.LabelFor(model => model.UserName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.UserName)
#Html.ValidationMessageFor(model => model.UserName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Password)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.FirstName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.FirstName)
#Html.ValidationMessageFor(model => model.FirstName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.LastName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.LastName)
#Html.ValidationMessageFor(model => model.LastName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PhoneNum)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PhoneNum)
#Html.ValidationMessageFor(model => model.PhoneNum)
</div>
<p>
<input type="submit" value="Register" />
<input type="reset" value="Clear" />
</p>
</fieldset>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Login page View:
#model HindiMovie.Models.User
#{
ViewBag.Title = "Login";
}
<h2>Login</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
<fieldset>
<legend>User</legend>
<div class="editor-label">
#Html.LabelFor(model => model.UserName)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.UserName)
#Html.ValidationMessageFor(model => model.UserName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Password)
</div>
<div class="editor-field">
#Html.PasswordFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
<p>
<input type="submit" value="Sign in" />
</p>
</fieldset>
}
#Html.ValidationMessage("LogOnError")
<div>
#Html.ActionLink("Create account", "Register","User")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
You are using the same model for the Login and the Registration page, so you get the same validation on both pages.
Create a ViewModel for each view and put your validation attributes there.
That way you can differentiate between the validations for each page.

Cannot convert lambda expression to type 'string' because it is not a delegate type MVC

I know there is a lot of topics like this one, but I cant find the answer.
In code:
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>TabelaModel</legend>
#Html.HiddenFor(model => model.ID)
<div class="editor-label">
#Html.LabelFor(model => model.Druzyna)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Druzyna)
#Html.ValidationMessageFor(model => model.Druzyna);
</div>
<div class="editor-label">
#Html.LabelFor(model => model.LiczbaMeczy)
</div>
<div class="editor-field">
#Html.TextBox(model => model.LiczbaMeczy)
#Html.ValidationMessageFor(model => model.LiczbaMeczy)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.LiczbaGoliStrzelonych)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.LiczbaGoliStrzelonych)
#Html.ValidationMessageFor(model => model.LiczbaGoliStrzelonych)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
Compiler is throwing an exception in line:
#Html.TextBox(model => model.LiczbaMeczy)
I have put a System.Linq, System.Data.Entity in model, in view, in controller, but still nothing. It's working when i replace #Html.TextBox into #Html.EditorFor, but i really would like to avoid this. My model class:
namespace GridViewTest.Models
{
public class TabelaModel
{
public int ID { get; set; }
public string Druzyna { get; set; }
[Required (ErrorMessage="*")]
public string LiczbaMeczy { get; set; }
[Required(ErrorMessage = "*")]
public int LiczbaGoliStrzelonych { get; set; }
}
}
Could You help me ?
You need to use TextBoxFor (not TextBox):
#Html.TextBoxFor(model => model.LiczbaMeczy)
That will take the lambda expression.

MVC Range Attribute not working properly

I have a RangeAttribute that checks if the value of a data field is within a specified range of values here, that gives me a validation error even if I pick a date in between "01/01/2000", "01/01/2015":
[Range(typeof(DateTime), "01/01/2000", "01/01/2015")]
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
[DataType(DataType.Date)]
public Nullable<System.DateTime> Date { get; set; }
Here is my edit.cshtml code:
#model StringLength.Models.Employee
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Employee</legend>
#Html.HiddenFor(model => model.ID)
<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>
<div class="editor-label">
#Html.LabelFor(model => model.Gender)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Gender)
#Html.ValidationMessageFor(model => model.Gender)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Email)
#Html.ValidationMessageFor(model => model.Email)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Age)
#Html.ValidationMessageFor(model => model.Age)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Date)
#Html.ValidationMessageFor(model => model.Date)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
For instance, if I pick 1.1.2014, I am NOT supposed to see any validation error.
Could anyone please help?
Thanks in advance!
First, DateTime structs weren't properly created from given strings. As your message in red states those strings were converted to 1.1.1910 and 1.1.2060 DateTimes. You should go with CustomValidation attribute.
Second, there might be a problem with converting 01.01.2014 to DateTime at server side. Bear in mind you might be using a specific culture that plays a role in conversions and bindings.
To fix this, we can create a custom DateRangeAttribute. Here are the steps
1. Right click on the project name in solution explorer, and add "Common" folder.
2. Right click on the "Common" folder and add a class file with name = DateRangeAttribute.cs
3. Copy and paste the following code in DateRangeAttribute.cs class file.
using System;
using System.ComponentModel.DataAnnotations;
namespace MVCDemo.Common
{
public class DateRangeAttribute : RangeAttribute
{
public DateRangeAttribute(string minimumValue)
: base(typeof(DateTime), minimumValue, DateTime.Now.ToShortDateString())
{
}
}
}
Finally decorate "HireDate" property with our custom DateRangeAttribute as shown below. Notice that, we are only passing the minimum date value. Maximum date value will be today's date. Please note, DateRangeAttribute is present in MVCDemo.Common namespace.
[DateRange("01/01/2000")]
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
public DateTime HireDate { get; set; }

submit a list become null in the post + MVC

I have a ViewModel:
public class RegistrationViewModel
{
public string Country { get; set; }
public ConfigurationParamValue CountryParam { get; set; }
public string Civility { get; set; }
public ConfigurationParamValue CivilityParam { get; set; }
[FirstNameValidator(Category = "Registration", IsLocal = false )]
public string FirstName { get; set; }
public ConfigurationParamValue FirstNameParam { get; set; }
[LastNameValidator(Category = "Registration", IsLocal = false)]
public string LastName { get; set; }
public List<int> Days { get; set; }
public int SelectedDay{ get; set; }
public List<Month> Months { get; set; }
public Month SelectedMonth { get; set; }
public List<int> Years { get; set; }
public int SelectedYear { get; set; }
public DateTime BirthDate { get; set; }
}
I create a view with this viewmodel :
#model Registration.Front.Web.Models.RegistrationViewModel
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>RegistrationViewModel</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Country)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Country)
#Html.ValidationMessageFor(model => model.Country)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Civility)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Civility)
#Html.ValidationMessageFor(model => model.Civility)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.FirstName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.FirstName)
#Html.ValidationMessageFor(model => model.FirstName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.LastName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.LastName)
#Html.ValidationMessageFor(model => model.LastName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.BirthDate)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.SelectedDay, new SelectList(Model.Days))
#Html.ValidationMessageFor(model => model.BirthDate)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Occupation)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Occupation)
#Html.ValidationMessageFor(model => model.Occupation)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ZipCode)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ZipCode)
#Html.ValidationMessageFor(model => model.ZipCode)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Email)
#Html.ValidationMessageFor(model => model.Email)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Password)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.CGV)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.CGV)
#Html.ValidationMessageFor(model => model.CGV)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Optin)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Optin)
#Html.ValidationMessageFor(model => model.Optin)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.CNIL)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.CNIL)
#Html.ValidationMessageFor(model => model.CNIL)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
this is My contoller:
public ActionResult Index()
{
List<int> listDays = new List<int>(){1, 2, 3};
return View(new RegistrationViewModel() { Days=listDays });
}
[HttpPost]
public ActionResult Index( RegistrationViewModel rvm)
{
if (ModelState.IsValid)
{ return RedirectToAction("Welcome"); }
return View(rvm);
}
public ActionResult Welcome()
{
return View();
}
My problem is in the post, the property Days of the viewmodel is null!!!!! How can i correct this?
in your View you are not rendering Days inside form
Render hidden fields inside form with name="Days" like
foreach(var day in #Model.Days)
{
<input type="hidden" name="Days" />
}
copy the above code and paste it after
<div class="editor-field">
#Html.EditorFor(model => model.CNIL)
#Html.ValidationMessageFor(model => model.CNIL)
</div>
Now,when you submit, the Days values will also submitted to the Post method and you will get values in Days List.

Resources