Search code examples
c#asp.net-mvcmodel-validation

VallidationAttribute check multiple values in a condition


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);            
        }
    }
}

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