Pacman
Pacman

Reputation: 2245

MVC Remote validation, parameter is null

public class UserModel
    {
        public LogOnModel LogOnModel { get; private set; }
        public RegisterModel RegisterModel { get; private set; }
    }

in my RegisterModel I have email address like this:

[RegularExpression(@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$")]
        [Required]
        [Display(Name = "E-mail")]
        [Remote("IsEmailAddressAvailable", "Validation", HttpMethod = "POST")]
        public string EmailAddress { get; set; }

My validationController:

public class ValidationController : Controller
    {
        public JsonResult IsEmailAddressAvailable(string emailAddress)
        {
            return Json(false, JsonRequestBehavior.AllowGet);
            
        }
}

The view @Model is UserProfile, the emailAddress in ValidationController is null.

I tried to change the ValidationController to look like this with no luck:

public class ValidationController : Controller
    {
        public JsonResult IsEmailAddressAvailable([Bind(Include = "EmailAddress")]RegisterModel register)
        {
            return Json(false, JsonRequestBehavior.AllowGet);
            
        }

        
    }

        
    

Upvotes: 7

Views: 7363

Answers (4)

Michael Dunlap
Michael Dunlap

Reputation: 4310

You have to either return true (validation passed), or a string of the error message in your validator. See here: http://msdn.microsoft.com/en-us/library/gg508808(v=vs.98).aspx

public class ValidationController : Controller {
    public JsonResult IsEmailAddressAvailable(string EmailAddress) {
        return Json("Email Address unavailable", JsonRequestBehavior.AllowGet);
    }
}

Upvotes: 0

Miron
Miron

Reputation: 181

Your thinking about using Bind attribute is correct. Instead using Include parameter, you should use Prefix parameter. So your controller should look:

public class ValidationController : Controller
    {
        public JsonResult IsEmailAddressAvailable([Bind(Prefix = "RegisterModel.EmailAddress")]string EmailAddress)
        {
            return Json(false, JsonRequestBehavior.AllowGet);

        }
    }

So Prefix parameter binds parameter sent by browser with action parameter.

Upvotes: 13

DMac the Destroyer
DMac the Destroyer

Reputation: 5290

I would suspect this to be a model binding issue. Try changing the action signature to something like this:

public class ValidationController : Controller
{
    public JsonResult IsEmailAddressAvailable([Bind(Prefix="RegisterModel")]string emailAddress)
    {
        return Json(false, JsonRequestBehavior.AllowGet);
    }
}

Notice the [Bind(Prefix="RegisterModel")], which was slightly similar to what you were trying to do from your latter attempt, so I think you were on the right track. I basically pulled this from a very similar answer posted here, so maybe that trail can help you out further if this doesn't quite do it for you.

Upvotes: 3

Dakait
Dakait

Reputation: 2620

The reason that comes to my mind is that as you are having another model (RegisterModel) as another model's property (UserModel), when you use the Html helper to render the model property like

@Html.TextBoxFor(x=>x.RegisterModel.EmailAddress)

it will render it something like

<input type="text" name="RegisterModel.EmailAddress"/>

MVC model binding works on the name properties and you are recieving string emailAddress in the first example and RegisterModel model in the second attempt, try using the UserModel model as the recieving parameter of the remote validtion ActionResult like

public JsonResult IsEmailAddressAvailable(UserModel model)
        {
            return Json(false, JsonRequestBehavior.AllowGet);

        }

Upvotes: 1

Related Questions