I have created a simple project with login and verification. However, I don't know why I cannot use gmail to register the program. During I put my gmail account for registration, I will met this error.
System.Data.Entity.Infrastructure.DbUpdateException: 'An error occurred while updating the entries. See the inner exception for details.'
During testing this project, I have use hotmail account yao0529#live.com and gmail account yuky0529#gmail.com to register. The hotmail account is register success but gmail cannot. Both of the information for register are exactly same except email.
The code below is normal data class
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace Food_Founder.Models
{
[MetadataType(typeof(UserMetaData))]
public partial class User
{
public string ConfirmPassword { get; set; }
}
public class UserMetaData
{
[Display(Name = "First Name")]
[Required(AllowEmptyStrings = false, ErrorMessage = "This field is required")]
public string FirstName { get; set; }
[Display(Name = "Last Name")]
[Required(AllowEmptyStrings = false, ErrorMessage = "This field is required")]
public string LastName { get; set; }
[Display(Name = "Email ID")]
[Required(AllowEmptyStrings = false, ErrorMessage = "This field is required")]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
[Display(Name = "Date Of Birth")]
[DataType(DataType.Date)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
public Nullable<System.DateTime> DateOfBirth { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessage = "This field is required")]
[DataType(DataType.Password)]
[MinLength(8, ErrorMessage = "Minimum 8 characters or numbers are required")]
public string Password { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessage = "This field is required")]
[DataType(DataType.Password)]
[Compare("Password", ErrorMessage = "The password is not match")]
public string ConfirmPassword { get; set; }
}
}
and this is another normal data class
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Food_Founder.Models
{
using System;
using System.Collections.Generic;
public partial class User
{
public int UserID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public Nullable<System.DateTime> DateOfBirth { get; set; }
public string Password { get; set; }
public bool IsEmailVerified { get; set; }
public System.Guid ActivationCode { get; set; }
}
}
The picture below is my database details.
Below the code is my controller class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Web;
using System.Web.Mvc;
using Food_Founder.Models;
namespace Food_Founder.Controllers
{
public class UserController : Controller
{
//Registration
[HttpGet]
public ActionResult Registration()
{
return View();
}
//Post Registration
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Registration([Bind(Exclude = "IsEmailVerified,ActivationCode")]User user)
{
//Model Validation
bool Status = false;
string message = "";
if (ModelState.IsValid)
{
#region Email is already exist
var isExist = IsEmailExist(user.Email);
if (isExist)
{
ModelState.AddModelError("EmailExist", "Email already exist");
return View(user);
}
#endregion
#region Generate Activation Code
user.ActivationCode = Guid.NewGuid();
#endregion
#region Password Hashing
user.Password = Crypto.Hash(user.Password);
user.ConfirmPassword = Crypto.Hash(user.ConfirmPassword);
#endregion
user.IsEmailVerified = false;
#region Save Data to Database
using (myDatabaseEntities myDatabase = new myDatabaseEntities())
{
myDatabase.Users.Add(user);
myDatabase.SaveChanges();
//Send Email to User
SendVerificationLinkEmail(user.Email, user.ActivationCode.ToString());
message = "Registration successfully done. Account activation link" +
"has been send to your Email:" + user.Email + "Please go check and activate your account";
Status = true;
}
#endregion
}
else
{
message = "Invalid Request";
}
ViewBag.Message = message;
ViewBag.Status = Status;
return View(user);
}
//Verify Email
//Verify Email Link
//Login
//Login POST
//Logout
[NonAction]
public Boolean IsEmailExist(string email)
{
using (myDatabaseEntities myDatabase = new myDatabaseEntities())
{
var v = myDatabase.Users.Where(a => a.Email == email).FirstOrDefault();
return v != null;
}
}
[NonAction]
public void SendVerificationLinkEmail(string email, string activationCode)
{
var verifyUrl = "/User/VerifyAccount/" + activationCode;
var link = Request.Url.AbsoluteUri.Replace(Request.Url.PathAndQuery, verifyUrl);
var fromEmail = new MailAddress("yukwokyao2#gmail.com", "yukwokyao");
var toEmail = new MailAddress(email);
var fromEmailPassword = "********";
string subject = "Your account is successfully created!";
string body = "<br/><br/>We are excited to tell you that your FoodFounder account is" +
"successfully created. Please click the below link to verify your FoodFounder account" +
"<a href = '" + link + "' >" + link + "</a>";
var smtp = new SmtpClient
{
Host = "smtp.gmail.com",
Port = 587,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(fromEmail.Address, fromEmailPassword)
};
using (var message = new MailMessage(fromEmail, toEmail)
{
Subject = subject,
Body = body,
IsBodyHtml = true
})
smtp.Send(message);
}
}
}
And this is my database.
CREATE TABLE [dbo].[User] (
[UserID] INT IDENTITY (1, 1) NOT NULL PRIMARY KEY,
[FirstName] VARCHAR (50) NOT NULL,
[LastName] VARCHAR (50) NOT NULL,
[Email] VARCHAR (256) NOT NULL,
[DateOfBirth] DATE NULL,
[Password] NVARCHAR (MAX) NOT NULL,
[IsEmailVerified] BIT NOT NULL,
[ActivationCode] UNIQUEIDENTIFIER NOT NULL,
PRIMARY KEY CLUSTERED ([UserID] ASC)
);
GO
SET IDENTITY_INSERT [dbo].[User] ON
Here I met the new problem is when I set the auto-increment for database primary key, it show this error
SQL70001 this statement is not recognized in this context
This error is showed as there is a red line under the SET. Plus, I can't find any database script for set the BuildAction as None
Anywhere, if anything I miss put please inform me ya.. Thank you.
Related
So i seem to be getting this error when trying to insert more than one user into my ASP.NET SQL database. One user can register succesfully and their data shows in the database no problem, but for some reason multiple users gives me this problem.
Inner Exception 2:
SqlException: Violation of PRIMARY KEY constraint 'PK_Users'. Cannot insert duplicate key in object 'dbo.Users'. The duplicate key value is (0).
The statement has been terminated.
I've done some research on this problem and changed my database a lot to see if I could fix the problem, but so far nothing has worked. It would appear as if my UsersID isn't actually accending like it should be when a new user is added to the database through my registration page, just for reference, here is my SQL table code!
CREATE TABLE [dbo].[Users] (
[UserID] int NOT NULL Identity(1,1),
[FirstName] VARCHAR (50) NOT NULL,
[LastName] VARCHAR (50) NOT NULL,
[EmailID] VARCHAR (254) NOT NULL,
[DateOfBirth] DATETIME NULL,
[Password] NVARCHAR (MAX) NOT NULL,
[IsEmailVerified] BIT NOT NULL,
[ActivationCode] UNIQUEIDENTIFIER NOT NULL,
CONSTRAINT [PK_Users] PRIMARY KEY ([UserID])
);
Any idea what the problem I'm having is since I assumed setting an identity for my UserID primary key would solve the problem?
Thanks!
//Registration Action
[HttpGet]
public ActionResult Registration()
{
return View();
}
//Registration POST action
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Registration([Bind(Exclude ="IsEmailVerified, ActivationCode")]User user)
{
bool Status = false;
String message = "";
//Model Validation
if (ModelState.IsValid)
{
#region //Email already exists
var isExist = isEmailExist(user.EmailID);
if(isExist)
{
ModelState.AddModelError("EmailExist", "Email Already Exists");
return View(user);
}
#endregion
#region Generate Activation Code
user.ActivationCode = Guid.NewGuid();
#endregion
#region Password Hashing
user.Password = Crypto.Hash(user.Password);
user.ConfirmPassword = Crypto.Hash(user.ConfirmPassword); //
#endregion
user.IsEmailVerified = false;
#region Save Data To Database
using (MyDatabaseEntities1 dc = new MyDatabaseEntities1())
{
dc.Users.Add(user);
dc.SaveChanges();
//Send Email To User
SendVerificationLinkEmail(user.EmailID, user.ActivationCode.ToString());
message = "Registration Success!" + " " + "Account activation link" + "has been sent to your email id:" + user.EmailID;
Status = true;
}
#endregion
}
else
{
message = "Invalid Request";
}
ViewBag.Message = message;
ViewBag.Status = Status;
return View(user);
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace Store.Models
{
[MetadataType(typeof(UserMetadata))]
public partial class User
{
public string ConfirmPassword { get; set; }
}
public class UserMetadata
{
[Display(Name ="First Name")]
[Required(AllowEmptyStrings = false, ErrorMessage = "First name required")]
public string FirstName { get; set; }
[Display(Name = "Last Name")]
[Required(AllowEmptyStrings = false, ErrorMessage = "Last name required")]
public string LastName { get; set; }
[Display(Name = "Email ID")]
[Required(AllowEmptyStrings = false, ErrorMessage = "Email ID required")]
[DataType(DataType.EmailAddress)]
public string EmailID { get; set; }
[Display(Name = "Date of birth")]
[DataType(DataType.Date)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime DateOfBirth { get; set; }
[Required(AllowEmptyStrings =false, ErrorMessage ="Password is required")]
[DataType(DataType.Password)]
[MinLength(6, ErrorMessage ="Minimum 6 characters required")]
public string Password { get; set; }
[Display(Name = "Confirm Password")]
[DataType(DataType.Password)]
[Compare("Password", ErrorMessage = "Confirm password and password do not match")]
public string ConfirmPassword { get; set; }
}
}
your userId column is not nullabale and you are not sending any value into this column, by default is going as 0. and in the database its getting value to auto increment is not working. try this code and let me know.
#region Save Data To Database
using (MyDatabaseEntities1 dc = new MyDatabaseEntities1())
{
var maxUserId = dc.Users.Max(x=>x.UserId);
if(maxUserId !=null)
user.UserId = maxUserId + 1;
dc.Users.Add(user);
dc.SaveChanges();
//Send Email To User
SendVerificationLinkEmail(user.EmailID, user.ActivationCode.ToString());
message = "Registration Success!" + " " + "Account activation link" + "has been sent to your email id:" + user.EmailID;
Status = true;
}
#endregion
How do I test DataType.EmailAddress?
I have a Customer model with an Email property with the following data annotations to validate:
[StringLength(100)]
[DataType(DataType.EmailAddress, ErrorMessage = "Email must be a valid email address")]
[Display(Name = "Email")]
[Required(ErrorMessage = "Email is required")]
public string email { get; set; }
I am writing unit tests to test validations. I have figured out how to test required and string length.
Here's my method that catches other errors, but doesn't handle the DataType validations:
private List<ValidationResult> ValidateModel<T>(T model)
{
var context = new ValidationContext(model, null, null);
var result = new List<ValidationResult>();
var valid = Validator.TryValidateObject(model, context, result, true);
return result;
}
I call it in a test method:
[TestMethod]
public void Invalid_email_addresses_throw_errors()
{
var model = new Models.Customer();
model.email = "";
var results = ValidateModel(model);
Assert.IsTrue(results.Any(v => v.ErrorMessage == "Email is required"));
}
How do I test DataType.EmailAddress - passing in an invalid value and receiving the an error as a result?
Use the [EmailAddress] DataTypeAttribute.
EmailAddressAttribute is derived from DataTypeAttribute and overrides the IsValid method which is what checks that the value is in fact a valid email.
Using
[DataType(DataType.EmailAddress, ErrorMessage = "Email must be a valid email address")]
does not do anything for email validation.
If you inspect the source code for DataTypeAttribute you will realize that it is primarily a base attribute used to create custom and targeted validation attribute.
The DataTypeAttribute in the original question is being used incorrectly.
There is no other solution than to use the EmailAddressAttribute as demonstrated below in the following unit test.
[TestClass]
public class UnitTestExample {
[TestMethod]
public void Invalid_email_addresses_throw_errors() {
//Arrange
var badEmail = "1234_)(";
var subject = new Customer { email = badEmail };
//Act
var results = ValidateModel(subject);
//Assert
Assert.IsTrue(results.Count > 0);
Assert.IsTrue(results.Any(v => v.MemberNames.Contains("email")));
}
public class Customer {
[StringLength(100)]
[Display(Name = "Email")]
[Required(ErrorMessage = "Email is required")]
[EmailAddress(ErrorMessage = "Email must be a valid email address")]
public string email { get; set; }
}
private List<ValidationResult> ValidateModel<T>(T model) {
var context = new ValidationContext(model, null, null);
var result = new List<ValidationResult>();
var valid = Validator.TryValidateObject(model, context, result, true);
return result;
}
}
The objective that I'm trying to achieve is that you have a Team which has many Players (ApplicationUsers), and you have Players (ApplicationUsers) which can potentially have many Teams. (Currently I am just focused on assigning one team).
I am receiving the error (in the title of this question) upon creation of a new user (code is below). After successfully creating a new user the code will call:
CreateAsync(user, userViewModel.Password);
which is where it fails.
The error that I am receiving seems to be related to Entity Framework and the instructions it's sending to SQL (I have a local instance of SQL Express configured in the Connection String). I have searched StackOverflow for this error and there do seem to be a lot of posts, but I can't seem to find an answer that relates to this circumstance - they all seem to reference SQL directly. Unfortunately I am new to .NET and am weak in EF and SQL which is why I am reaching out.
I believe the issue is something to do with the foreign key that EF is trying to establish between Teams and ApplicationUsers given the "IdentitySample.Models.Team_Players" part of the error.
I am working off of the .NET Identity 2.0 sample project, and have added some additional properties to the included ApplicationUser class which relate to a new class I added, "Team".
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here - db NOTE: Registration of claims from "IdentityExtensions.cs" class. See file.
// These need to be added to the ViewModels and the Controllers to capture the data. See the "AccountViewModel.cs"
// file, the "ManageViewModels.cs" and the "AccountController.cs" files, plus the views for corresponding changes.
userIdentity.AddClaim(new Claim("firstName", firstName));
userIdentity.AddClaim(new Claim("lastName", lastName));
userIdentity.AddClaim(new Claim("number", number.ToString()));
return userIdentity;
}
[Display(Name = "First Name")]
public string firstName { get; set; }
[Display(Name = "Last Name")]
public string lastName { get; set; }
[Display(Name = "Hawks Number")]
public int number { get; set; }
[Display(Name = "Successful Logins")]
public int successfulLogins { get; set; }
[Display(Name = "Password Status")]
public bool tempPassword { get; set; }
public virtual ICollection<Team> Teams { get; set; }
public ApplicationUser()
{
Teams = new List<Team>();
}
}
public class Team
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<ApplicationUser> Players { get; set; }
public Team()
{
Players = new List<ApplicationUser>();
}
}
I have two DbContexts, the included ApplicationDbContext along with one I added - IdentityDB - which inherits from the ApplicationDbContext class. In the IdentityDB context I have added the Team DbSet, "Teams".
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
static ApplicationDbContext()
{
// Set the database intializer which is run once during application start
// This seeds the database with admin user credentials and admin role
Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
public class IdentityDB : ApplicationDbContext
{
public DbSet<Team> Teams { get; set; }
}
I am creating a user by creating an instance of a view model called RegistrationViewModel:
public class RegisterViewModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[Display(Name = "First Name")]
public string firstName { get; set; }
[Required]
[Display(Name = "Last Name")]
public string lastName { get; set; }
[Display(Name = "Assigned Team")]
public string SelectedTeam { get; set; }
[Required]
[Display(Name = "Hawks Number")]
public int number { 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")]
[System.ComponentModel.DataAnnotations.Compare("Password", ErrorMessage= "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
public ICollection<SelectListItem> Teams { get; set; }
public RegisterViewModel()
{
Teams = new List<SelectListItem>();
}
}
in the UserAdminController:
//
// GET: /Users/Create
public async Task<ActionResult> Create()
{
//Get the list of Roles
ViewBag.RoleId = new SelectList(await RoleManager.Roles.ToListAsync(), "Name", "Name");
//Get list of Teams
IdentityDB _db = new IdentityDB();
var teams = _db.Teams.Select(t => new SelectListItem
{
Value = t.Name,
Text = t.Name
}).ToList();
return View(new RegisterViewModel { Teams = teams });
}
//
// POST: /Users/Create
[HttpPost]
public async Task<ActionResult> Create(RegisterViewModel userViewModel, params string[] selectedRoles)
{
IdentityDB _db = new IdentityDB();
Team userTeam = _db.Teams.First(x => x.Name == userViewModel.SelectedTeam);
if (ModelState.IsValid)
{
var user = new ApplicationUser
{
UserName = userViewModel.Email,
Email = userViewModel.Email,
firstName = userViewModel.firstName,
lastName = userViewModel.lastName,
number = userViewModel.number,
successfulLogins = 0,
tempPassword = true
};
user.Teams.Add(userTeam);
var adminresult = await UserManager.CreateAsync(user, userViewModel.Password); // CODE FAILS HERE
//Add User to the selected Roles
if (adminresult.Succeeded)
{
if (selectedRoles != null)
{
var result = await UserManager.AddToRolesAsync(user.Id, selectedRoles);
if (!result.Succeeded)
{
ModelState.AddModelError("", result.Errors.First());
ViewBag.RoleId = new SelectList(await RoleManager.Roles.ToListAsync(), "Name", "Name");
return View();
}
}
}
else
{
ModelState.AddModelError("", adminresult.Errors.First());
ViewBag.RoleId = new SelectList(RoleManager.Roles, "Name", "Name");
return View();
}
// Various email related activities that work fine and are unrelated to this error.
}
ViewBag.RoleId = new SelectList(RoleManager.Roles, "Name", "Name");
return View();
}
The definition of the CreateAsync method that the code fails at is:
[AsyncStateMachine(typeof(UserManager<,>.<CreateAsync>d__d))]
[DebuggerStepThrough]
public virtual Task<IdentityResult> CreateAsync(TUser user, string password);
The SQL Express database does contain a table called "ApplicationUserTeams" with the 'TeamId' and 'ApplicationUser_Id' columns created, so it seems like EF is doing its job though something is failing along the way.
Steps taken to troubleshoot at this point include deleting the entire database and the migration folder in the project, then running the application again so it creates a fresh instance, along with a new "initial" migration. This did not have any effect on the issue. I really don't know where to go from here so any help would be greatly appreciated. Thank you in advance for your time.
EDIT: In working on an Index view for the "Team" controller, I noticed I am getting an error 'Invalid object name 'dbo.ApplicationUserTeams'. This was a result of iterating over the foreign key property "Players" which are of type Application User.
#model IEnumerable<IdentitySamplesTEST.Models.Team>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
#if (item.Players.Count == 0) #*ERROR OCCURS HERE*#
{
<td>
None.
</td>
}
else
{
foreach (var player in item.Players)
{
<td>
#Html.DisplayFor(modelItem => player.firstName)
</td>
}
}
The table in the database is actually called dbo.TeamApplicationUsers - backwards to what EF seems to be looking. I have no idea what would cause this...
I have a set up where a Company can have none or one or many clients. So there is no strict relationship between the Client table and the Company table. I have created a Search view where all companies are populated. Then using a button a client can be attached to the company. I thought using an ActionLink I would be able to achieve this, so my Search (view) has,
#Html.ActionLink("Book", "Book", new { id = a.CompanyId })
Where the Model is looped over to get all the company list. Now when I click the link, it populates the Address with the right params, Companies/Book/1 the ID I am playing with is 1. Which is correct, however the View I am landing at is a new Customer Model.
public class CustomerModel
{
[HiddenInput(DisplayValue = true)]
public long CompanyId { get; set; }
[HiddenInput(DisplayValue = false)]
public long CustomerId { get; set; }
[Display(Name = "Customer Name")]
[Required(ErrorMessage = "* required")]
public string CustomerName { get; set; }
[Display(Name = "Address Line 1")]
[Required(ErrorMessage = "* required")]
public string AddressLine1 { get; set; }
[Display(Name = "Postcode")]
[Required(ErrorMessage = "* required")]
public string Postcode { get; set; }
[Display(Name = "Phone Number")]
[Required(ErrorMessage = "* required")]
[RegularExpression(#"\d*", ErrorMessage = "Not a valid phone number")]
public string PhoneNo { get; set; }
}
Even though I am able to see the ID being passed (using FireBug) is 1, somehow when I click the button to submit the view to the controller I get a 0. Why would this be? Could anyone help me?
EDIT - 1
This is the controller.
public ActionResult Book()
{
return View(new CustomerModel());
}
[HttpPost]
public ActionResult SaveCustomer(CustomerModel model)
{
_companyService.SaveCustomer(model);
return RedirectToAction("Index");
}
I have tried using the CompanyId instead of id, it came up with another error.
Before submitting the Form, Address bar has : http://localhost:53294/Companies/Book?CompanyId=1
After submitting the Form, Address Bar has : http://localhost:53294/Companies/SaveCustomer
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.Customer_dbo.Company_CompanyId". The conflict occurred in database "BoilerServicing", table "dbo.Company", column 'CompanyId'.
The statement has been terminated.
The save method by itself,
public void SaveCustomer(CustomerModel customer)
{
using (var db = new BoilerServicingDbContext())
{
Customer entity;
if (customer.CustomerId > 0)
{
entity = db.Customers.First(x => x.Id == customer.CustomerId);
}
else
{
entity = new Customer();
db.Customers.Add(entity);
}
entity.Name = customer.CustomerName;
entity.TelephoneNumber = customer.PhoneNo;
entity.AddressLine1 = customer.AddressLine1;
entity.PostCode = customer.Postcode;
entity.CompanyId = customer.CompanyId;
db.SaveChanges();
}
}
Okay, after trying so many ways, I have come to this. I changed the Action method on the controller.
public ActionResult Book(long id)
{
return View(new CustomerModel
{
CompanyId = id
});
}
This seems to have passed in the CompanyId I am passing into the Book view. Took me a while, but I got there. Thanks for all your help !
I am creating a test method in Asp.Net MVC 5. I am using following code to test my registration method
[TestMethod]
public async Task Registration_Test_For_Password_And_Confirm_Password_Mismatch()
{
// Arrange
var registerationModel = new RegisterViewModel() { UserName = "abc", Password = null, ConfirmPassword = "jjk", Email = "nitin.daiya#sunarctechnologies.com" };
// Validate model state start
var validationContext = new ValidationContext(registerationModel, null, null);
Validator.TryValidateObject(registerationModel, validationContext, validationResults);
foreach (var validationResult in validationResults)
{
controller.ModelState.AddModelError(validationResult.MemberNames.First(), validationResult.ErrorMessage);
}
// Validate model state end
// Act
var result = await controller.Register(registerationModel) as ViewResult;
// Assert
Assert.AreEqual("", result.ViewName);
Assert.IsFalse(controller.ModelState.IsValid);
}
Above code is working fine if I pass empty values for the Required fields.
If I try to check any other validation it is not showing the error message and test fails each time.
Following is my ViewModel
public class RegisterViewModel
{
public string UserId { get; set; }
[Required]
[System.Web.Mvc.Remote("IsUserNameAvailable", "Account", ErrorMessage = "That UserName is already taken.")]
[Display(Name = "User Name")]
public string UserName { 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; }
[Required]
[EmailAddress]
[System.Web.Mvc.Remote("IsEmailAvailable", "Account", ErrorMessage = "That email is already taken.")]
[Display(Name = "Email")]
public string Email { get; set; }
}
Any help will be appreciated
EDIT: Solved the issue by changing Validator.TryValidateObject(registerationModel, validationContext, validationResults); to Validator.TryValidateObject(registerationModel, validationContext, validationResults,true); this. True is set for validateAllProperties property to check all validation.
It still not testing the remote validation. Any clue??
Validator.TryValidateObject(registerationModel, validationContext, validationResults)
This line will by default only validate required properties. To validate all properties, you need to set the validateAllProperties parameter to true:
Validator.TryValidateObject(registerationModel, validationContext, validationResults, true);
(Adding this as it wasn't immediately clear that this question had an answer)