asp.net mvc 3 Remote validation problem - asp.net-mvc

This is my Model :
[Required(ErrorMessage = "Email required!")]
[Remote("EmailExists","User",ErrorMessage = "Email already")]
public virtual string Email { get; set; }
View :
#Html.TextBoxFor(x => x.Email)
#Html.ValidationMessageFor(x => x.Email)
Controller:
public ActionResult EmailExists(string Email)
{
return Json(!Email.Equals("teste#gmail.com"),
JsonRequestBehavior.AllowGet);
}
jquery.validate.min.js and jquery.validate.unobtrusive.min.js are added. And web.config is configured as well.
When I type on Email input it fires EmailExists fine. Returns true/false as well. But it nevers shows the ErrorMessage
And I get this error :
Erro: uncaught exception:
[Exception... "Cannot modify properties of a WrappedNative"
nsresult: "0x80570034 (NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN)"
location: "JS frame :: chrome://global/content/bindings/autocomplete.xml ::
onxblpopuphiding :: line 848" data: no]
Any idea?

There is nothing in your description that supposes a problem. I've created a new ASP.NET MVC 3 application using the default template, added the model:
public class MyViewModel
{
[Required(ErrorMessage = "Email required!")]
[Remote("EmailExists", "Home", ErrorMessage = "Email already")]
public string Email { get; set; }
}
updated the HomeController:
public class HomeController: Controller
{
public ActionResult Index()
{
return View(new MyViewModel());
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
return View(model);
}
public ActionResult EmailExists(string Email)
{
return Json(
!Email.Equals("teste#gmail.com"),
JsonRequestBehavior.AllowGet
);
}
}
and the ~/Views/Home/Index.cshtml view:
#model AppName.Models.MyViewModel
<script type="text/javascript" src="#Url.Content("~/scripts/jquery.validate.min.js")"></script>
<script type="text/javascript" src="#Url.Content("~/scripts/jquery.validate.unobtrusive.min.js")"></script>
#using (Html.BeginForm())
{
#Html.LabelFor(x => x.Email)
#Html.TextBoxFor(x => x.Email)
#Html.ValidationMessageFor(x => x.Email)
<input type="submit" value="OK" />
}
Validation fires fine and correct error messages are shown (tested with Chrome 10.0, IE9 and FireFox 4.0). So the question now is how does your scenario differs than this one?

You just need to do this:
[Required(ErrorMessage = "Email required!")]
[Remote("EmailExists","User")]
public virtual string Email { get; set; }
and
public JsonResult EmailExists(string Email)
{
string errorMessage = "Email already";
if (!Email.Equals("teste#gmail.com"))
return Json(true, JsonRequestBehavior.AllowGet);
return Json(errorMessage, JsonRequestBehavior.AllowGet);
}

Related

How to use login and registration views in a single page?

I am getting an issue. While using Login and Registration views in a single page. When main view page loaded. I got an error pop up:
You are using dublicating email & password.
Dublicating email & password may lead to big mess.
Please note that it says dublicating not duplicating.
Have any one help me. My code is below.
My Modal is:
public class LoginViewModel {
public string Email { get; set; }
public string Password { get; set; }
}
public class RegisterViewModel {
public string Email { get; set; }
[DataType(DataType.Password)]
public string Password { get; set; }
}
public class RegisterLoginViewModel
{
public LoginViewModel LoginViewModel { get; set; }
public RegisterViewModel RegisterViewModel { get; set; }
}
My Controller:
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
var model = new RegisterLoginViewModel();
model.LoginViewModel = new LoginViewModel();
model.RegisterViewModel = new RegisterViewModel();
ViewBag.ReturnUrl = returnUrl;
return View(model);
}
Main View:
#model OpenOrderFramework.Models.RegisterLoginViewModel
#Html.Partial("_RegisterForm", Model.RegisterViewModel
#Html.Partial("_LoginForm", Model.LoginViewModel)
Partial View _LoginForm:
#model OpenOrderFramework.Models.LoginViewModel
#using (Html.BeginForm("Login", "Account", FormMethod.Post))
{ #Html.TextBoxFor(x => x.Email)
#Html.PasswordFor(x => x.Password)
<input type="submit" value="Log In" />
}
Partial View _RegisterForm:
#model OpenOrderFramework.Models.RegisterViewModel
#using (Html.BeginForm("Register", "Account", FormMethod.Post))
{
#Html.TextBoxFor(x => x.Email)
#Html.PasswordFor(x => x.Password)
<input type="submit" value="Register" />
}
Have you tried to rename your properties Email and Password from either or both of the RegisterViewModel and LoginViewModel? It's possible that is causing the problem.

"Required" attribute not working when "AllowHtml" attribute is used. MVC 5

I want to post a html with a wysiwyg editor so I used [AllowHtml] attribute on my property. It works, but when I use it with [Required] and [StringLength] attributes, it stops working. ModelState.IsValid returns true even if prop is empty.
Yes, I know I can manually control it if it is null and add an error to ModelState, but why?
Why this happens? Is there a better way to post some HTML code to back-end?
My dto:
public int Id { get; set; }
[Required(ErrorMessage = CErr.RequiredField)]
[StringLength(100, ErrorMessage = CErr.Min5Max100)]
[MinLength(5, ErrorMessage = CErr.Min5Max100)]
public string Name { get; set; }
[AllowHtml]
[Required(ErrorMessage = CErr.RequiredField)]
[StringLength(4000, ErrorMessage = CErr.TooLongValue)]
public string HtmlBody { get; set; }
My action:
[Route("new")]
[HttpPost]
public ActionResult NewMessageLayout(ManageMessageLayoutDto model)
{
if (ModelState.IsValid)
{
var response = Repositories.MessageLayoutRepository.SaveMessageLayout(model, CurrentUser.Id);
if (response.Status == ResultStatus.Success)
{
return RedirectToAction("MessageManagement");
}
else
{
ModelState.AddModelError("error", response.Message);
return View("ManageMessageLayout", model);
}
}
return View("ManageMessageLayout", model);
}
And some HTML:
#using (Html.BeginForm())
{
#Html.HiddenFor(m => m.Id)
<label>Name <span class="req">*</span></label>
#Html.TextBoxFor(m => m.Name, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Name, null, new { #class = "label label-danger" })
<label>Content <span class="req">*</span></label>
#Html.TextBoxFor(m => m.HtmlBody)
#Html.ValidationMessageFor(m => m.HtmlBody, null, new { #class = "label label-danger" })
<input class="btn btn-success btn-block btn-lg" type="submit" value="#(editing ? "Save" : "Add")" />
}
I am unable to replicate your error. However, I did notice a few things. First, according to the ckEditor documentation, textbox is not a valid attaching point for the editor. You should use textarea.
CkEditor Developer Documentation
At this point any textarea, p, or div element can be transformed into
a rich text editor by using the ckeditor() method.
Next, notice that I added AllowEmptyStrings=false to the [Required( attribute. This may be the important piece you are missing (will test without) - Testing seems to indicate that not setting AllowEmptyStrings does not impact the results of this test setup as the default value for this property is false. The model was still invalid.
Setup
VS 2015, MVC 5.2.2, .NET 4.5.1, jQuery 1.10.2, ckEditor 3.6.4
View Model
public class TestViewModel
{
[AllowHtml]
[Required(AllowEmptyStrings = false, ErrorMessage = "This should be filled out")]
[StringLength(4000, ErrorMessage="Its too big")]
public string HtmlBody { get; set; }
}
Controller Actions
public ActionResult About()
{
return View(new TestViewModel());
}
[HttpPost]
public ActionResult About(TestViewModel model)
{
if (!ModelState.IsValid) throw new Exception();
var test = model.HtmlBody;
return RedirectToAction("Contact");
}
View
#model WebApplication6.Models.TestViewModel
#{
ViewBag.Title = "About";
}
<h2>Test of HTML</h2>
#using (Html.BeginForm())
{
<label>Content <span class="req">*</span></label>
#Html.TextAreaFor(m => m.HtmlBody)
#Html.ValidationMessageFor(m => m.HtmlBody, null, new { #class = "label label-danger" })
<input type ="submit" value="test on server"/>
}
#section scripts
{
<script type="text/javascript">
$(function () {
$('#HtmlBody').ckeditor();
});
</script>
}
Results:
Basically, the exception was thrown because the model state was invalid
I found the problem.
My presentation layer was using 5.2.2.0 version of System.Web.Mvc but repository layer was using 5.2.3.0. I downgraded this to 5.2.2.0. And now it is working normally.

MVC Required Field not Working

Title says it all, can anyone spot what I'm doing wrong. I've tried moving around my HTMlValidation Summary and a bunch of other things. I feel like it may have something to with the views I am returning from my Controller Class.
-- Model
public class Login
{
[Required(ErrorMessage = "First Name is required")]
[Display(Name = "First Namex")]
public string FirstName { get; set; }
[Required(ErrorMessage = "Password is required")]
[DataType(DataType.Password)]
[Display(Name = "Passwordx")]
public string Password { get; set; }
}
-- Controller
[HttpPost]
public ActionResult Login(string FirstName, string Password)
{
if (ModelState.IsValid)
{
bool validLogin = new UserBAL().ValidateUser(FirstName, Password);
{
if (validLogin == true)
{
return RedirectToAction("Index", "Invoice");
}
else
{
return RedirectToAction("Index");
// ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
}
return View();
}
--View
#using (Html.BeginForm("Login", "Home"))
{ #Html.ValidationSummary(true)
<div>
<fieldset>
<legend>Login</legend>
<div class ="fields">
#Html.LabelFor(u => u.FirstName)
</div>
#Html.TextBoxFor(u => u.FirstName)
#Html.ValidationMessageFor(u => u.FirstName) <br />
<div class ="fields">
#Html.LabelFor(u => u.Password)
</div>
#Html.PasswordFor(u => u.Password) <br />
<input type="submit" value="Log In" />
</fieldset>
</div>
}
[HttpPost]
public ActionResult Login(EIAS.Models.Login login)
{
if (ModelState.IsValid)
{
bool validLogin = new UserBAL().ValidateUser(login);
{
if (validLogin == true)
{
return RedirectToAction("Index", "Invoice");
}
else
{
return RedirectToAction ("Index");
// ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
}
return View();
}
MVC in if (ModelState.IsValid) validate the model, and you don't receive the model in your action:
public ActionResult Login(string FirstName, string Password)
change the parameters of the action to:
public ActionResult Login(Login model)
and, for validate in the client, check if:
if you include jquery validate plugin (js)
check your web.config, keys ClientValidationEnabled and UnobtrusiveJavaScriptEnabled ir are in true.
check this link
You have to take the Model as the parameter to your Login action
public ActionResult Login()
{
// This will return the view with the form that you have above
return View();
}
[HttpPost]
public ActionResult Login(Login login)
{
// this is what your form will post too
if (ModelState.IsValid)
{
bool validLogin = new UserBAL().ValidateUser(login.FirstName, login.Password);
{
if (validLogin == true)
{
return RedirectToAction("Index", "Invoice");
}
else
{
return RedirectToAction("Index");
// ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
}
return View();
}
In the View just have
#using (Html.BeginForm())
Here is a link about MVC Razor Forms: http://blog.michaelckennedy.net/2012/01/20/building-asp-net-mvc-forms-with-razor/
Try that.
The problem was with my Views and which views I was returning. I was trying to use my Index view for validation, I hadn't created a Login View, so once I did that and added my validation to the Login View it worked. So in my question, Return View() wasn't really returning anything

MVC not pulling through validation

I have the following View code:
#using (Html.BeginForm("Login", "Press", FormMethod.Post))
{
<fieldset>
<legend>User Registration</legend>
<div>
#Html.TextBoxFor(model => model.FullName)
#Html.ValidationMessageFor(model => model.FullName)
</div>
<div>
#Html.TextBoxFor(model => model.Company)
#Html.ValidationMessageFor(model => model.Company)
</div>
<div>
#Html.TextBoxFor(model => model.EmailAddress)
#Html.ValidationMessageFor(model => model.EmailAddress)
</div>
<div>
#Html.CheckBoxFor(model => model.JoinMailingList)
Please check this box to recieve a seasonal look book pdf and monthly newsletter
</div>
<p>
<input type="submit" value="Proceed" />
</p>
</fieldset>
}
And here is my Model:
public class UserViewModel
{
[Required(ErrorMessage = "Please enter your name.")]
[MaxLength(100)]
public string FullName { get; set; }
[Required(ErrorMessage = "Please enter the name of your company.")]
[MaxLength(50)]
public string Company { get; set; }
[Required(ErrorMessage = "Please enter your email.")]
[DataType(DataType.EmailAddress)]
[RegularExpression(#"^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+#((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}$", ErrorMessage = "Please enter a valid email address.")]
[MaxLength(255)]
public string EmailAddress { get; set; }
public bool JoinMailingList { get; set; }
}
The problem is that when I click on the 'Proceed' button, none of the validation occurs. It just posts the action with no validation performed on it? Do I have to perform this inside the Controller?
Here is my Controller code:
public class PressController : Controller
{
//
// GET: /Press
public ViewResult Index()
{
return View();
}
//
// GET: /Press/Login
public ViewResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(UserViewModel userViewModel)
{
return RedirectToAction("Index", "Press");
}
}
Make sure that the action you are posting to takes the view model as argument:
[HttpPost]
public ActionResult Press(UserViewModel model)
{
// at this stage the validation has been performed during
// the process of model binding and now you could look in the
// modelstate if the model is vaild:
if (!ModelState.IsValid)
{
// validation failed => redisplay the view so that the user
// can fix his errors.
// Note that calling ModelState.IsValid doesn't trigger any validation
return View(model);
}
// at this stage we know that validation passed => we could do some processing
// and redirect
return RedirectToAction("Success");
}
or some people also use the TryUpdateModel method which also allows you to perform model binding which triggers the validation:
[HttpPost]
public ActionResult Press()
{
var model = new UserViewModel();
// validation will be triggered at this stage and the method
// will return true or false based on the result of this validation
if (!TryUpdateModel(model))
{
// validation failed => redisplay the view so that the user
// can fix his errors.
return View(model);
}
// at this stage we know that validation passed => we could do some processing
// and redirect
return RedirectToAction("Success");
}
And if you want to enable client side validation, just make sure that the following 2 scripts are referenced in your page:
<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>
Do you have the client-validation enabled?
See "Step 3: Enabling Client-side Validation" in ScottGu's post
In the server side you must check is the model valid using
ModelState.IsValid

DisplayAttribute turns off validation message

So when I have a DisplayAttribute decorating a property in one of my models...
[Required, Display(Name = "Some Name")]
public string SomeProperty { get; set; }
I no longer get a validation message for the field when using the ValidationMessageFor helper
#Html.ValidationMessageFor(model => model.SomeProperty)
And what's odd is if I use the overload that specifies a message, I still don't get the message. Anyone know what's going on here?
Unable to repro.
Model:
public class MyViewModel
{
[Required, Display(Name = "Some Name")]
public string SomeProperty { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel();
return View(model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
return View(model);
}
}
View:
#model MyViewModel
#using (Html.BeginForm())
{
#Html.LabelFor(x => x.SomeProperty)
#Html.EditorFor(x => x.SomeProperty)
#Html.ValidationMessageFor(x => x.SomeProperty)
<input type="submit" value="OK" />
}
When the form is submitted the validation error message is correctly shown if the field is left blank.

Resources