Как сделать загрузку файлов в ASP.NET MVC

3

Интересует решение задачи загрузки файлов в ASP.NET MVC. Какие тут есть тонкости и нюансы?

Progg it

Лучший ответ:

3

Подход, который описал Sergey, подразумевает работу с объектом Request в теле методов контроллера. И, хотя в оригинальной статье приводятся методики тестирования такого кода, сам подход не очень вписывается в концепцию MVC. Предлагаю альтернативное решение.

Во-первых, определяем класс, который будет содержать информацию о загружаемом файле:

public class FileData
{
    public FileData()
    {
    }

    public FileData(string name, long sizeInBytes, Stream inputStream)
    {
        Name = name;
        SizeInBytes = sizeInBytes;
        InputStream = inputStream;
    }

    public string Name { get; private set; }

    public long SizeInBytes { get; private set; }

    public Stream InputStream { get; private set; }
}

Затем пишем ModelBinder, который будет автоматически доставать из объекта Request информацию о файле и создавать соответствующий объект FileData:

public class FileDataModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var filePropertyName = bindingContext.ModelName;
        var file = controllerContext.HttpContext.Request.Files[filePropertyName];
        if (file != null && file.ContentLength > 0)
        {
            return new FileData(file.FileName, file.ContentLength, file.InputStream);
        }

        return null;
    }
}

Регистрируем binder в коде инициализации приложения:

ModelBinders.Binders.Add(typeof(FileData), new FileDataModelBinder());

Вид для загрузки файлов:

<%using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data", @class = "small" }))
  {%>
    <div>
        <label for="FileData">Файл</label>
        <input type="file" id="FileData" name="FileData" />
        <%=Html.ValidationMessage("FileData") %>
    </div>

    <input type="submit" value="Сохранить" />
<%} %>

Теперь, если соответствующий метод контроллера принимает аргумент типа FileData, то этот объект будет создан и заполнен автоматически.

public class FileController 
{
    public ActionResult Upload()
    {
        return View();
    }

    [AcceptPost]
    public ActionResult Upload(FileData fileData)
    {
        // Работаем с объектом fileData
    }
}

Новые ответы


1

Вот способ реализации на jquery — "Прикручиваем ajax-загрузку файлов в asp.net mvc, используя плагины к jQuery". В статье описывается реализация асинхронной загрузки, причем больше внимания уделяется именно клиентской части.

1

Controller:

public class ViewDataUploadFilesResult
{
    public string Name { get; set; }
    public int Length { get; set; }
}

public class HomeController : Controller
{
    public ActionResult UploadFiles()
    {
    	var r = new List<ViewDataUploadFilesResult>();

    	foreach (string file in Request.Files)
    	{
    		HttpPostedFileBase hpf = Request.Files[file] as HttpPostedFileBase;
    		if (hpf.ContentLength == 0)
    			continue;
    		string savedFileName = Path.Combine(
    			AppDomain.CurrentDomain.BaseDirectory, 
    			Path.GetFileName(hpf.FileName));
    			hpf.SaveAs(savedFileName);
    		r.Add(new ViewDataUploadFilesResult() 
    			{ Name = savedFileName, 
    				Length = hpf.ContentLength });
    	}
    return View("UploadedFiles",r);
    }
}

View:

<form  action="/home/uploadfiles" method="post" enctype="multipart/form-data">
    <label for="file">Filename:</label>
    <input type="file" name="file" id="file" />

    <input type="submit" name="submit" value="Submit" />
</form>

Подробнее можно прочитать в англоязычном блоге

admax

Код View не совсем тот:

<ul>
    <% foreach (ViewDataUploadFilesResult v in this.ViewData.Model)  { %>
    <%=String.Format("<li>Uploaded: {0} totalling {1} bytes.</li>",v.Name,v.Length) %>
    <%   } %>    
</ul>

Этот код отображает результат загрузки файлов, а не upload-форму.


v1.7.123.556
© 2009—2010 CodeHelper FAQ | О сайте | Обратная связь | История изменений | Статьи
Creative Commons LicenseМатериалы сайта распространяются под лицензией Creative Commons Attribution-Share Alike 3.0 Unported.