2016-03-30 3 views
0

Ich habe Probleme beim Übergeben eines Viewmodels, das eine Liste von "Dateien" aus meiner Sicht an meinen Controller (Aktion) enthält. Das Viewmodel scheint mit allen Proprietas außer der Liste (List Files) an das Actionresult übergeben zu werden. Die Liste bleibt einfach null, auch wenn das Modell beim Senden des Formulars Dateien enthält.ViewModel mit Liste kann nicht an Controller-Aktion (MVC 5) übergeben werden

Was mache ich falsch? Ich werde meinen C# Code von meinem Controller, Modell, Viewmodel und meinem RazorHTML einfügen.

Datei-Modell:

public class File 
{ 
    [Key] 
    public int ID { get; set; } 
    [Display(Name = "Filnamn")] 
    public string Filename { get; set; } 
    //[Display(Name = "Beskrivning")] 
    //public string Description { get; set; } 
    [Display(Name = "Filtyp")] 
    public string ContentType { get; set; } 
    public byte[] Data { get; set; } 
    public int Size { get; set; } 

    //public string CreatorId { get; set; } 

    public string CreatorID { get; set; } 
    [Required] 
    [Display(Name = "Skapare")] 
    [ForeignKey("CreatorID")] 
    public virtual ApplicationUser Creator { get; set; } 

    //public int DocumentId { get; set; } 

    public int DocumentID { get; set; } 
    [Required] 
    [Display(Name = "Dokument")] 
    [ForeignKey("DocumentID")] 
    public virtual Document Document { get; set; } 
} 

Ansichtsmodell:

public class CreateDocumentViewModel 
{ 
    public CreateDocumentViewModel() 
    { 
     CheckboxUsers = new List<CheckBoxListUser>(); 
     CheckboxGroups = new List<CheckBoxListGroup>(); 
     CheckboxTags = new List<CheckBoxListTags>(); 
     Files = new List<File>(); 
    } 

    [Display(Name = "Beskrivning")] 
    public string Description { get; set; } 
    [Display(Name = "Titel")] 
    public string Name { get; set; } 
    [DataType(DataType.MultilineText)] 
    [Display(Name = "Markdown")] 
    public string Markdown { get; set; } 
    HttpPostedFileBase FileToAdd { get; set; } 

    [Display(Name="Användare")] 
    public List<CheckBoxListUser> CheckboxUsers { get; set; } 
    [Display(Name = "Grupper")] 
    public List<CheckBoxListGroup> CheckboxGroups { get; set; } 
    [Display(Name = "Taggar")] 
    public List<CheckBoxListTags> CheckboxTags { get; set; } 
    [Display(Name = "Filer")] 
    public ICollection<File> Files { get; set; } 
    public string FilesJson { get; set; } 
} 

Ausblick:

@model MarkdownManagerNew.Viewmodels.CreateDocumentViewModel 

@{ 
    ViewBag.Title = "CreateDocument"; 
} 

<h2>Nytt dokument</h2> 


@Html.BeginForm("CreateFile", "User", new { model = Model, test = Model.Name, files = Model.Files }, FormMethod.Post, new { enctype = "multipart/form-data" })) 
{ 
@Html.AntiForgeryToken() 

<div class="form-horizontal"> 
    @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 

    <div class="form-group"> 
     <div class="col-md-10"> 
      @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control", placeholder = "Titel" } }) 
      @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" }) 
     </div> 
    </div> 

    <div class="form-group"> 
     <div class="col-md-10"> 
      @Html.EditorFor(model => model.Description, new { htmlAttributes = new { @class = "form-control", placeholder = "Beskrivning" } }) 
      @Html.ValidationMessageFor(model => model.Description, "", new { @class = "text-danger" }) 
     </div> 
    </div> 

    <div class="row"> 
     <div class="col-sm-12"> 
      <div class="form-group col-md-6 markdownEditorForm"> 
       <div class="col-md-12"> 
        @Html.EditorFor(model => model.Markdown, new { htmlAttributes = new { @class = "form-control markdownEditor" } }) 
        @Html.ValidationMessageFor(model => model.Markdown, "", new { @class = "text-danger" }) 
       </div> 
      </div> 
      <div class="col-sm-6 markdownResult"></div> 
     </div> 
    </div> 

    <div class="row"> 
     <dl class="dl-horizontal"> 
      <dt> 
       @Html.DisplayNameFor(model => model.CheckboxGroups) 
      </dt> 

      @for (int i = 0; i < Model.CheckboxGroups.Count; i++) 
      { 
       <dd> 
        @Html.CheckBoxFor(x => x.CheckboxGroups[i].IsChecked) 
        @Html.HiddenFor(x => x.CheckboxGroups[i].ID) 
        @Html.HiddenFor(x => x.CheckboxGroups[i].Display) 

        @Html.DisplayFor(x => x.CheckboxGroups[i].Display) 
       </dd> 
      } 


      <dt> 
       @Html.DisplayNameFor(model => model.CheckboxUsers) 
      </dt> 

      @for (int i = 0; i < Model.CheckboxUsers.Count; i++) 
      { 
       <dd> 
        @Html.CheckBoxFor(x => x.CheckboxUsers[i].IsChecked) 
        @Html.HiddenFor(x => x.CheckboxUsers[i].ID) 
        @Html.HiddenFor(x => x.CheckboxUsers[i].Display) 

        @Html.DisplayFor(x => x.CheckboxUsers[i].Display) 
       </dd> 
      } 

      <dt> 
       @Html.DisplayNameFor(model => model.CheckboxTags) 
      </dt> 

      @for (int i = 0; i < Model.CheckboxTags.Count; i++) 
      { 
       <dd> 
        @Html.CheckBoxFor(x => x.CheckboxTags[i].IsChecked) 
        @Html.HiddenFor(x => x.CheckboxTags[i].ID) 
        @Html.HiddenFor(x => x.CheckboxTags[i].Display) 

        @Html.DisplayFor(x => x.CheckboxTags[i].Display) 
       </dd> 
      } 

     </dl> 
    </div> 

    <div class="form-group"> 
     @Html.Label("File", new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      <input type="file" id="File" name="upload" /> 
     </div> 
    </div> 

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

    <div class="form-group"> 
     <div class="col-md-10"> 
      @if (Model.Files.Count > 0) 
      { 
       <h3>@Html.DisplayNameFor(model => model.Files)</h3> 
       <table class="table table-striped table-bordered"> 
        <tr> 
         <th>Filename</th> 
         <th>Filetype</th> 
         <th>Size(bytes)</th> 
        </tr> 

        @foreach (var file in Model.Files) 
        { 
         <tr> 
          <td>@file.Filename</td> 
          <td>@file.ContentType</td> 
          <td>@file.Size</td> 
         </tr> 
        } 

       </table> 
      } 
     </div> 
    </div> 

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


<div> 
    @Html.ActionLink("Back to List", "Index") 
</div> 

@section Scripts { 
    @Scripts.Render("~/bundles/jqueryval") 
} 

-Controller

[HttpPost] 
    public ActionResult CreateFile(CreateDocumentViewModel viewModel) 
    { 
     var file = repo.CreateFile(upload, GetCurrentUser()); 
     viewModel.Files.Add(file); 
     TempData["viewModel"] = viewModel; 

     //return RedirectToAction("CreateDocument", file); 
     return RedirectToAction("CreateDocument", new { files = viewModel.Files }); 

    } 

-EDIT-

Ich habe auch versucht editorfields für jede Eigenschaft in jeder Datei wie folgt ergänzt:

@for (int i = 0; i < Model.Files.Count; i++) 
{ 
    <div> 

     @Html.LabelFor(x => x.Files[i].DocumentID) 
     @Html.EditorFor(x => x.Files[i].DocumentID) 
     @Html.ValidationMessageFor(x => x.Files[i].DocumentID) 
     @Html.LabelFor(x => x.Files[i].CreatorID) 
     @Html.EditorFor(x => x.Files[i].CreatorID) 
     @Html.ValidationMessageFor(x => x.Files[i].CreatorID) 
     @Html.LabelFor(x => x.Files[i].ID) 
     @Html.EditorFor(x => x.Files[i].ID) 
     @Html.ValidationMessageFor(x => x.Files[i].ID) 
     @Html.LabelFor(x => x.Files[i].ContentType) 
     @Html.EditorFor(x => x.Files[i].ContentType) 
     @Html.ValidationMessageFor(x => x.Files[i].ContentType) 
     @Html.LabelFor(x => x.Files[i].CreatorID) 
     @Html.EditorFor(x => x.Files[i].CreatorID) 
     @Html.ValidationMessageFor(x => x.Files[i].CreatorID) 
     @Html.LabelFor(x => x.Files[i].Data) 
     @Html.EditorFor(x => x.Files[i].Data) 
     @Html.ValidationMessageFor(x => x.Files[i].Data) 
     @Html.LabelFor(x => x.Files[i].Filename) 
     @Html.EditorFor(x => x.Files[i].Filename) 
     @Html.ValidationMessageFor(x => x.Files[i].Filename) 
     @Html.LabelFor(x => x.Files[i].Size) 
     @Html.EditorFor(x => x.Files[i].Size) 
     @Html.ValidationMessageFor(x => x.Files[i].Size) 
    </div> 
} 

Antwort

0

Ihre Dateien also vom Typ ICollection jeweils Dateiinformationen in der Form vorhanden sein muss in der Lage sein, auf dem Controller im bevölkerten Viewmodel gepostet werden. Derzeit haben Sie keine Felder für diese Sammlung und die ICollection ist leer, wenn sie auf dem Controller veröffentlicht wird. Sie können einen benutzerdefinierten Editor erstellen, um die Dateidaten anzuzeigen und diese Daten auf dem Controller zu veröffentlichen.

Bitte auf diese Anleitung, wie dies zu tun:

http://blog.learningtree.com/en/editing-collections-in-asp-net-mvc/

In Ihrem Code Sie etwas ähnliches für die Kontrollkästchen zu tun sind:

@for (int i = 0; i < Model.CheckboxUsers.Count; i++) 
{ 
    <dd> 
     @Html.CheckBoxFor(x => x.CheckboxUsers[i].IsChecked) 
     @Html.HiddenFor(x => x.CheckboxUsers[i].ID) 
     @Html.HiddenFor(x => x.CheckboxUsers[i].Display) 

     @Html.DisplayFor(x => x.CheckboxUsers[i].Display) 
    </dd> 
} 

Beachten Sie die verborgenen Felder, dies ist Was leitet die Daten an den Controller für die Liste der Checkboxen weiter? Ich würde empfehlen, einen benutzerdefinierten Editor für die Dateien zu erstellen. Oder füllen Sie einfach die Sammlung von Dateien erneut in Ihrem Controller aus dem Modell.

+0

Ich habe versucht, Edit-Felder für jede Eigenschaft in jeder Datei hinzuzufügen. Aber es scheint immer noch nicht so, als würden die Dateien zum Controller durchgehen. – filemilk

+0

Ah, scheint, als hätte ich es jetzt funktioniert! Vielen Dank! – filemilk

0

Aber die Dateien Sammlung ist nicht in irgendwelchen Eingaben. Sie sind im Grunde nur Etiketten, daher werden sie nicht zum Server posten. Da sie sich nicht vom Benutzer ändern, können Sie die Dateien einfach erneut aus der DB in Ihre Aktion laden.

+0

Ah, ich verstehe. Aber die Dateien existieren noch nicht in der DB. Sie haben die Möglichkeit, Dateien in ein temporäres Dokument hochzuladen. Dann erstellen Sie das Dokument mit den darin enthaltenen Dateien. Nur dann sind die Dateien in der Datenbank vorhanden. Wie kann ich die Dateien zu einer Eingabe machen, damit sie mit dem Modell übergeben wird? Ich habe versucht, eine versteckte Eingabe ohne Erfolg zu machen. Vielleicht mache ich es falsch? – filemilk

+0

Scheint wie eine andere Frage, die Sie fragen, und ich bin nicht klar, was es ist. –