2017-09-19 4 views
0

Utilisation d'une vue principale et d'une vue partielle pour ajouter dynamiquement des champs à ModelViews. Le problème est le ModelState.isValid renvoie toujours des chutes car il y a 2 champs dans la vue partielle qui échouent à la validation. Ces champs ne sont pas destinés à être obligatoires, donc je l'ai rendu nullable mais ils sont quand même validés. Comment peut-on surmonter cette situation?Validation toujours déclenchée pour les champs ajoutés dynamiquement avec vue partielle

code: Voir principal:

@model ViewModel.EnquiryVM 

@using (Html.BeginForm("Create", "Enquiries", FormMethod.Post)) 
{ 
    @Html.AntiForgeryToken() 

    <div class="form-horizontal"> 

     <hr /> 
     @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 
     <div class="form-group"> 
      @Html.LabelFor(model => model.EnquiryNumber, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-3"> 
       @Html.EditorFor(model => model.EnquiryNumber, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.EnquiryNumber, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.ClientID, "Client", htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-3"> 

       @Html.DropDownListFor(u => u.ClientID, (IEnumerable<SelectListItem>)Model.Clients, "--Select--") 
       @Html.ValidationMessageFor(model => model.ClientID, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div id="LineItems"> 
       <div id="editorRowsLineitems"> 
        @foreach (var item in Model.LineItems) 
        { 
         @Html.Partial("_CreateEnquiryItem", item) 
        } 
       </div> 
       @Html.ActionLink("Add Items", "CreateLineItem", null, new { id = "addItem", @class = "button" }); 

     </div> 
     <div class="form-group"> 
      <div class="col-md-offset-2 col-md-10"> 
       <input type="submit" value="Create" class="btn btn-default" /> 
      </div> 
     </div> 
    </div> 
} 

@section Scripts { 
    @Scripts.Render("~/bundles/jqueryval") 
<script type="text/javascript"> 
    $(function() { 
     $('#addItem').on('click', function() { 
      $.ajax({ 
       url: '@Url.Action("CreateLineItem")', 
        cache: false, 
        success: function (html) { 
         $("#editorRowsLineitems").append(html); 

         $('form').data('validator', null); 
         $.validator.unobtrusive.parse($('form')); 
        } 
       }); 
       return false; 
      }); 
     $('#editorRowsLineitems').on('click', '.deleteRow', function() { 
       $(this).closest('.editorRow').remove(); 
      }); 
     $('form').data('validator', null); 
     $.validator.unobtrusive.parse($('form')); 
    }); 


</script> 
} 

Vue partielle:

@model ViewModels.EnquiryLineItemVM 

<div class="editorRow"> 
    @using (Html.BeginCollectionItem("LineItems")) 
    { 
     <table class="table"> 

      <tr> 
       <td> 
        @Html.EditorFor(model => model.ItemDesc) 

       </td> 
       <td> 
        @Html.EditorFor(model => model.Quantity) 

       </td> 

       <td> 
        @Html.DropDownListFor(model => model.ManufacturerId, Model.ManufacturerList, "--Please Select--") 

       </td> 
       <td> 

        <a href="#" class="deleteRow">Delete</a> 
       </td> 
      </tr> 
     </table> 

    } 

ViewModels:

public class EnquiryVM 
    { 
     public int ID { get; set; } 

     [Required] 
     public string EnquiryNumber { get; set; } 
     public int ClientID { get; set; } 
     public IEnumerable<SelectListItem> Clients { get; set; } 
     public int ItemID { get; set; } 
     public List<EnquiryLineItem> LineItems { get; set; } 

    } 
    public class EnquiryLineItemVM 
    { 
     public int? EnquiryID { get; set; } //nullable but still validation fires 
     [Required] 
     public string ItemDesc { get; set; } 
     public int Quantity { get; set; } 
     public int? ManufacturerId { get; set; } // this too fires 
     public IEnumerable<SelectListItem> ManufacturerList { get; set; } 
    } 

action contrôleur Méthode

[HttpPost] 
     [ValidateAntiForgeryToken] 
     public ActionResult Create(EnquiryVM enquiryVM) 
     { 
      var errors = ModelState.Keys.Where(k => ModelState[k].Errors.Count > 0).Select(k => new { propertyName = k, errorMessage = ModelState[k].Errors[0].ErrorMessage });// for error debugging shows Validation errors for EnquiryID and ManufacturerID 
      var enquiry = new Enquiry(); 
      enquiry.EnquiryNumber = enquiryVM.EnquiryNumber; 
      enquiry.ClosingDate = enquiryVM.ClosingDate; 
      enquiry.RFQSentDate = enquiryVM.RFQSentDate; 
      enquiry.ClientID = enquiryVM.ClientID; 
      enquiry.DivisionID = enquiryVM.DivisionID; 
      enquiry.EnquiryLineItems = enquiryVM.LineItems; 

      if (ModelState.IsValid) 
      { 
       db.Enquiries.Add(enquiry); 
       enquiryVM.ID = enquiry.ID; 
       foreach (var item in enquiry.EnquiryLineItems) 
       { 
        if (enquiryVM.ID != null) 
        { 
         item.EnquiryID = (int)enquiryVM.ID; 
        } 
        db.EnquiryLineItems.Add(item); 
       } 

       db.SaveChanges(); 
       return RedirectToAction("Index"); 
      } 

      var viewModel = GetAllCategories(); 
      return View(viewModel); 
     } 

Impossible de résoudre ce problème. Merci pour votre temps.

ManufacturerID et EnquiryID est la relation FK utilisée dans Model, mais j'utilise ViewModels qui est nullable pour ces champs.

enter image description here

Répondre

1

Le LineItems propery de EnquiryVM est typeof List<EnquiryLineItem> mais le modèle que vous avez montré pour la collection est EnquiryLineItemVM, pas EnquiryLineItem.

Je suppose que vous EnquiryLineItem est un modèle de données et sur la base des ModelState erreurs dans l'image, à la fois EnquiryId et ManufacturerId ne sont pas marqués comme nullable dans ce modèle de données.

Changer votre EnquiryVM utiliser votre modèle de vue EnquiryLineItemVM

public class EnquiryVM 
{ 
    public int ID { get; set; } 
    [Required] 
    public string EnquiryNumber { get; set; } 
    .... 
    public List<EnquiryLineItemVM> LineItems { get; set; } // change 

} 
public class EnquiryLineItemVM 
{ 
    .... 
}