2011-04-01 4 views
5

Uzaktan doğrulama, modelimin yalnızca bir örneğini görünümde gördüğümde iyi çalışıyor.Modellerin koleksiyonunda Eklentilerle uzaktan doğrulama

Görünümüm, model koleksiyonunu ele aldığım zamandır. Bende Bence

public class TableFormTestModel 
{ 
    public GridRow[] GridData { get; set; } 
    public class GridRow 
    { 
     public Int32 Id { get; set; } 

     [Required, StringLength(50), Remote("IsNameAvailable", "TableFormTest", "Admin", AdditionalFields = "Id")] 
     public String Name { get; set; } 
    } 
} 

: İşte benim modeldir

@model TableFormTestModel 
@using (Html.BeginForm()) 
{ 
    Html.EnableClientValidation(); 
    Html.EnableUnobtrusiveJavaScript(); 
    for(var i = 0;i<Model.GridData.Length;i++) 
    { 
    <div> 
     @Html.HiddenFor(x => Model.GridData[i].Id) 
     @Html.TextBoxFor(x => Model.GridData[i].Name) 
     @Html.ValidationMessageFor(x => Model.GridData[i].Name)  
    </div> 
    } 
} 

Bu formu oluşturmanın oldukça uzun bir yol olduğunu herkes benim için sözdizimi lütfen geliştirebilirim?

ardından html formu üretilir: Yukarıdaki html (her koleksiyonundan Modeli benzersiz kimliği ve adı var) uzaktan doğrulama ek alanları ile bir sorun olduğunda iyi oldukça bakar

<form method="post" action="/Admin/TableFormTest/"> <div> 
    <input type="hidden" value="1" name="GridData[0].Id" id="GridData_0__Id" data-val-required="The Id field is required." data-val-number="The field Id must be a number." data-val="true"> 
    <input type="text" value="abc" name="GridData[0].Name" id="GridData_0__Name" data-val-required="The Name field is required." data-val-remote-url="/Admin/TableFormTest/IsNameAvailable" data-val-remote-additionalfields="*.Name,*.Id" data-val-remote="&amp;#39;Name&amp;#39; is invalid." data-val-length-max="50" data-val-length="The field Name must be a string with a maximum length of 50." data-val="true"> 
    <span data-valmsg-replace="true" data-valmsg-for="GridData[0].Name" class="field-validation-valid"></span>  
</div> 
<div> 
    <input type="hidden" value="2" name="GridData[1].Id" id="GridData_1__Id" data-val-required="The Id field is required." data-val-number="The field Id must be a number." data-val="true"> 
    <input type="text" value="def" name="GridData[1].Name" id="GridData_1__Name" data-val-required="The Name field is required." data-val-remote-url="/Admin/TableFormTest/IsNameAvailable" data-val-remote-additionalfields="*.Name,*.Id" data-val-remote="&amp;#39;Name&amp;#39; is invalid." data-val-length-max="50" data-val-length="The field Name must be a string with a maximum length of 50." data-val="true"> 
    <span data-valmsg-replace="true" data-valmsg-for="GridData[1].Name" class="field-validation-valid"></span>  
</div> 

rağmen : İkinci satırda uzaktan doğrulama işlemi başlatıldığında, ilk satırdaki kimlik algılanır.

+0

DisplayTemplates ve ardından @Html kullanmayı deneyin.DisplayFor (model => model.GridData) – mimo

cevap

1

Öncelikle, evet, görünümünüzün sözdizimini geliştirebilirsiniz. EditorTemplates kullanın.

Views\Shared\EditorTemplates\GridRow.cshtml oluşturun:

@model TestMvc.Models.TableFormTestModel.GridRow 
<div> 
    @Html.HiddenFor(x => x.Id) 
    @Html.TextBoxFor(x => x.Name) 
    @Html.ValidationMessageFor(x => x.Name) 
</div> 

Şimdi ana görünüm yalnızca olması gerekiyor:

@model TableFormTestModel 
@using (Html.BeginForm()) 
{ 
    Html.EnableClientValidation(); 
    Html.EnableUnobtrusiveJavaScript(); 
    @Html.EditorFor(x => x.GridData) 
} 

RemoteAttribute sorunları gelince, bu zorlu. Sorun, MVC'nin diziler için yarattığı girdilerin adlarından kaynaklanıyor. Gördüğünüz gibi, girişleriniz örneğin GridData[1].Id, GridData[1].Name (etc) olarak adlandırılır. JQuery, ajax çağrısını bu isimleri querystring'e sağlayarak yapar.

Böylece ne denir almak biter

/Admin/TableFormTest/IsNameAvailable?GridData%5B1%5D.Name=sdf&GridData%5B1%5D.Id=5 

/Admin/TableFormTest/IsNameAvailable?GridData[1].Name=sdf&GridData[1].Id=5 

aka olduğunu ... ve varsayılan modeli bağlayıcı gerçekten ne yapacağını bilmiyor.

Öneririm, kendi özel model bağlayıcınızı yazmaktır. MVC'ye bu sorgu dizesini okumasını ve sonra istediğiniz nesneyi nasıl yapmasını söyleyin.

İşte bir kavram kanıtı. (Ama üretim bu şey kullanmayın: Çok fazla sayıda varsayımları alır ve beklenmedik bir şey üzerinde çökmesine ve yakacaktır.)

public class JsonGridRowModelBinder : IModelBinder { 

    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { 
     var model = new TableFormTestModel.GridRow(); 
     var queryString = controllerContext.HttpContext.Request.QueryString; 
     model.Name = queryString[queryString.AllKeys.Single(x => x.EndsWith("Name"))]; 
     string id = queryString[queryString.AllKeys.Single(x => x.EndsWith("Id"))]; 
     model.Id = string.IsNullOrWhiteSpace(id) ? 0 : int.Parse(id); 

     return model; 
    } 

} 

Sonra bu modeli cilt kullanmak için IsNameAvailable yöntemini anlatmak:

public JsonResult IsNameAvailable([ModelBinder(typeof(JsonGridRowModelBinder))] TableFormTestModel.GridRow gridRow) { 
    ... 
}