0
votes

For some reason fields named with '.value' or .anything does not generate client validation. For example this code:

@Html.TextArea("ContentObjectFirm.Description")

generates this:

<textarea rows="2" name="ContentObjectFirm.Description" id="ContentObjectFirm_Description" data-val-required="Firm description is required" data-val="true" cols="20"></textarea>

notice "data-val-required"

Now, I NEED to have the field named "ContentObjectFirm.Description.Value" - i'm using a custom binder here (not related to my question however). The bottom line is, is that I need to have '.Value' in the name of the field. So,

for this code: @Html.TextArea("ContentObjectFirm.Description.Value")

Text area helper generates:

<textarea rows="2" name="ContentObjectFirm.Description.Value" id="ContentObjectFirm_Description_Value" cols="20"></textarea>

MODEL class:

[Required(ErrorMessageResourceName = "fld_Description_val_Required", ErrorMessageResourceType = typeof(Resources.Service.Controllers.Firm))]
[Display(Name = "fld_Description_lbl", ResourceType = typeof(Resources.Service.Controllers.Firm))]
public MultilanguageProperty<string> Description
{
    get
    {
        return this.GetMultilanguageProperty("Description", string.Empty, this);
    }

    set
    {
        this.SetMultilanguageProperty("Description", value);
    }
}

where MultilanguageProperty is my custom interface (unimportant)..when using 'string Description' it still doesn't work.

how do i make it so that Unobtrusive validation code will be added? why is it skipped when .value string is added?.

thanks

1
Hi, can you provide you model class for analysis?tpeczek

1 Answers

1
votes

The default HtmlHelper is using the name which you provide for looking up MetaData and ValidationAttributes from your model. If the name doesn't correspond with property, the HtmlHelper will not find those informations. The best solution seems to be creating a custom HtmlHelper extension, which may look like this:

public static class CustomTextAreaExtensions
{
    public static MvcHtmlString CustomNameTextArea(this HtmlHelper htmlHelper, string name, string metadataPropertyName)
    {
        string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);

        TagBuilder tagBuilder = new TagBuilder("textarea");
        tagBuilder.GenerateId(fullName);
        tagBuilder.MergeAttribute("rows", "2", true);
        tagBuilder.MergeAttribute("cols", "20", true);
        tagBuilder.MergeAttribute("name", fullName, true);

        ModelState modelState;
        if (htmlHelper.ViewData.ModelState.TryGetValue(fullName, out modelState) && modelState.Errors.Count > 0)
            tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);

        tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(metadataPropertyName));

        ModelMetadata modelMetadata = ModelMetadata.FromStringExpression(metadataPropertyName, htmlHelper.ViewContext.ViewData);
        string value;
        if (modelState != null && modelState.Value != null)
            value = modelState.Value.AttemptedValue;
        else if (modelMetadata.Model != null)
            value = modelMetadata.Model.ToString();
        else
            value = String.Empty;
        tagBuilder.SetInnerText(Environment.NewLine + value);

        return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.Normal));
    }
}

After registering proper namespace in web.config, you will be able to use this extension method like this:

@Html.CustomNameTextArea("ContentObjectFirm.Description.Value", "ContentObjectFirm.Description")

This should give you the desired output.