2

I'm building a site where users can fill in a multi-page form which is dynamically generated from a database. I use JQuery to post the data to my controller and return the next page of the form. It works fine for everything except files.

The problem is getting files to be posted to my controller, I'm using the HtmlHelpers from this post to generate the html for file fields.

My models:

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; }
}

My static view:

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>
} 

My partial view (_FormPartial) which gets replaced by jQuery ajax, simplified:

    @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>
    }

The data gets bound to the answer field in the question object. My controller action:

    [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);
    }

Normal fields like textboxes return something like String[]{"test"}, file fields return null.

EDIT: Perhaps the problem lies with javascript? This is the code that posts to the server:

    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);
            }
        });
    });

3 Answers 3

1

Change the type of answer inside the QuestionPageItem class to be of HttpPostedFiledBase not object:

public HttpPostedFileBase answer { get; set; }

ACTUALLY: His real problem is because he was trying to submit his form as part of an Ajax request in jQuery.

Sign up to request clarification or add additional context in comments.

12 Comments

Will this work for retrieving strings from textboxes and string arrays from checkbox lists?
@Blight Nope, for that you'll have to have @Html.HiddenFor(m => Model.questions[i].FieldName) for each of your fields :)
Could you show me how I can retrieve information posted by the user with a hidden field?
The reason I use an object is that I do not know before hand what will be posted, I was hoping I could cast it to HttpPostedFileBase when I see that the type is QuestionType.File...
Hidden fields are automatically bound to the model by the model binder. So if you browse what has been posted, then you should see the value in your posted model.
|
0

As mentioned by mattytommo, file upload is not possible in this way.

I think I will use a JQuery plugin to upload the files while still on the page without posting it.

I thank mattytommo for his help.

I am not sure if I should mark his answer as correct because the question is resolved in the comments.

Comments

0

File field must be indexed, otherwise it will not upload to server

<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" />

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.