Загрузка файла MVC 3 и привязка модели

91

У меня есть загрузка формы, которая работает, но я хотел бы передать информацию о модели для моей базы данных, чтобы сохранить файл, конечно, под другим именем.

Вот мой вид Razor:

@model CertispecWeb.Models.Container

@{
  ViewBag.Title = "AddDocuments";
}

<h2>AddDocuments</h2>

@Model.ContainerNo

@using (Html.BeginForm("Uploadfile", "Containers", FormMethod.Post, 
            new { enctype = "multipart/form-data" }))
{
    <input type='file' name='file' id='file' />
    <input type="submit" value="submit" />
}

Вот мой контроллер:

[HttpPost]
public ActionResult Uploadfile(Container containers, HttpPostedFileBase file)
{
     if (file.ContentLength > 0)
     {
        var fileName = Path.GetFileName(file.FileName);
        var path = Path.Combine(Server.MapPath("~/App_Data/Uploads"),
                       containers.ContainerNo);
        file.SaveAs(path);
     }

     return RedirectToAction("Index");
}

Информация о модели не передается в контроллер. Я прочитал, что мне может потребоваться обновить модель, как мне это сделать?

Фрэнсис
источник
2
Обратитесь к stackoverflow.com/questions/9411563/… по связанной проблеме
LCJ

Ответы:

123

Ваша форма не содержит никаких тегов ввода, кроме файла, поэтому в действии вашего контроллера вы не можете ожидать получения чего-либо, кроме загруженного файла (это все, что отправляется на сервер). Один из способов добиться этого - включить скрытый тег, содержащий идентификатор модели, который позволит вам получить его из вашего хранилища данных внутри действия контроллера, которое вы публикуете (используйте это, если пользователь не должен изменять модель, но просто прикрепите файл):

@using (Html.BeginForm("Uploadfile", "Containers", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.HiddenFor(x => x.Id)
    <input type="file" name="file" id="file" />
    <input type="submit" value="submit" />
}

а затем в действии вашего контроллера:

[HttpPost]
public ActionResult Uploadfile(int id, HttpPostedFileBase file)
{
    Containers containers = Repository.GetContainers(id);
    ...
}

С другой стороны, если вы хотите разрешить пользователю изменять эту модель, вам нужно будет включить соответствующие поля ввода для каждого поля вашей модели, которое вы хотите отправить на сервер:

@using (Html.BeginForm("Uploadfile", "Containers", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.TextBoxFor(x => x.Prop1)
    @Html.TextBoxFor(x => x.Prop2)
    @Html.TextBoxFor(x => x.Prop3)
    <input type="file" name="file" id="file" />
    <input type="submit" value="submit" />
}

и тогда у вас будет связыватель модели по умолчанию, реконструирующий эту модель из запроса:

[HttpPost]
public ActionResult Uploadfile(Container containers, HttpPostedFileBase file)
{
    ...
}
Дарин Димитров
источник
1
Я получаю , fileкак nullи Request.Files.Countв 0 тоже, будет ли какой - либо разницы , если formэто AjaxFormи есть routeValues, а?
bjan
8

Решено

Модель

public class Book
{
public string Title {get;set;}
public string Author {get;set;}
}

Контроллер

public class BookController : Controller
{
     [HttpPost]
     public ActionResult Create(Book model, IEnumerable<HttpPostedFileBase> fileUpload)
     {
         throw new NotImplementedException();
     }
}

И просмотр

@using (Html.BeginForm("Create", "Book", FormMethod.Post, new { enctype = "multipart/form-data" }))
{      
     @Html.EditorFor(m => m)

     <input type="file" name="fileUpload[0]" /><br />      
     <input type="file" name="fileUpload[1]" /><br />      
     <input type="file" name="fileUpload[2]" /><br />      

     <input type="submit" name="Submit" id="SubmitMultiply" value="Upload" />
}

Обратите внимание, что заголовок параметра из действия контроллера должен совпадать с именем входных элементов IEnumerable<HttpPostedFileBase> fileUpload->name="fileUpload[0]"

fileUpload должен соответствовать

Isxaker
источник
2
Это единственное решение, которое я нашел для нескольких файлов. Спасибо, что поделились своим кодом.
Rojan Gh.
6

Если вы не всегда будете размещать изображения в вашем действии, вы можете сделать что-то вроде этого:

[HttpPost]
public ActionResult Uploadfile(Container container, HttpPostedFileBase file) 
{
    //do container stuff

    if (Request.Files != null)
    {
        foreach (string requestFile in Request.Files)
        {
            HttpPostedFileBase file = Request.Files[requestFile]; 
            if (file.ContentLength > 0)
            {
                string fileName = Path.GetFileName(file.FileName);
                string directory = Server.MapPath("~/App_Data/uploads/");
                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }
                string path = Path.Combine(directory, fileName);
                file.SaveAs(path);
            }
        }
    }

} 
jhatcher9999
источник
1

Для нескольких файлов; обратите внимание на более новый атрибут " множественный " для ввода:

Форма:

@using (Html.BeginForm("FileImport","Import",FormMethod.Post, new {enctype = "multipart/form-data"}))
{
    <label for="files">Filename:</label>
    <input type="file" name="files" multiple="true" id="files" />
    <input type="submit"  />
}

Контроллер:

[HttpPost]
public ActionResult FileImport(IEnumerable<HttpPostedFileBase> files)
{
    return View();
}
Mcfea
источник
1

1-й загрузите файл jquery.form.js из ниже URL-адреса

http://plugins.jquery.com/form/

Напишите ниже код в cshtml

@using (Html.BeginForm("Upload", "Home", FormMethod.Post, new { enctype = "multipart/form-data", id = "frmTemplateUpload" }))
{
    <div id="uploadTemplate">

        <input type="text" value="Asif" id="txtname" name="txtName" />


        <div id="dvAddTemplate">
            Add Template
            <br />
            <input type="file" name="file" id="file" tabindex="2" />
            <br />
            <input type="submit" value="Submit" />
            <input type="button" id="btnAttachFileCancel" tabindex="3" value="Cancel" />
        </div>

        <div id="TemplateTree" style="overflow-x: auto;"></div>
    </div>

    <div id="progressBarDiv" style="display: none;">
        <img id="loading-image" src="~/Images/progress-loader.gif" />
    </div>

}


<script type="text/javascript">

    $(document).ready(function () {
        debugger;
        alert('sample');
        var status = $('#status');
        $('#frmTemplateUpload').ajaxForm({
            beforeSend: function () {
                if ($("#file").val() != "") {
                    //$("#uploadTemplate").hide();
                    $("#btnAction").hide();
                    $("#progressBarDiv").show();
                    //progress_run_id = setInterval(progress, 300);
                }
                status.empty();
            },
            success: function () {
                showTemplateManager();
            },
            complete: function (xhr) {
                if ($("#file").val() != "") {
                    var millisecondsToWait = 500;
                    setTimeout(function () {
                        //clearInterval(progress_run_id);
                        $("#uploadTemplate").show();
                        $("#btnAction").show();
                        $("#progressBarDiv").hide();
                    }, millisecondsToWait);
                }
                status.html(xhr.responseText);
            }
        });

    });


</script>

Метод действия: -

 public ActionResult Index()
        {
            ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";

            return View();
        }

 public void Upload(HttpPostedFileBase file, string txtname )
        {

            try
            {
                string attachmentFilePath = file.FileName;
                string fileName = attachmentFilePath.Substring(attachmentFilePath.LastIndexOf("\\") + 1);

           }
            catch (Exception ex)
            {

            }
        }
Ace
источник