Question

I'm still new to ASP.NET MVC and I'm struggling with a validator I need to implement.

I have a UserName property in my Account model, that needs to be checked for uniqueness. It's declared as followed:

[Required(ErrorMessageResourceName = "UserNameRequiredError", ErrorMessageResourceType = typeof(App_LocalResources.Resources))]
[Display(Name = "UserName", ResourceType = typeof(App_LocalResources.Resources))]
[VallidateAccount(Field = AccountChecks.UserNameUnique, ErrorMessageResourceName = "UserNameUniqueError", ErrorMessageResourceType = typeof(App_LocalResources.Resources))]
public string UserName { get; set; }

The used ValidationAttribute has the following to perform the check

public class VallidateAccountAttribute : ValidationAttribute
{
    public AccountChecks Field { get; set; }
    public int ID { get; set; }

    public override bool IsValid(object value)
    {
        switch (Field){
            case AccountChecks.UserNameUnique:
                return CheckUserName((string)value);
            //Other Fields
            default:
                throw new ParameterException("Invallid Field");
        }
    }

    private bool CheckUserName(string username)
    {
        Account account = Connection.DB.Accounts.FirstOrDefault(x => x.UserName == username);
        return !string.IsNullOrEmpty(username) && (account == null || account.AccountID == this.ID);
    }
    //Other checks
}

And now for the problem: The entered username is correctly passed into the validation through the value parameter of the IsValid method, but I can't find a way to pass the ID along with it.

I've tried to pass it along the same way I pass the Field parameter, but I can't use the this keyword.

[VallidateAccount(Field = AccountChecks.UserNameUnique, ID = this.AccountID, ErrorMessageResourceName = "UserNameUniqueError", ErrorMessageResourceType = typeof(App_LocalResources.Resources))]

Can anyone please help me in passing through the ID value?

EDIT: Implemented solution proposed by Rahul RJ

Remote validation provided me with the ability to do exactly what I wanted.

The new UserName property:

[Required(ErrorMessageResourceName = "UserNameRequiredError", ErrorMessageResourceType = typeof(App_LocalResources.Resources))]
[Display(Name = "UserName", ResourceType = typeof(App_LocalResources.Resources))]
[System.Web.Mvc.Remote("UserNameUnique", "Validation", AdditionalFields = "AccountID", HttpMethod = "POST", ErrorMessageResourceName = "UserNameUniqueError", ErrorMessageResourceType = typeof(App_LocalResources.Resources))]
public string UserName { get; set; }

The ValidationAttribute is no longer used in this case, instead it is replaced with a new ValidationController.

using System.Web.Mvc;
using MyProject.Models;

namespace MyProject.Controllers
{
    [OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
    public class ValidationController : Controller
    {
        MyDbContext _repository;
        public ValidationController() : this(Connection.DB) { }

        public ValidationController(MyDbContext repository)
        {
            _repository = repository;
        }
        //NOTE: Make sure the parameters have the same name as your properties!!!
        public JsonResult UserNameUnique(string UserName, int AccountID = 0)
        {
            Account account = Connection.DB.Accounts.FirstOrDefault(x => x.UserName == UserName);
            return Json(!string.IsNullOrEmpty(UserName) && (account == null || account.AccountID == AccountID), JsonRequestBehavior.AllowGet);            
        }
    }
}
Était-ce utile?

La solution

You can do the Remote Side Validation in this Scenario. with that you can easily check the Exsisting UserName.

Use this http://msdn.microsoft.com/en-us/library/gg508808(v=vs.98).aspx for your Reference

Autres conseils

You're doing to much! If you want to validate for uniqueness then just do that.

Where you have .FirstOrDefault you should change to .Any and just check to see if there is any rows with that username.

private bool CheckUserName(string username) { if(string.IsNullOrEmpty(username)) return false;

return !Connection.DB.Accounts.Any(x => x.UserName == username); }

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top