2016-08-17 6 views
0

Мне нужно представить список навыков. когда я пытаюсь сделать эту представленную модель, значение null. Но в Фидлере я вижу, что данные были отправлены.mvc 5, модель is List, отправленная модель null

public class MvcSkill 
{ 
    [HiddenInput(DisplayValue = false)] 
    public int Id { get; set; } 

    [Display(Name = "Category Name")] 
    [StringLength(128, ErrorMessage = "Max length - {0} symbols")] 
    [Required(ErrorMessage = "Please enter your last name")] 
    public string Name { get; set; } 

    public int Level { get; set; } 

    [Required(ErrorMessage ="Choose skill category")] 
    public string CategoryName { get; set; } 
} 

Частичный вид для каждого навыка (странный вход для уровня квалификации является самозагрузки-звездочный рейтинг:

@using MvcApp.Infrastructure; 
@model MvcApp.ViewModels.MvcSkill 

<tr> 
    <td> 
     @Html.HiddenFor(x => x.Id) 
    </td> 
    <td> 
     @Html.HiddenFor(x => x.Name) 
     @Html.DisplayFor(x => x.Name) 
    </td> 
    <td> 
     @Html.HiddenFor(x => x.CategoryName) 
     @Html.DisplayFor(x => x.CategoryName) 
    </td> 
    <td> 
     <input for="Level" id="@Model.Id" value="@Model.Level" name="Level" type="number" class="rating-loading" data-size="xs" data-min="0" data-max="5" data-step="1" data-show-clear="false"> 
    </td> 

    @{ 
     var identity = (CustomIdentity)User.Identity; 

     if (identity.Roles.FirstOrDefault(r => r == "Administrator") != null) 
     { 
      <td> 
       @Html.RouteLink("Edit", new { controller = "Administrator", action = "EditSkill", id = Model.Id }) 
      </td> 
      <td> 
       @Html.RouteLink("Remove", new { controller = "Administrator", action = "RemoveSkill", id = Model.Id }) 
      </td> 
     } 
    } 
</tr> 

Просмотр для списка навыков:

@model IList<MvcApp.ViewModels.MvcSkill> 

@{ 
    ViewBag.Title = "Skills"; 
} 
@using (Html.BeginForm("Index","Skill", Model)) 
{ 
    <table> 
     @foreach (var s in Model) 
     { 
      @Html.Partial("_Skill", s) 
     } 
    </table> 

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

@section scripts{ 
    <link href="http://netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" rel="stylesheet"> 
    <link href="~/Content/star-rating.css" media="all" rel="stylesheet" type="text/css" /> 
    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.js"></script> 
    <script src="~/Scripts/star-rating.js" type="text/javascript"></script> 
    @foreach (var item in Model) 
    { 
     string id = item.Id.ToString(); 
     <script> 
      $(document).on('ready', function() { 
       $('#@id').rating({ 
        step: 1, 
        defaultCaption: 'Unknown', 
        starCaptions: { 0: 'Unknown', 1: 'Beginner', 2: 'Elementary', 3: 'Intermediate', 4: 'Advanced', 5: 'Profi' }, 
        starCaptionClasses: function (val) { return 'text-success'; } 
       }).on('rating.change', function (event, value, caption) { 
        Model.Skills.FirstOrDefault(s => s.Key.Id.ToString() == id).Value = value; 
       }); 
      });    
     </script> 
    } 
} 

И метод контроллера:

[HttpPost] 
     public ActionResult Index(List<MvcSkill> skillModel) 
     { 
      //Do something... 

      return View(); 
     } 

Fidler Текст: Id = 1 & Имя = C% 2B% 2B & CategoryName = Programing & уровень = 5 & Id = 3 & Имя = РНР & CategoryName = Programing & Уровень = 3 & Id = 6 & Имя = JAVA & CategoryName = Programing & Level = 3 & Id = 7 & Name = Имя & CategoryName = .Net + Frameworks & Level = 5

+0

Вы можете взглянуть на [Редактирование списка переменных длины, ASP.NET MVC 2-style] (http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list -aspnet-2 MVC-стиль /). Он использует NuGet [BeginCollectionItem HtmlHelper] (https://www.nuget.org/packages/BeginCollectionItem/). Он предназначен для размещения списков переменной длины для другого действия контроллера MVC. –

+0

Вы не можете использовать цикл foreach для создания элементов управления формы для коллекции (см. [Этот ответ] (http://stackoverflow.com/questions/30094047/html-table-to-ado-net-datatable/30094943#30094943) - вам нужен цикл 'for' пользовательского' EditorTemplate' для typeof 'MvcSkill') –

ответ

3

Вы должны вручную добавить индексы так MVC структура может успешно связывать данные. Что-то вроде:

@using (Html.BeginForm("Index","Skill", Model)) 
{ 
    <table> 
     @for (int i = 0; i < Model.Length; i++) 
     { 
      <tr> 
       <td> 
        @Html.Hidden("[" + i + "].Id"); 
       </td>    
       <td> 
        @Html.DisplayFor(m => Model.ElementAt(i).Name) 
        @Html.Hidden("[" + i + "].Name"); 
       </td> 
       <td> 
        @Html.DisplayFor(m => Model.ElementAt(i).CategoryName) 
        @Html.Hidden("[" + i + "].CategoryName"); 
       </td> 
      </tr> 
     } 
    </table> 
} 

Или , как указано в комментариях вы можете использовать BeginCollectionItem (который я лично использую). То, что делает BeginCollectionItem, обычно добавляет GUIDs в качестве индекса для вас. Исходный код можно найти here, и вы можете с ним познакомиться here.

+0

Большое спасибо. Это помогает –

+0

@ Яков Штыков, я рад, что это помогло –