4

Our credit card processor (Braintree Payments) requires that we not use the "name" attribute on credit card fields (card number, expiration date, and CCV) to obviously make sure they don't get POSTed to the server unencrypted. I found a custom Extension to generate a name-less text box (How to extend html.textboxfor to remove the name attribute?). This works great, since it allows us to generate a text box without the name attribute, but it still adds all the other validation attributes and such automatically. But I have run into a problem.

When I use @Html.NameLessTextBoxFor(model => model.CardNumber) in my view, it correctly generates the text box without a name attribute. We also use Data Annotations in the View Model to generate unobtrusive validation. The visible problem on the actual website is that when there is a validation error with one of these name-less fields, the ValidationMessage span doesn't display any error messages. The name-less field correctly turns red, but the error messages don't display.

I believe I have deduced why this isn't working, but I can't figure out how to fix it. I looked at the generated HTML for the ValidationMessage span, and I see this attribute:

data-valmsg-for="MyViewModel.CardNumber"

That would be correct if my name-less field had the name attribute set like normal. But since I can't set the name attribute, how do I get the ValidationMessage to still work?

5
  • 3
    MVC validations use jqueryvalidation, which uses the name of the field to validate the form content. You'll need either modify the source code of the validation plugin or try to use a different one Commented Apr 12, 2013 at 20:07
  • It's not a big plugin, so rewriting it is not too big of an issue (for instance, I added a onvalidation callBack to it recently, to allow me to leverage jQuery once it had run), however, looking through it, name is really baked in there. Also beware that name occasionally differs from ID when the ASP.Net MVC Binding spits out the fields, so you may have to intervene at the metadata provider/object template level as the fields are being generated to make sure your data-valmsg-for relates to the value generated for the ID and not the name. I hope this is of some small help to you. Good luck! Commented Apr 12, 2013 at 20:37
  • 1
    Thank you both for the info. So it sounds like it could be a hassle to change jqueryvalidation. We also don't like changing plugins if we don't have to. Do you think it would be easier to allow the name attribute on the credit card fields, but scrub the POST data for those fields before submitting? Any clue how difficult that would be, in contrast to changing jqueryvalidation? Any other possible solutions? Commented Apr 12, 2013 at 21:03
  • Scrubbing the name attributes on submit would be the path of least resistance IMHO. Commented Apr 12, 2013 at 21:17
  • For anyone who comes upon this question later on, we have simply left the credit card fields without any client-side validation. Validation is done server-side, which is fine for us. It's inconvenient, if the user enters something incorrectly and has to reload the page to see the error, but that's a small price to pay, instead of us hacking into jqueryvalidation to make this work. So if anyone ever comes up with a fix, let me know please. Commented Aug 15, 2013 at 19:24

1 Answer 1

0

Scrub the name attrributes on submit would be something like:

$("form").submit(function () {
    $(this.find(":input").removeAttr("name");
});

It's possible that this may be too late in the chain of events though, so you may have to preventDefault and repost the form, something like this:

$("form").submit(function (e) {
    if($(this.find(":input[name]").length > 0) {
        e.preventDefault();
        $(this.find(":input").removeAttr("name");
        $(this).trigger("submit");
    }
});

Or indeed do as I did and code a callBack into unobtrusive validation to check if validation has passed and at that point remove the name attributes. Here are my notes on adding that callBack:

//Added the following to the onErrors function:
    if ($.isFunction(callBackOnError)) {
        setTimeout(function () {
            callBackOnError();
        }, 100);
    }
//Then in the exposing declarative section of the plugin
    onError: function (callBack) {
        callBackOnError = callBack;
    }

Have a play with it and see what you find. Keen to know your eventual conclusion, so please do update. Hope this has somewhat helped you.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks so much for the answer, but after checking with our CC processor, they advised to never allow the name attribute to be used. They mentioned potential situations, like if someone had JS disabled. In that case, the name attribute wouldn't be removed, and those sensitive CC fields would be POSTed. So for now, we are tabling this whole issue and are just going to forego client-side validation. Frustrating, but it is what it is.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.