Pergunta

I have created an editor template for one of my models in my current MVC3 project. This model is calling the correct editors for the properties of the underlying mode, but they're missing the unobtrusive data-val-* attributes for validation.

How can I get MVC to emit the data-val attributes?

Here's my model

[MetadataType(typeof(FieldTripRouteMetadata))]
public partial class FieldTripRoute
{
    private class FieldTripRouteMetadata
    {
        [Required]
        [DisplayFormat(DataFormatString = "{0:d}")]
        public DateTime Date { get; set; }

        [Required]
        [DisplayName("Route")]
        public int RouteID { get; set; }

        [Required]            
        [DisplayName("Departure Time")]
        [UIHint("TimeWithPeriod")]
        [DisplayFormat(DataFormatString = "{0:h:mm tt}")]
        public DateTime DepartureTime { get; set; }

        [Required]
        [StringLength(255)]
        [DisplayName("Pickup Location")] 
        public String PickupLocation { get; set; }

        [Required]
        [StringLength(255)]
        public String Destination { get; set; }

        [Required]            
        [DisplayName("Arrival Time")]
        [UIHint("TimeWithPeriod")]
        [DisplayFormat(DataFormatString = "{0:h:mm t}")]
        public DateTime ArrivalTime { get; set; }

        public bool IsReturnRoute { get; set; }

        public int FieldTripID { get; set; }
    }

and my Editor Template:

@model FieldTripRoute

@{string routeType = (Model.IsReturnRoute ? "return" : "");}

<fieldset class="add@(routeType)Route" style="clear: both; width: 620px; margin-right: auto; margin-left: auto;">
    <legend>Add Route</legend>
    <div style="float: left; width: 275px;">
        <div>
            <div class="editor-label">@Html.LabelFor(model => model.Date)</div>
            <div class="editor-field">@Html.EditorFor(model => model.Date)</div>
            <div class="validation-error">@Html.ValidationMessageFor(model => model.Date)</div>
        </div>
        <div>
            <div class="editor-label">@Html.LabelFor(model => model.DepartureTime)</div>
            <div class="editor-field">@Html.EditorFor(model => model.DepartureTime)</div>
            <div class="validation-error">@Html.ValidationMessageFor(model => model.DepartureTime)</div>
        </div>
        <div>
            <div class="editor-label">@Html.LabelFor(model => model.ArrivalTime)</div>
            <div class="editor-field">@Html.EditorFor(model => model.ArrivalTime)</div>
            <div class="validation-error">@Html.ValidationMessageFor(model => model.ArrivalTime)</div>
        </div>
    </div>
    <div style="float: left;">
        <div>
            <div class="editor-label">@Html.LabelFor(model => model.RouteID)</div>
            <div class="editor-field">@Html.DropDownListFor(model => model.RouteID, Model.EditRouteList)</div>
            <div class="validation-error">@Html.ValidationMessageFor(model => model.RouteID)</div>
        </div>
        <div>
            <div class="editor-label">@Html.LabelFor(model => model.PickupLocation)</div>
            <div class="editor-field">@Html.TextBoxFor(model => model.PickupLocation)</div>
            <div class="validation-error">@Html.ValidationMessageFor(model => model.PickupLocation)</div>
        </div>
        <div>
            <div class="editor-label">@Html.LabelFor(model => model.Destination)</div>
            <div class="editor-field">@Html.EditorFor(model => model.Destination)</div>
            <div class="validation-error">@Html.ValidationMessageFor(model => model.Destination)</div>
        </div>          
    </div>        
    <div style="clear: both; width: 100px; margin: 20px auto 0 auto;">
        <input type="button" id="submit@(routeType)Form" name="submit@(routeType)Form" value="Add" />
    </div>
</fieldset>

And my viewModel:

public class FieldTripEditViewModel
{
    public FieldTrip Trip { get; set; }        
    public FieldTripRoute Route { get; set; }        
    public FieldTripRoute ReturnRoute { get; set; }

    public FieldTripEditViewModel(){}

    public FieldTripEditViewModel(FieldTrip trip)
    {
        this.Trip = trip;
        this.Route = new FieldTripRoute();
        this.ReturnRoute = new FieldTripRoute {IsReturnRoute = true};
    }
}

I looked at this post and all of my base editor templates correspond to the idea of leaving the name as an empty string to allow MVC to generate it. Yet I still have no validation.

Foi útil?

Solução

I was able to get it to function by adding a form tag before and after my editor template and adding this.ViewContext.FormContext = new FormContext(); at the beginning of the Editor Template.

It appears that when the control is passed to the editor template it loses the current form context. I tried just addin the ViewContext.FormContext command but without the addition of the form tags the embedded model would not validate.

So right now I have a form inside of a form and it works as intended, but it seems like there should be an easier way.

The idea for the formContext command came from here

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top