在编辑器模板中使用文件上传器

时间:2019-02-27 00:14:51

标签: c# asp.net-mvc

我正在处理文档。我已经为DocumentViewModel工作CRUD-到目前为止很好。将有其他具有文档作为属性的模型。我不想重复自己,所以我将DocumentViewModel的“编辑视图”转换为编辑器模板。

现在,我正在研究LeaseViewModel,它具有类型LeaseDocument的属性DocumentViewModel。脚手架的“创建”视图可正确拉入编辑器模板。但是,我在控制器的POST Create方法中遇到问题。填充了所有简单的LeaseViewModel属性,并且填充了LeaseDocument属性的大多数子属性,但是DocumentUpload为空。有什么想法吗?

查看模型:

public class DocumentViewModel
{

    #region Properties
    public int? ItemID { get; set; }

    [Required(ErrorMessage = "Name is required")]
    public string Name { get; set; }
    public string Description { get; set; }

    [Display(Name = "Version Number")]
    public int Version_Number { get; set; }

    // TODO: culture code?

    [Display(Name = "Document")]
    [DataType(System.ComponentModel.DataAnnotations.DataType.Upload)]
    public HttpPostedFileBase DocumentUpload { get; set; }
    ...
}

public class LeaseViewModel
{
    #region Properties
    public int ItemID { get; set; }
    [Display(Name = "Space")]
    [Required]
    public int SpaceID { get; set; }
    [Display(Name = "Status")]
    [Required]
    public int StatusID { get; set; }
    public string StatusText { get; private set; }
    [Display(Name = "Type")]
    [Required]
    public int TypeID { get; set; }
    public string TypeText { get; private set; }
    public DocumentViewModel LeaseDocument { get; set; }
    ...
}

控制器:

[Authorize]
public class LeasesController : Controller
{
    ...

    // POST: Lease/Create
    [HttpPost]
    [ValidateAntiForgeryToken]
    [ValidateInput(true)]
    public ActionResult Create(LeaseViewModel vm)
    {
        LeaseItem created = createLeaseVersion(vm);
        if (created == null)
            return View(vm);
        else
            return RedirectToAction("Index");
    }
    ...
}

查看:

@using CMS.CustomTables;
@using CMS.CustomTables.Types.Tenantportal;
@using CMS.DocumentEngine.Types.Tenantportal;
@model TenantPortal.Models.LeaseViewModel

@{
    ViewBag.Title = "Documents";

    var emptySpaceOpts = new SelectList(new List<CustomTableItem>(), "ItemID", "Identifier");
    var tenantOpts = new SelectList(TenantProvider.GetTenants(), "ItemID", "Display_Name");
    var statusOpts = new SelectList(CustomTableItemProvider.GetItems<LeaseStatusItem>(), "ItemID", "Name");
    var typeOpts = new SelectList(CustomTableItemProvider.GetItems<LeaseTypeItem>(), "ItemID", "Name");
}

<h2 class="page-title">Create Lease</h2>

@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()

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

        @Html.EditorFor(model => model.LeaseDocument)

        <div class="form-group">
            @Html.LabelFor(model => model.SpaceID, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownListFor(model => model.SpaceID, emptySpaceOpts, "(select Property)")
                @Html.ValidationMessageFor(model => model.SpaceID, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.StatusID, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownListFor(model => model.StatusID, statusOpts)
                @Html.ValidationMessageFor(model => model.StatusID, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.TypeID, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownListFor(model => model.TypeID, typeOpts)
                @Html.ValidationMessageFor(model => model.TypeID, "", new { @class = "text-danger" })
            </div>
        </div>

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

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

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

        <div class="form-group">
            @Html.LabelFor(model => model.CanViewCapBudget, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                <label>
                    @Html.RadioButtonFor(model => model.CanViewCapBudget, "true")
                    Yes
                </label>
                <label>
                    @Html.RadioButtonFor(model => model.CanViewCapBudget, "false", htmlAttributes: new { @checked = "checked" })
                    No
                </label>
                @Html.ValidationMessageFor(model => model.CanViewCapBudget, "", new { @class = "text-danger" })
            </div>
        </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>
}

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

DocumentViewModel的编辑器模板

@using TenantPortal.Models
@using CMS.DocumentEngine.Types.Tenantportal
@model DocumentViewModel

@{

    var signedOpts = DocumentViewModel.GetSignedOpts();

    var propertyOpts = new SelectList(PropertyProvider.GetProperties().Columns("ItemID", "Identifier"), "ItemID", "Identifier");

    var tenantOpts = new SelectList(TenantProvider.GetTenants(), "ItemID", "Display_Name");

    bool isEdit = ViewContext.Controller.ValueProvider.GetValue("action").RawValue.ToString() == "Edit";

    object uploaderAtts;
    int version;
    if (isEdit)
    {

        uploaderAtts = new { @type = "file", @class = "form-control" };
        Model.Version_Number += 1;
        version = Model.Version_Number;
    }
    else
    {
        uploaderAtts = new { @type = "file", @required = "required", @class = "form-control" };
        version = 1;
    }
}

@Html.HiddenFor(model => model.ItemID)

<div class="form-group row">
    <div class="col-sm-12 col-md-6 field">
        @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label" })
        @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
    </div>

    <div class="col-sm-12 col-md-6 field">
        @Html.LabelFor(model => model.Description, htmlAttributes: new { @class = "control-label" })
        @Html.EditorFor(model => model.Description, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Description, "", new { @class = "text-danger" })
    </div>
</div>

<div class="form-group row">
    <div class="col-sm-12 col-md-6 field">
        @Html.LabelFor(model => model.Version_Number, htmlAttributes: new { @class = "control-label" })
        @Html.EditorFor(model => model.Version_Number, new { htmlAttributes = new { @class = "form-control", @readonly = "readonly", @Value = version } })
        @Html.ValidationMessageFor(model => model.Version_Number, "", new { @class = "text-danger" })
    </div>

    <div class="col-sm-12 col-md-6 field">
        @Html.LabelFor(model => model.DocumentUpload, htmlAttributes: new { @class = "control-label" })
        @(isEdit ? Html.Raw(String.Format("<a href='{0}' download='{1}'>{1}</a>", Model.Document_Url, Model.Original_File_Name)) : new HtmlString(""))
        @Html.TextBoxFor(model => model.DocumentUpload, uploaderAtts)
        @Html.ValidationMessageFor(model => model.DocumentUpload, "", new { @class = "text-danger" })
    </div>
</div>

<div class="form-group row">
    <div class="col-sm-12 col-md-4 field">
        @Html.LabelFor(model => model.Signed, htmlAttributes: new { @class = "control-label" })
        @Html.DropDownListFor(model => model.Signed, signedOpts, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Signed, "", new { @class = "text-danger" })
    </div>

    <div class="col-sm-12 col-md-4 field">
        @Html.LabelFor(model => model.PropertyID, htmlAttributes: new { @class = "control-label" })
        @Html.DropDownListFor(model => model.PropertyID, propertyOpts, "(none)")
        @Html.ValidationMessageFor(model => model.PropertyID, "", new { @class = "text-danger" })
    </div>

    <div class="col-sm-12 col-md-4 field">
        @Html.LabelFor(model => model.TenantID, htmlAttributes: new { @class = "control-label" })
        @Html.DropDownListFor(model => model.TenantID, tenantOpts, "(none)")
        @Html.ValidationMessageFor(model => model.TenantID, "", new { @class = "text-danger" })
    </div>
</div>

1 个答案:

答案 0 :(得分:0)

如果您的form发送file,则必须将其enctype设置为multipart/form-data

例如

@using (Html.BeginForm("Action", "Controller", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
  ...

Hth ...