I am having problem passing a viewmodel that contains a list of "files" from my view to my controller(action). The viewmodel seems to be passed to the actionresult with all the propetries, except the list (List Files). The list just stays null, even if the model contains files when i submit the form.
What do i do wrong? I will paste my c# code from my controller, model, viewmodel and my RazorHTML.
File-model:
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; }
}
Viewmodel:
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; }
}
View:
@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-
I have also tried adding editorfields for every property in every file like this:
@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>
}