2

I have a basic model which I'm trying to do some Remote validation using the remote attribute.

    [Remote("IsCodeValid", "Utilities", ErrorMessage = "Code already in use")]
    [Required]
    public string Code { get; set; }

If I do a normal Html.Editorfor(m => m.Code) then everything works fine and I am able to successfully use the Remote Validation. So the attribute and the controller method in a normal use case is working perfectly.

The issue

I'm trying to use an EditorTemplate in which I'm using a 3rd party library to re-create the Input control. In the EditorTemplate I need to either access the Remote validation attributes such as all the "data-val" attributes and then add them on or if there is some method available that I can get a list of them and then just add them on in one go.

I have managed to get access to the Html.ViewData within the editor template.

Can someone point me in the right direction? Has someone done something like this before?

Here is the flow of my Editor template so it gives you an idea of what I'm trying to achieve.

// Start of editor template
@model String

@{
var htmlAttributes = new Dictionary<string, object>();

// Observe how I can manually add attributes to the dictionary
htmlAttributes.Add("data-val", "true");

// Able to add Css class from ViewModel
if (Html.ViewData.ContainsKey("class"))
{
    var cssClass = Html.ViewData.SingleOrDefault(kvp => kvp.Key.ToLower() == "class");
    htmlAttributes.Add(cssClass.Key, cssClass.Value);
}
}
@(

// At this point is where I need to pass the htmlAttributes with the [Remote] validation values so that it can be added to the input control
Html.Custom3rdPartyLibrary()
    .TextEditorFor(x => Model)
    .HtmlAttributes(htmlAttributes)
    .Render()
)
JARRRRG
  • 917
  • 2
  • 14
  • 44
  • It seems to me like the problem could be with your 3rd party and not your setup. Is there an error you are getting? – Travis J Dec 08 '16 at 22:56
  • Well, there isn't a problem The 3rd party TextEditorFor does not work with the MVC [Remote] attribute. Hence the question in the first place. It does however take htmlAttributes. So before I call the 3rd party text editor I need the attributes from the [Remote] tag. IE access them within then Editor Template. – JARRRRG Dec 08 '16 at 23:14
  • You should be able to use reflection to access the values in the remote attribute. These answers should provide a good first step to reading that value: http://stackoverflow.com/q/6637679/1026459 – Travis J Dec 08 '16 at 23:18

1 Answers1

1

You can use the GetUnobtrusiveValidationAttributes() method of the HtmlHelper to get the validation attributes based on the ModelMetadata.

@model string
@{
    // Get the ModelMetadata
    ModelMetadata metadata = ViewContext.ViewData.ModelMetadata;
    // Get the validation attributes
    IDictionary<string, object> attributes = @Html.GetUnobtrusiveValidationAttributes(metadata.PropertyName, metadata );
}

based on the validation attributes applied to you property, attributes will contain the following key/value pairs

data-val-required: "The Code field is required."
data-val-remote: "Code already in use"
data-val-remote-url: "/Utilities/IsCodeValid"
data-val-remote-additionalfields: "*.Code"
data-val: true

and then you can add any further attributes such as class names to the dictionary and pass it to your custom helper method using .HtmlAttributes(attributes)

  • @StepehenMuecke just the method I needed. If you don't mind me asking, how did you come to finding the GetUnobtrusiveValidationAttributes? – JARRRRG Dec 09 '16 at 10:04
  • Also perhaps this is for a separate question. The validation is now working however is using the previous value in the textbox. So for example on first usage if I enter a character "B". It will post and empty string "" to the controller to validate. If I then add another character it will post "B" but not the next character and so on. I think it has something to do with the 3rd party library setting the original input as hidden and the remote validation is firing before the hidden attributes value is updated. – JARRRRG Dec 09 '16 at 10:04
  • You will need to ask a new question with the relevant details (including a link to whatever 3rd party plugin your using). Although it all sounds a bit strange since hidden inputs are not even validated by default, and the fact its not including the 'current key' suggests its handling the `keypress()` event rather that a `keyup()` event (and I know the the source code better than most :) –  Dec 09 '16 at 10:09
  • I've fixed it now. What this 3rd party libraries text editor does is sets the original incoming input to hidden but leaves on a name tag and I'm assuming it sets the value of that hidden tag. So when it's created, the Name attribute is only on the hidden input. What I did to fix it is just add a Name attribute to the newly generated Input by the library, done. http://imgur.com/JfNrRtK - probably not the cleanest way of fixing it but at least now when it's posted to the controller it has the right value to validate. – JARRRRG Dec 09 '16 at 10:26