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}$") { }
}
Related
Can someone help Encrypt information according to the user's role?
Basically I want the following: if the User Role = "Admin" the mobile phone number (Telemovel) appears 435267456. If the User Role = "User" the number of the mobile phone appears (Telemovel) xxxxxxxxxx.
I have used this #if (User.IsInRole("Admin")) to hide links depending on the role and it works, now I want to encrypt the information.
Model
public partial class Cliente
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Cliente()
{
this.Reserva = new HashSet<Reserva>();
}
public int ID_Cliente { get; set; }
public string Nome { get; set; }
public string Morada { get; set; }
public string Telemovel { get; set; }
public string Email { get; set; }
public string Contribuinte { get; set; }
public string CartaoCidadao { get; set; }
public System.DateTime DataValidade { get; set; }
public System.DateTime DataNascimento { get; set; }
public System.DateTime DataRegisto { get; set; }
public string País { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Reserva> Reserva { get; set; }
}
View example
<div class="form-group">
<label class="col-md-4 control-label">Telemóvel</label>
<div class="col-md-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-earphone"></i></span>
<input name="Telemovel" class="form-control" type="text" value="#Model.Telemovel" readonly="readonly">
</div>
</div>
</div>
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.
I have trouble with sending value from view to controller. When I send a value like 35 it works but when I try to pass 35.00 I have validation message:
The value '125.50' is not valid for Cena.
When i try give 35,50 i get:
The field Cena must be a number.
Here is my view code
<div class="editor-label">
#Html.LabelFor(model => model.Cena)
</div>
<div>
#Html.TextBoxFor(model => model.Cena)
#Html.ValidationMessageFor(model => model.Cena)
</div>
<p>
<input type="submit" value="Dodaj" />
</p>
Model:
public partial class Czapki
{
public Czapki()
{
this.Zamowienie = new HashSet<Zamowienie>();
}
public int IdCzapki { get; set; }
[Required]
public string Model { get; set; }
[Required]
public int Ilosc { get; set; }
public decimal Cena { get; set; }
[Required]
public string Rodzaj { get; set; }
public bool Checked { get; set; }
public virtual ICollection<Zamowienie> Zamowienie { get; set; }
}
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*"
I am having a bugger of a time trying to figure out where I am going wrong. Scenario is this. Trying to add an object that has a foreign key in it with mvc entity framework.
public class Person
{
[Key]
public virtual int PersonId { get; set; }
[Display(Name = "First Name")]
[Required]
[MaxLength(50)]
public virtual string FirstName { get; set; }
[Display(Name = "Last Name")]
[Required]
[MaxLength(50)]
public virtual string LastName { get; set; }
[Required]
public virtual int TestItem { get; set; }
[Required(ErrorMessage = "Please Select an Employee Type")]
public virtual EmployeeType EmployeeTypeId { get; set; }
}
public class EmployeeType
{
[Key]
public virtual int EmployeeTypeId { get; set; }
[Required]
public virtual string EmployeeTypeName { get; set; }
}
Those are the two pocos for the entities.
public ActionResult Create()
{
PersonViewModel pv = new PersonViewModel();
ViewBag.EmployeeTypeSelect= new SelectList(db.EmployeeTypes, "EmployeeTypeId", "EmployeeTypeName");
return View(pv);
}
//
// POST: /Person/Create
[HttpPost]
public ActionResult Create(PersonViewModel personVM)
{
if (ModelState.IsValid)
{
Person person = new Person();
person.EmployeeTypeId = personVM.EmployeeTypeId;
person.FirstName = personVM.FirstName;
person.LastName = personVM.LastName;
person.TestItem = personVM.TestItem;
db.Persons.Add(person);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(personVM);
}
That is the controller.
#model MvcApplication3.Models.PersonViewModel
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>PersonViewModel</legend>
<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.TestItem)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.TestItem)
#Html.ValidationMessageFor(model => model.TestItem)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.EmployeeTypeId)
</div>
<div class="editor-field">
#Html.DropDownListFor(model=>model.EmployeeTypeId,(SelectList)ViewBag.EmployeeTypeSelect)
#Html.ValidationMessageFor(model => model.EmployeeTypeId)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
That is the view.
Everything works fine with the view off the initial get, but when I post the EmployeeTypeId has a null value. I check the source and the select list is fine, has proper values and text. Please help as I have no clue where i am going wrong.
Thanks
Try adding in Html.EndForm() in the HTML after all of the values you wish to post and see if that fixes the problem?
Your Person and EmployeeType class needs to have a default (empty) constructor for the model binding to work -
public class EmployeeType
{
[Key]
public virtual int EmployeeTypeId { get; set; }
[Required]
public virtual string EmployeeTypeName { get; set; }
public EmployeeType()
{
}
}
public class Person {
[Key]
public virtual int PersonId { get; set; }
[Display(Name = "First Name")]
[Required]
[MaxLength(50)]
public virtual string FirstName { get; set; }
[Display(Name = "Last Name")]
[Required]
[MaxLength(50)]
public virtual string LastName { get; set; }
[Required]
public virtual int TestItem { get; set; }
[Required(ErrorMessage = "Please Select an Employee Type")]
public virtual EmployeeType EmployeeTypeId { get; set; }
public Person()
{
EmployeeTypeId = new EmployeeType();
}
}
Also, try in your view, making it
#Html.DropDownListFor(model=>model.EmployeeTypeId.EmployeeTypeId,(SelectList)ViewBag.EmployeeTypeSelect)