0

I'm using ASP.NET MVC3.
When an user create an account, I need the chosen nickname be unique, so I use the Remote DataAnnotation like this :

public class UserModel
{
    [Required]
    [Remote("CheckNickname", "Validation", ErrorMessage = "This nickname is already used")]
    public string Nickname { get; set; }

    // ...
}

I used it in a strongly-typed view, via @Html.TextBoxFor(m => m.Nickname) and it perfeclty works.


However, I created another model with the exact same property.

public class MyOtherModel
{
    // ...

    [Required]
    [Remote("CheckNickname", "Validation", ErrorMessage = "This nickname is already used")]
    public string Nickname { get; set; }
}

I used this MyOtherModel.Nickname on a strongly-typed view via :
@Html.TextBoxFor(m => m.MyOtherModel.Nickname) However, in this case only, the data passed to my CheckNickame() method is always null.

There are only two differences :

  • In the second case, the property I want to remotely validate is contained in another model (is it a problem ? I don't think so...)
  • In the second case, the property is displayed inside a modal bootstrap (is it a problem ?)

For information, this is what my CheckNickname() looks like :

public JsonResult CheckNickname(string nickname)
{
    UserDAL userDAL = new UserDAL();
    bool userIsAvailable = !userDAL.IsUserAlreadyInUse(nickname);

    return Json(userIsAvailable, JsonRequestBehavior.AllowGet);
}

As I wrote it before, in the second case only, the parameter nickname is always null whereas it works as expected in the first case.

Is anyone knows why ?
Any help is appreciated.


UPDATE :
I created this method :
public JsonResult CheckNickname2([Bind(Prefix = "MyOtherModel")]string nickname)
{
    UserDAL userDAL = new UserDAL();
    bool userIsAvailable = !userDAL.IsUserAlreadyInUse(nickname);

    return Json(userIsAvailable, JsonRequestBehavior.AllowGet);
}

The call is now :
http://mysite/Validation/CheckNickname2?MyOtherModel.Nickname=Alex
but if I put a breakpoint on CheckNickname2, the nickname paremeter is still null !

However, the call on the working validaton method is :
http://mysite/Validation/CheckNickname?Nickname=Alex
and this one works...


SOLUTION:
Ok, solved by changing [Bind(Prefix = "MyOtherModel")] to [Bind(Prefix = "MyOtherModel.Nickname")] as suggested by Stephen Muecke
Community
  • 1
  • 1
AlexB
  • 7,302
  • 12
  • 56
  • 74

1 Answers1

2

In your second example, the html generated will be name="MyOtherModel.Nickname" so the key/value pair posted back will be MyOtherModel.Nickname:yourValue. Change the controller method to

public JsonResult CheckNickname([Bind(Prefix="MyOtherModel.Nickname")]string nickname)

which will effectively strip the prefix and bind correctly to parameter nickname

Note also that the modal usage may be a problem if this is adding dynamic content after the initial page has been rendered (in which case you need to re-parse the validator)

  • You're right about the html generated, which is `name="MyOtherModel.Nickname"`. However, adding the `[Bind]` doesn't change anything and the nickname parameter is always `null` Even if I'm not sure what you call "dynamic", my `modal` is "hard-coded" on the view and called by `$("#myModal").modal()` if necessary. How can I "re-parse the validator" ? – AlexB Apr 28 '15 at 10:47
  • 1
    If the controls for the modal exist when you first generate the view, then re-parsing the validator is not necessary (but [this answer](http://stackoverflow.com/questions/26542509/validate-dynamically-added-fields/26542591#26542591) explains it). –  Apr 28 '15 at 10:52
  • I also suggest you look my [answer here](http://stackoverflow.com/questions/27513472/remote-validation-for-list-of-models/27517407#27517407) which is related and shows how you can modify the `jquery.validate.js` file to strip the prefix. I have seen some action on the bug report I made so hopefully this will be resolved in the next issue of `jquery` –  Apr 28 '15 at 10:55
  • 1
    And sorry, it needs to needs to be `[Bind(Prefix="MyOtherModel.Nickname")]`, not `[Bind(Prefix="MyOtherModel")]`. See update –  Apr 28 '15 at 10:58
  • Aaaaah, yes, it's better with `[Bind(Prefix="MyOtherModel.Nickname")]`, thanks a lot ! – AlexB Apr 28 '15 at 11:03