我在传递包含"文件列表的视图模型时遇到问题"从我的视图到我的控制器(动作)。除了list(List Files)之外,viewmodel似乎被传递给具有所有propetries的actionresult。即使模型在提交表单时包含文件,列表也保持为空。
我做错了什么?我将从我的控制器,模型,视图模型和我的RazorHTML中粘贴我的c#代码。
文件的模型:
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; }
}
视图模型:
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; }
}
查看:
@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")
}
控制器
[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 });
}
- 编辑 -
我还尝试为每个文件中的每个属性添加编辑器字段,如下所示:
@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>
}
答案 0 :(得分:0)
您的文件属于ICollection类型,因此每个文件信息都需要存在于表单中,以便能够在填充的视图模型中发布到控制器。目前,您没有此集合的字段,并且在发布到控制器时ICollection为空。您可以创建自定义EditorFor以显示文件数据,也可以将此数据发布到控制器。
请参阅本教程,了解如何执行此操作:
http://blog.learningtree.com/en/editing-collections-in-asp-net-mvc/
在您的代码中,您正在为复选框执行类似的操作:
@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>
}
请注意隐藏字段,这是将数据传递给控制器以获取复选框列表的内容。我建议为文件创建一个自定义EditorFor。或者更简单地从模型中再次在控制器中重新填充文件集。
答案 1 :(得分:0)
但是Files集合不在任何输入中。它们基本上只是标签,因此它们不会发布到服务器。由于它们不会被用户更改,因此您只需在操作中再次从DB加载文件即可。