Завантаження файлів 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 повинні відповідати


2
Це рішення - єдине рішення, яке я знайшов для декількох файлів. Дякуємо, що поділилися своїм кодом.
Рожан Гх.

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

} 

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

1

Перше завантаження файлу jquery.form.js знизу за адресою

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)
            {

            }
        }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.