【问题标题】:Mvc 4 dynamic form file uploadmvc 4 动态表单文件上传
【发布时间】:2013-03-13 15:12:44
【问题描述】:

我正在构建一个站点,用户可以在其中填写从数据库动态生成的多页表单。我使用 JQuery 将数据发布到我的控制器并返回表单的下一页。它适用于除文件之外的所有内容。

问题是将文件发布到我的控制器,我正在使用来自 this post 的 HtmlHelpers 为文件字段生成 html。

我的模型:

public class QuestionPage
{
    public const string Next = "next";
    public const string Prev = "prev";
    public const string Save = "save";

    public int currentID { get; set; }
    public bool advanced { get; set; }
    public QuestionPageItem[] questions { get; set; }
    public int pagenumber { get; set; }
    public int? next {  get; set; }
    public int? prev { get; set; }

    public string submitaction { get; set; }
    public int? gotoID { get; set; }

    public Dictionary<Int32, QuestionPageTitle> titles { get; set; }
}

public class QuestionPageItem
{
    public int id { get; set; }
    public string question { get; set; }
    public string description { get; set; }
    public bool required { get; set; }
    public QuestionType type { get; set; }
    public object answer { get; set; }
    public int? enableID { get; set; }
    public bool initHidden { get; set; }
    public QuestionOptionIndexModel[] options { get; set; }
}

我的静态视图:

using (Html.BeginForm("Form", "QuestionPage", new { id = Model }, FormMethod.Post, new { id = "frm" + Model, name = Model, enctype = "multipart/form-data" }))
{
    <div id="formcontainer">
        @Html.Partial("_FormPartial", Model)
    </div>
} 

我的局部视图 (_FormPartial) 被 jQuery ajax 取代,简化:

    @model DPDF.Models.QuestionPage
    Some hidden fields...
    @for (int i = 0; i < Model.questions.Length; i++)
    {
        var question = Model.questions[i];
        Some hidden fields...
        <tr class="@(question.initHidden ? "hidden" : "")" id="@(question.id)" >
            show textbox or textarea or radio etc depending on question type, for instance
            @Html.TextBox("questions[" + i + "].answer", (question.answer == null ? string.Empty : question.answer.ToString()))
            in case of file field
            @Html.FileBox("questions[" + i + "].answer")
        </tr>
    }

数据被绑定到问题对象中的答案字段。 我的控制器操作:

    [AllowAnonymous]
    public ActionResult Form(QuestionPage model)
    {

        if (!ModelState.IsValid)
            return View(model);

        // this is to make some hidden fields get the correct new values
        ModelState.Clear();

        // do stuff to determine what page to show next...
        // save data, extract value from model.answer object depending on question type
        // make new model and return it
        if (Request.IsAjaxRequest())
            return PartialView("_FormPartial", model);
        return View(model);
    }

文本框等普通字段返回类似 String[]{"test"} 的内容,文件字段返回 null。

编辑: 也许问题出在javascript上?这是发布到服务器的代码:

    var $form = $(form);
    var $container = $('#formcontainer');
    $container.hide('slide', { direction: direction }, 500, function () {
        $.ajax({
            url: $form.attr('action'),
            type: $form.attr('method'),
            data: $form.serialize(),
            success: function (data, textStatus, jqXHR) {
                $container.html(data);
                updateOverzicht();
                $container.show('slide', { direction: (direction == 'left') ? 'right' : 'left' }, 500);
            }
        });
    });

【问题讨论】:

    标签: c# jquery asp.net-mvc razor asp.net-mvc-4


    【解决方案1】:

    QuestionPageItem 类中answer 的类型更改为HttpPostedFiledBase object

    public HttpPostedFileBase answer { get; set; }
    

    实际上:他真正的问题是因为他试图在 jQuery 中提交表单作为 Ajax 请求的一部分。

    【讨论】:

    • 这是否适用于从文本框中检索字符串和从复选框列表中检索字符串数组?
    • @Blight 不,因为你的每个字段都必须有@Html.HiddenFor(m =&gt; Model.questions[i].FieldName) :)
    • 您能告诉我如何使用隐藏字段检索用户发布的信息吗?
    • 我使用对象的原因是我事先不知道会发布什么,我希望当我看到类型是 QuestionType.File 时可以将其转换为 HttpPostedFileBase...
    • 隐藏字段由模型绑定器自动绑定到模型。因此,如果您浏览已发布的内容,那么您应该会在您发布的模型中看到该值。
    【解决方案2】:

    正如mattytommo所说,这种方式无法上传文件。

    我想我会使用 JQuery 插件在页面上上传文件而不发布它。

    感谢 mattytommo 的帮助。

    我不确定是否应该将他的答案标记为正确,因为问题已在 cmets 中解决。

    【讨论】:

      【解决方案3】:

      文件字段必须被索引,否则不会上传到服务器

      <input type="file" name="Document_Path[0]" class="form-control" />
      <input type="file" name="Document_Path[1]" class="form-control" />
      <input type="file" name="Document_Path[2]" class="form-control" />
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-18
        • 2019-04-16
        • 2013-03-14
        • 2017-02-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多