Remote Validation working elsewhere - asp.net-mvc

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.

Related

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.

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.

Override Default MVC Editor Templates Not Working

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.

ValidationMessageFor for different object

I'm using mvc4, in my view I have a declaration
#model IEnumerable<UserDisplay>
on the same view I want to have a Form with "create" post for different object type name "Review"
how can I use the EditorFor and ValidationMessageFor ? cause model is of different type.
this is not working
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Review</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Info)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Info)
#Html.ValidationMessageFor(model => model.Info)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.FromId)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.FromId)
#Html.ValidationMessageFor(model => model.FromId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ToId)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ToId)
#Html.ValidationMessageFor(model => model.ToId)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
Create a partial view for that form that uses the #model declaration of the required type then use #Html.Partial("mySubFormView"). Don't mix model types in your views, it makes life too complicated.
You can use a view model containing both objects.
public class MyViewModel
{
public IEnumerable<UserDisplay> { get; set; }
public Review Review { get; set; }
}
Then your model declaration in the view becomes:
#model TheNamespace.For.MyViewModel
Which will allow you to use #Html.EditorFor and #Html.ValidationMessageFor helpers.

DateTime required in ModelState, however never set to be

I have a DateTime field in my form. For whatever reason, everytime I submit the form ModelState comes back as invalid and a message that my date time field (called PostDate) is required, even though in the view model I don't have the required attribute set.
Does anyone know why this would be happening as I'm going around in circles trying to figure it out.
Here is the view model
public class BlogViewModel
{
[Required]
public string Title { get; set; }
[Required]
public string Content { get; set; }
public bool Published { get; set; }
public DateTime PostDate { get; set; }
}
Here is the controller actions
public ActionResult Create()
{
return View();
}
//
// POST: /Admin/Blog/Create
[HttpPost]
[ValidateInput(false)]
public ActionResult Create(BlogViewModel model)
{
if(ModelState.IsValid)
{
model.Content = HtmlSanitizer.SanitizeHtml(model.Content);
Services.BlogService.CreateBlogPost(model.Title, model.Content, User.Identity.Name);
return RedirectToAction("Index");
}
return View(model);
}
Here is the View
#using Payntbrush.Infrastructure.Mvc.Extensions
#model Payntbrush.Presentation.Demo.MVC3.Areas.Admin.Models.BlogViewModel
#Html.Resource(Html.ScriptTag("Areas/Admin/js/plugins/wysiwyg/jquery.wysiwyg.js"), ResourceType.Js)
<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>
#using (Html.BeginForm((string)ViewBag.Action, "Blog", FormMethod.Post, new { Id = "BlogEditor" }))
{
#Html.ValidationSummary(true)
<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.TextAreaFor(model => model.Content, new { #class = "wysiwyg blog-editor" })
#Html.ValidationMessageFor(model => model.Content)
</div>
<div class="editor-label">
Time of post (Only set this if you want to make a post appear to have been published at a different date.)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.PostDate, new{#class="datetimepicker"})
#Html.ValidationMessageFor(model => model.PostDate)
</div>
<div class="editor-label">
Published (Check to make this post live on the site)
</div>
<div class="editor-field">
#Html.CheckBoxFor(model => model.Published)
#Html.ValidationMessageFor(model => model.Published)
</div>
<p>
<input class="large awesome" type="submit" value="Create" />
#Html.ActionLink("Cancel", "Index", "Blog", null, new { #class = "large awesome cancel-button" })
</p>
}
<div>
</div>
If you leave the corresponding field empty your model will be invalid because DateTime is a value type. You should use a nullable DateTime if you want to allow empty values:
public DateTime? PostDate { get; set; }

Resources