MVC Two Class Within One Model Conflict while Saving data - asp.net-mvc

My Code is as shown in below
MODEL
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyProject.Models
{
[Table("UserMaster")]
public partial class UserMaster
{
[Key]
public int UserID { get; set; }
[System.Web.Mvc.Remote("doesAlreadyExist", "User", HttpMethod = "POST", ErrorMessage = "User Number already exists. Please enter a different Number.")]
[Required(ErrorMessage = "Enter Personal No")]
[Display(Name = "User No")]
[StringLength(10)]
public string User No{ get; set; }
[Required(ErrorMessage = "Enter Password")]
[Display(Name = "Password")]
public string Password { get; set; }
[NotMapped]
[Compare("Password", ErrorMessage = "Password doesn't match.")]
[Display(Name = "Confirm Password")]
public string CPassword { get; set; }
}
public class UserChangePassMV
{
[Required]
[Display(Name = "Old Password")]
[DataType(DataType.Password)]
public string OldPassword { get; set; }
[Required]
[Display(Name = "New Password")]
[DataType(DataType.Password)]
public string NewPassword { get; set; }
[NotMapped]
[Display(Name = "Confirm Password")]
[DataType(DataType.Password)]
[Compare("NewPassword",ErrorMessage="Password Doesnt Match in User Change Password.")]
public string ConfirmPassword { get; set; }
}
public class ChangeAvatar
{
public byte[] Photo { get; set; }
public string ImgSrc { get; set; }
}
}
CONROLLER
[OutputCache(Duration = 10, VaryByParam = "none", Location = OutputCacheLocation.Client, NoStore = true)]
public ActionResult ChangeAvatar()
{
ChangeAvatar avatar = new Models.ChangeAvatar();
int uid = Convert.ToInt32(Session.GetDataFromSession<CommonUserSession>("CommonUserSession").UserID);
avatar.Photo = db.UserMasters.SingleOrDefault(x => x.UserID == uid).Photo;
if (avatar.Photo != null)
{
string imageBase64 = Convert.ToBase64String(avatar.Photo);
avatar.ImgSrc = string.Format("data:image/jpeg;base64,{0}", imageBase64);
}
return View("ChangeAvatar", "_Layout", avatar);
}
[HttpPost]
public ActionResult ChangeAvatar(HttpPostedFileBase file)
{
if (file == null)
{
ModelState.AddModelError("", "Select image to upload");
}
int uid = Convert.ToInt32(Session.GetDataFromSession<CommonUserSession>("CommonUserSession").UserID);
UserMaster Mem = db.UserMasters.SingleOrDefault(x => x.UserID == uid);
try
{
if (ModelState.IsValid)
{
string path = System.IO.Path.Combine(Server.MapPath("~/ProfileImg"), uid.ToString() + ".jpg");
// file is uploaded
file.SaveAs(path);
using (MemoryStream ms = new MemoryStream())
{
file.InputStream.CopyTo(ms);
byte[] array = ms.GetBuffer();
Mem.Photo = array;
}
db.SaveChanges();
return RedirectToAction("ChangeAvatar");
}
}
catch (DbEntityValidationException ex)
{
var errorMessages = ex.EntityValidationErrors
.SelectMany(x => x.ValidationErrors)
.Select(x => x.ErrorMessage);
var fullErrorMessage = string.Join("; ", errorMessages);
var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);
HtmlHelperExtensions.LogError(ex);
throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
}
catch (RetryLimitExceededException /* dex */)
{
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
}
ChangeAvatar avatar = new Models.ChangeAvatar();
avatar.Photo = db.UserMasters.SingleOrDefault(x => x.UserID == uid).Photo;
if (avatar.Photo != null)
{
string imageBase64 = Convert.ToBase64String(avatar.Photo);
avatar.ImgSrc = string.Format("data:image/jpeg;base64,{0}", imageBase64);
}
return View(avatar);
}
VIEW
#model MyProject.Models.ChangeAvatar
#{
ViewBag.Title = "Change Avatar";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<!-- BEGIN PAGE BAR -->
#section PageBreadcrumb{
<ul class="breadcrumb">
<li><i class="icon-home2 position-left"></i> Dashboard</li>
<li class="active">Change Avatar</li>
</ul>
}
<!-- END PAGE BAR -->
<div class="clearfix"></div>
#section PageJS{
<script type="text/javascript" src="~/assets/js/plugins/uploaders/fileinput.min.js"></script>
<script type="text/javascript" src="~/assets/js/pages/uploader_bootstrap.js"></script>
<script type="text/javascript">
if ('#ViewBag.Status' != "") {
var notice = new PNotify({
title: '#ViewBag.Status',
text: '#ViewBag.Msg',
addclass: 'bg-#ViewBag.Type' //primary,info,danger,success,warning
}).get().click(function () {
notice.remove(); //Click to remove
});
}
</script>
}
#using (Html.BeginForm("ChangeAvatar", "User", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary()
<div class="panel panel-flat">
<div class="panel-heading">
<h5 class="panel-title text-primary">Change Avatar</h5>
<div class="heading-elements">
<ul class="icons-list">
<li><a data-action="collapse"></a></li>
#*<li><a data-action="reload"></a></li>
<li><a data-action="close"></a></li>*#
</ul>
</div>
</div>
<div class="panel-body">
<div class="col-md-12">
<div class="form-group">
<label class="col-lg-2 control-label text-semibold">Avatar:</label>
<div class="col-lg-10">
<input type="file" name="file" class="file-input-custom" data-show-caption="true" data-show-upload="true" accept="image/*">
<span class="help-block">Show only image files for selection & preview.</span>
</div>
</div>
<div class="col-lg-12">
<div class="text-right">
<p>
<div class="text-right">
#*<button type="submit" class="btn btn-primary">Change <i class="icon-arrow-right14 position-right"></i></button>*#
</div>
</p>
</div>
</div>
</div>
</div>
</div>
}
Now while I am trying to save the data in Change Avatar it shows error of first model for
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details. The validation errors are: Password doesn't match.
If i remove Compare part than it works, but i need that compare to confirm password
is this possible to work with two class like this?
Help me out I am stuck here.

Your UserMaster class has a CPassword property which will be set to null when you do db.UserMasters.SingleOrDefault(x => x.UserID == uid). You update Photo field and save the entity. db.SaveChanges(); triggers validation on your entity which is comparing password field values producing the exception. Both MVC and EF use data annotation attributes for validation. EF reads an attribute designed for presentation layer.
Think why do you need a CPassword field in your model class? It is not stored in the database. It is needed only to capture user input. Usually this is so-called viewModel class responsibility. In order to resolve the issue split UserMaster into separate classes.
public partial class UserMaster
{
[Key]
public int UserID { get; set; }
[Required]
[Display]
[StringLength(10)]
public string UserNo { get; set; }
[Required]
public string Password { get; set; }
}
public class UserMasterViewModel
{
public int UserID { get; set; }
[System.Web.Mvc.Remote("doesAlreadyExist", "User", HttpMethod = "POST", ErrorMessage = "User Number already exists. Please enter a different Number.")]
[Required(ErrorMessage = "Enter Personal No")]
[Display(Name = "User No")]
[StringLength(10)]
public string UserNo{ get; set; }
[Required(ErrorMessage = "Enter Password")]
[Display(Name = "Password")]
public string Password { get; set; }
[Compare("Password", ErrorMessage = "Password doesn't match.")]
[Display(Name = "Confirm Password")]
public string CPassword { get; set; }
}
Use UserMasterViewModel as a #model of your views. Perform dbModel <=> viewModel mappings in you controller methods.

Related

how to pass parameter to controller from viewpage in mvc

please help me.
i can not bind the input parameter from textbox in to actionmethod
Controller code:
public ActionResult CheckUser(string empCode) // ActionMethod with parameter
{
try
{
string res = "";
DataSet dataSet = new DataSet();
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
using (SqlCommand command = new SqlCommand("spUserCheck"))
{
command.Parameters.AddWithValue("#UserCode", empCode);
command.CommandType = CommandType.StoredProcedure;
connection.Open();
command.Connection = connection;
SqlDataAdapter dataAdapter = new SqlDataAdapter();
dataAdapter.SelectCommand = command;
dataAdapter.Fill(dataSet);
connection.Close();
}
}
if (dataSet.Tables.Count > 0)
{
res = "Alredy Avilable";
}
else
{
res = "Not Avilable. Please create user";
}
return View(res) ;
}
catch (Exception ex)
{
throw new Exception("Error ", ex);
}
}
ViewCode:-
<div class="form-group">
<label class="control-label col-sm-2">Employee Code <span class="mandatory"></span>:</label>
<div class="col-sm-3">
<input type="text" class="form-control input-md" id="empCode" placeholder="Enter employee code" />
</div>
<div class="col-sm-2">
<input type="button" class="btn btn-info" onclick="location.href='#Url.Action("CheckUser", "User")'" id="btnAvaiaable" value="Check Availability ?" />
</div>
</div>
ModelCode
public class UserParameter
{
public string empCode { get; set; }
public string Role { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string EmailID { get; set; }
public int MobileNo { get; set; }
public string Zone { get; set; }
public string State { get; set; }
public string Branch { get; set; }
public string CompanyType { get; set; }
}
First issue is you need a textbox with attribute name="empCode".
Second, you need to wrap the textbox in a form element.
Third, you need to post to the controller. Just changing the location in a button click (as you are doing) will do a get with no form data attached.
There are plenty of samples online which show this.

Adding a dropdown of Departments in the in Register.cshtml and retrieving its selected value in the Reginster action method [duplicate]

This question already has answers here:
The ViewData item that has the key 'XXX' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'
(6 answers)
Closed 5 years ago.
In my Asp:Net MVC project I want to add departments to the Registerform. When I try to register a user I get this error
There is no ViewData item of type 'IEnumerable' that
has the key 'DepartmentId'.
and I think it's something to do with my Register action.
This is my Department class in my Model
public class Department
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int DepartmentId { get; set; }
[Required]
[MaxLength(50)]
public string DepartmentName { get; set; }
}
Then I added this two properity to RegisterViewModel
public int DepartmentId { get; set; }
public Department Department { get; set; }
Looks like this below..
public class RegisterViewModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
public string FirstName { get; set; }
[ForeignKey("Department")]
public int DepartmentId { get; set; }
public Department Department { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
Then In my Register action I dont know how to code it .. tried many kind of codes but don't know how to do it.
// Probably it's here the very problem , i think.
// GET: /Account/Register
[AllowAnonymous]
public ActionResult Register()
{
// Here inside.. I don't know how to do... ;)
ViewBag.DepartmentId = new SelectList(?????, "DepartmentId", "DepartmentName");
Or maybe:
ViewBag.DepartmentId = new IEnumerable<SelectListItem> .....;
return View();
}
// And this is what my Register looks like
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser {FirstName = model.FirstName, DepartmentId = model.DepartmentId, Email = model.Email };
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
......
And RegisterView
#model PersonRegister.Models.RegisterViewModel
....
<div class="form-group">
#Html.LabelFor(m => m.DepartmentId, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.DropDownList("DepartmentId", null, htmlAttributes: new { #class = "form-control" })
</div>
</div>
.....
... and here rest of view such as... email.....
Thank you in advance!
Example:
[AllowAnonymous]
public ActionResult Register()
{
ViewBag.DeptList = _context.Departments
.select(s=> new SelectListItem
{
Value=s.DepartmentId.ToString(),
Text=s.DepartmentName
}).ToList();//select data from determent table
return View();
}
View
#model PersonRegister.Models.RegisterViewModel
....
<div class="form-group">
#Html.LabelFor(m => m.DepartmentId, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.DropDownListFor(m => m.DepartmentId , new SelectList((IEnumerable)ViewBag.DeptList,"Value","Text",Model.DepartmentId ), new { #class = "form-control" })
</div>
</div>
OR
public class RegisterViewModel
{
Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
public string FirstName { get; set; }
public int? DepartmentId { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
[Ignore]
public List<SelectListItem> DepartmentList {get;set;}
}
[AllowAnonymous]
public ActionResult Register()
{
var model= new RegisterViewModel();
model.DepartmentList = _context.Departments
.select(s=> new SelectListItem
{
Value=s.DepartmentId.ToString(),
Text=s.DepartmentName
}).ToList();//select data from determent table
return View(model);
}
View
#model PersonRegister.Models.RegisterViewModel
....
<div class="form-group">
#Html.LabelFor(m => m.DepartmentId, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.DropDownListFor(m => m.DepartmentId ,Model.DepartmentList,"--Select--" ,new { #class = "form-control" })
</div>
</div>

MVC4 dropdownlist error

Based on this post
Second answerI tried to create a dropdown list for my register page.
Register page has a field where you can select the PossibleAccessRight for the user while registering him/her which should be saves in AccessRight Attribute.
Right now i can't even show the items in dropdownlist
My model looks like this
public class UserModel
{
public int UserId { get; set; }
[Required]
[EmailAddress]
[StringLength(100)]
[DataType(DataType.EmailAddress)]
[Display(Name = "Email ID ")]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
[StringLength(20,MinimumLength = 6)]
[Display(Name = "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]
[Display(Name = "Address ")]
public string Address { get; set; }
public List<string> PossibleRights;
[Required]
[Display(Name = "Access Rights")]
public string AccessRight { get; set; }
public UserModel()
{
PossibleRights = new List<string>()
{
{"High"},
{"Low"},
};
}
}
in controller i have this in registeration method which is httppost method
[HttpGet]
public ActionResult Register()
{
return View();
}
[HttpPost]
public ActionResult Register(Models.UserModel user)
{
var rights = new UserModel();
if (ModelState.IsValid)
{
using (var db = new DBaseEntities())
{
var crypto = new SimpleCrypto.PBKDF2();
var encrpPass = crypto.Compute(user.Password);
var sysUser = db.SystemUsers.Create();
sysUser.FirstName = user.FirstName;
sysUser.Email = user.Email;
sysUser.Password = encrpPass;
sysUser.PasswordSalt = crypto.Salt;
db.SystemUsers.Add(sysUser);
db.SaveChanges();
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("","Login data is incorrect.");
}
return View(rights);
}
View for this method looks like this
<div class="editor-label">#Html.LabelFor(u=> u.FirstName)</div>
<div class="editor-field"> #Html.TextBoxFor(u=> u.FirstName)</div>
<br/>
<div class="editor-label">#Html.LabelFor(u=> u.LastName)</div>
<div class="editor-field"> #Html.TextBoxFor(u=> u.LastName)</div>
<br/>
<div class="editor-label">#Html.LabelFor(u=> u.Address)</div>
<div class="editor-field"> #Html.TextBoxFor(u=> u.Address)</div>
<br/>
<div class="editor-label">#Html.LabelFor(u=> u.Email)</div>
<div class="editor-field"> #Html.TextBoxFor(u=> u.Email)</div>
<br/>
<div class="editor-label">#Html.LabelFor(u=> u.Password)</div>
<div class="editor-field"> #Html.PasswordFor(u=> u.Password)</div>
<br/>
<div class="editor-label">#Html.LabelFor(u=> u.AccessRight)</div>
<div class="editor-field"> #Html.DropDownListFor(u=> u.PossibleRights, new SelectList(Model.PossibleRights))</div>//error at this line(NullReference exception)
<br/>
<input type="submit" value="Register"/>
any idea what I'm doing wrong? Also, is my approach to show the items in dropdownlist good? Can you suggest better idea if any?
If you want to display any info on the view, you have to provide this info to the view first. Right now this code:
public ActionResult Register()
{
return View();
}
does not provide any info at all. Model for the view is created with default constructor, which means that model object is empty, therefore nothing is displayed on the view (particularly in the dropdown list). What you need is some initialization like this:
public ActionResult Register()
{
UserModel model = new UserModel();
model.PossibleRights = new List<string>{"Right1", "Right2", "Right3"};
// or go to db, or whatever
return View(model);
}
Besides dropdown returns selected value when posted, which is string representing a right in this case. So you need to introduce some field in the model to store the selection:
public class UserModel
{
...
public List<string> PossibleRights;
public string SelectedRight;
...
}
Usage on view is the following:
#Html.DropDownListFor(u => u.SelectedRight, new SelectList(Model.PossibleRights))

Validation not working in partial view

I have an Index page which has two partial views: login and register.I am using data model validation.
Login.cshtml
#model Project.ViewModel.UserModel
<div style="position:inherit;">
#using (Html.BeginForm("_Login", "account"))
{
#Html.ValidationSummary(true)
<div class="label">#Html.Label("Username")</div>
<div class="field">#Html.TextBoxFor(m => m.Username)</div>
<div class="error">#Html.ValidationMessageFor(model => model.Username)</div>
<div class="label">#Html.Label("Password")</div>
<div class="field">#Html.PasswordFor(m => m.Password)</div>
<div class="error">#Html.ValidationMessageFor(model => model.Password)</div>
<input class="field" id="submit" type="submit" value="Login" />
}
Register.cshtml
#model Project.ViewModel.UserModel
<link href="~/Content/Site.css" rel="stylesheet" />
<div style="position: inherit; margin-top: 20px">
#using (Html.BeginForm("_Register","account"))
{
<div class="label">#Html.Label("Name")</div>
<div class="field">#Html.TextBoxFor(m => m.FullName)</div>
<div class="error">#Html.ValidationMessageFor(model => model.FullName)</div>
<div class="label">#Html.Label("Username")</div>
<div class="field">#Html.TextBoxFor(m => m.Username)</div>
<div class="error">#Html.ValidationMessageFor(model => model.Username)</div>
<div class="label">#Html.Label("Password")</div>
<div class="field">#Html.PasswordFor(m => m.Password)</div>
<div class="error">#Html.ValidationMessageFor(model => model.Password)</div>
<div class="label">#Html.Label("Confirm Password")</div>
<div class="field">#Html.PasswordFor(m => m.ConfirmPassword)</div>
<div class="error">#Html.ValidationMessageFor(model => model.Password)</div>
<div class="label">#Html.Label("Email")</div>
<div class="field">#Html.TextBoxFor(m => m.Email)</div>
<div class="error">#Html.ValidationMessageFor(model => model.Email)</div>
<div class="label">#Html.Label("Country")</div>
<div class="field">#Html.TextBoxFor(m => m.Country)</div>
<div class="error">#Html.ValidationMessageFor(model => model.Email)</div>
<input class="field" id="submit" type="submit" value="Sign Up" />
#Html.ValidationSummary()
}
Index.cshtml
#model Project.ViewModel.UserModel
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div id="regiserandlogin">
<div id="registerandlogin-header">
<label style="margin-left:50px;">Sign Up For Free!!!</label>
<label style="margin-left:350px;color:#28a1e2">Already Have An Account?</label>
</div>
<div id="registerbox">
#Html.Partial("_Register", new ProjectHub.ViewModel.UserModel())
</div>
<div id="loginbox">
#Html.Partial("_Login", new ProjectHub.ViewModel.UserModel())
</div>
public ViewResult _Register()
{
return View("_Register");
}
[HttpPost]
public ActionResult _Register(UserModel usermodel)
{
if (!ModelState.IsValid)
{
return View("Index");
}
try
{
FormsAuthentication.SetAuthCookie(usermodel.Username, false);
return RedirectToAction("activationemail", new {username= Username});
}
catch (Exception ae)
{
ModelState.AddModelError("", ae.Message);
return View();
}
}
public ViewResult _Login()
{
return View("_Login");
}
[HttpPost]
public ActionResult _Login(string username, string password)
{
if (ModelState.IsValid)
{
if (MembershipService.ValidateUser(username, password))
{
if (!repository.IsVerified(username))
{
ModelState.AddModelError("","Account is not activated.;
return View();
}
FormsAuthentication.SetAuthCookie(username,false);
return RedirectToAction("Index","Home");
}
return RedirectToAction("Index", "account"); ;
}
else
{
ModelState.AddModelError("","Invalid Username/Password");
return View();
}
}
UserModel.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace ProjectHub.ViewModel
{
public class UserModel
{
[Required(ErrorMessage="Username is Required")]
public string Username { get; set; }
[Required(ErrorMessage = "Password is Required")]
public string Password { get; set; }
[Required(ErrorMessage = "Password is Required")]
public string ConfirmPassword { get; set; }
[Required(ErrorMessage = "Name is Required")]
public string FullName { get; set; }
[Required(ErrorMessage = "Email is Required")]
public string Email { get; set; }
[Required(ErrorMessage = "Country is Required")]
public string Country { get; set; }
}
}
When I press register button like this, I get a validation error
If I use RedirectToAction Method, I don't get the validation error.
Please advise me.
You should not use the same view model for both partials. You should have 2 different view models.
For example:
public class LoginViewModel
{
[Required(ErrorMessage="Username is Required")]
public string Username { get; set; }
[Required(ErrorMessage = "Password is Required")]
public string Password { get; set; }
}
and for the register partial:
public class RegisterViewModel
{
[Required(ErrorMessage="Username is Required")]
public string Username { get; set; }
[Required(ErrorMessage = "Password is Required")]
public string Password { get; set; }
[Required(ErrorMessage = "Password is Required")]
public string ConfirmPassword { get; set; }
[Required(ErrorMessage = "Name is Required")]
public string FullName { get; set; }
[Required(ErrorMessage = "Email is Required")]
public string Email { get; set; }
[Required(ErrorMessage = "Country is Required")]
public string Country { get; set; }
}
and then your main view model should aggregate those 2 view models:
public class MyViewModel
{
public LoginViewModel Login { get; set; }
public LoginViewModel Register { get; set; }
}
and then:
<div id="registerbox">
#Html.Partial("_Register", Model.Login)
</div>
<div id="loginbox">
#Html.Partial("_Login", Model.Register)
</div>
Add the following reference to the JQuery scripts in your View.
I went through the same situation and it solved my problem.
"~/Scripts/jquery.unobtrusive*"
"~/Scripts/jquery.validate*"

only show the errormessage when email is invalid

I work in ASP MVC3. I have a model for the input of the contact information of a customer.
The information is required. When the viewstat is not valid the textboxes must have a red border (this works) en no errormessage. But when the emailinput is invalid the the error must be visible on the view. So only the errormessage of the emailannotation must be visible and not of the requiredannotation. I have no idea how to do this.
model:
[Required]
public string FirstName { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Address { get; set; }
[Required]
public string PostalCode { get; set; }
[Required]
public string City { get; set; }
[Required]
public string Country { get; set; }
[Required]
public string PhoneNumber { get; set; }
public string Fax { get; set; }
[Required]
[Email]
public string Email { get; set; }
view:
<div class="row-fluid">
<div class="span6">
<div data-role="fieldcontain" class="ui-hide-label">
<label for=#Lingo.language.Obj_Telefoon>#Lingo.language.Obj_Telefoon</label>
<span>#Html.TextBoxFor(m => m.PhoneNumber, new { style = "width:90%!important;", placeholder = #Lingo.language.Obj_Telefoon })</span>
</div>
</div>
<div class="span6">
<div data-role="fieldcontain" class="ui-hide-label">
<label for=#Lingo.language.Obj_Fax>#Lingo.language.Obj_Fax</label>
<span>#Html.TextBoxFor(m => m.Fax, new { placeholder = #Lingo.language.Obj_Fax })</span>
</div>
</div>
</div>
<div class="row-fluid">
<div class="span12">
<div data-role="fieldcontain" class="ui-hide-label">
<label for=#Lingo.language.Obj_Email>#Lingo.language.Obj_Email</label>
<span>#Html.TextBoxFor(m => m.Email, new { style = "width:98%!important;", placeholder = #Lingo.language.Obj_Email })</span>
<span>#Html.ValidationMessageFor(m => m.Email)</span>
</div>
</div>
</div>
write with required message like this:
[Required( ErrorMessage = "The first name is required" )]
public string FirstName { get; set; }
If you want it to be required, but don't want to show the "required" error message, you could set the message to be a single space (to avoid the run-time error "Either ErrorMessageString or ErrorMessageResourceName must be set, but not both.")
[Required(ErrorMessage = " ")]
[Email(ErrorMessage = "Must be a valid email address.")]
public string Email { get; set; }
If you don't already have the Email attribute, you can create a class file (e.g. EmailAttribute.cs) containing:
using System.ComponentModel.DataAnnotations;
public class EmailAttribute: RegularExpressionAttribute {
public EmailAttribute()
: base(#"^[a-zA-Z0-9._%+-]+#[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$") { }
}

Resources