ASP.NET MVC validation of uniqueness
Rails has a very convenient uniqueness validation.
ASP.NET MVC doesn't.
I need to make sure that the e-mail address a user has entered hasn't been registered by anyone yet.
I can see only one way of doing this kind of validation: create a new data context object in the UniqueAttribute class.
But I'm afraid that wasting memory on a new data context object just for one validation is dangerous.
Am I wrong? Is there a better way to do that?
Update
This is what I got so far
public class UniqueEmailAttribute : ValidationAttribute {
public override bool IsValid(object value) {
Data开发者_Python百科Context db = new DataContext();
var userWithTheSameEmail = db.Users.SingleOrDefault(
u => u.Email == (string)value);
return userWithTheSameEmail == null;
}
}
// Usage
[UniqueEmail(ErrorMessage="This e-mail is already registered")]
public string Email { get; set; }
There are two problems.
It would be good to have just one UniqueAttribute class, not separate classes for e-mails, usernames etc. How can I do that?
Creating a new data context every time you need to validate a single attribute.
SOLUTION
So in the end I created a unique constraint on the table and now I just have to intercept SqlException in Users repository. Works great and is probably more efficient than searching for the same node in the whole table. Thanks!
Mvc 3 Relaease candidate has new New Validation Attributes as a remotevalidation -where you can register a method for validation on clientside(jquery).
see below example- RemoteAttribute
The new RemoteAttribute validation attribute takes advantage of the jQuery Validation plug-in's remote validator, which enables client-side validation to call a method on the server that performs the actual validation logic.
In the following example, the UserName property has the RemoteAttribute applied. When editing this property in an Edit view, client validation will call an action named UserNameAvailable on the UsersController class in order to validate this field.
public class User {
[Remote("UserNameAvailable", "Users")]
public string UserName { get; set; }
}
The following example shows the corresponding controller.
public class UsersController {
public bool UserNameAvailable(string username) {
return !MyRepository.UserNameExists(username);
}
}
Mvc 3
UPDATE
public bool UserNameAvailable(string Propertyname)
{
if (Request.QueryString[0]= "UserName")
{
//validate username
}
elseif (Request.QueryString[0]= "Email")
{
//Validate Email
}
}
ASP.Net does have a feature that can automatically check the uniqueness of a user's email address when a user registers. It is the ASP.Net Membership service and you can use it to do what you want even if you don't use all of the features of it.
If you are not using the full Membership feature in your MVC application, then all you need to do is use
Membership.FindUsersByEmail(emailYouAreLookingFor);
If any values come back, you know that the address is not unique. If you ARE using the Membership service to create users, then the Membership service will check AUTOMATICALLY and return a code to you if the user's email address is not unique.
The Membership service sits in the System.Web.Security area so you would need a
using System.Web.Security;
reference in your controller.
Here is an example
MembershipCreateStatus createStatus = MembershipService.CreateUser(UserName, Password, Email); if (createStatus == MembershipCreateStatus.DuplicateEmail) { //do something here } else { //do something here }
I hope this helps!
The right way to make a generic remote unique validator in MVC can be found in this MVC forum. by counsellorben. It's based on my MVC unique remote validator article http://msdn.microsoft.com/en-us/library/gg508808(VS.98).aspx
A foolproof way of doing this is to create a validation attribute that would query the database for the email address. It would certainly add latency.
An alternative would be to create a unique constraint on the table and intercept SqlException.
精彩评论