Файл веб-API ASP.NET, сохраненный как "BodyPart_3ded2bfb-40be-4183-b789-9301f93e90af"
Я загружаю файлы с помощью ASP.NET Web API. Я сделал это перед RC, но по какой-то причине файл сохраняется как "BodyPart_3ded2bfb-40be-4183-b789-9301f93e90af" вместо имени файла. Переменная filename ниже возвращает эту строку bodypart, а не имя файла. Я не могу понять, где я ошибаюсь. Любая помощь приветствуется.
Клиентский код:
function upload() {
$("#divResult").html("Uploading...");
var formData = new FormData($('form')[0]);
$.ajax({
url: 'api/files/uploadfile?folder=' + $('#ddlFolders').val(),
type: 'POST',
success: function (data) {
$("#divResult").html(data);
},
data: formData,
cache: false,
contentType: false,
processData: false
});
};
Контроллер:
public Task<HttpResponseMessage> UploadFile([FromUri]string folder)
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.UnsupportedMediaType));
}
// Save file
MultipartFormDataStreamProvider provider = new MultipartFormDataStreamProvider(HttpContext.Current.Server.MapPath("~/Files"));
Task<IEnumerable<HttpContent>> task = Request.Content.ReadAsMultipartAsync(provider);
return task.ContinueWith<HttpResponseMessage>(contents =>
{
string filename = provider.BodyPartFileNames.First().Value;
return new HttpResponseMessage()
{
Content = new StringContent(string.Format("File saved in {0}.", folder))
};
}, TaskScheduler.FromCurrentSynchronizationContext());
Файлы выглядят так:
![enter image description here]()
Ответы
Ответ 1
Это было убедительное изменение, которое мы сделали - считалось, что риск безопасности взять имя файла, указанное в поле заголовка Content-Disposition, и поэтому вместо этого мы теперь вычислим имя файла, которое вы видите.
Если вы хотите самостоятельно управлять именем локального файла сервера, вы можете получить из MultipartFormDataStreamProvider и переопределить GetLocalFileName, чтобы предоставить любое имя, которое вы хотите. Обратите внимание, что это могут быть соображения безопасности.
Надеюсь, что это поможет,
Хенрик
Ответ 2
Я обновил код учебника, чтобы он работал с ASP.NET Web API RC. Действительно, как отметил Хенрик, Content-Disposition больше не используется имя файла. См. Исходные файлы в нижней части сообщения - http://www.strathweb.com/2012/04/html5-drag-and-drop-asynchronous-multi-file-upload-with-asp-net-webapi/
Обратите внимание, что в MultipartFormDataStreamProvider внесены дополнительные изменения, которые не сделали разрезание на RC, поэтому теперь он еще более гибкий. Хенрик писал о них здесь - http://blogs.msdn.com/b/henrikn/archive/2012/04/27/asp-net-web-api-updates-april-27.aspx.
РЕДАКТИРОВАТЬ: Я написал о новых и улучшенных способах загрузки файлов в RTM для веб-API, так что, надеюсь, поможет организовать все, что угодно - http://www.strathweb.com/2012/08/a-guide-to-asynchronous-file-uploads-in-asp-net-web-api-rtm/
Ответ 3
Здесь эта работа для меня
В API-интерфейсе
// We implement MultipartFormDataStreamProvider to override the filename of File which
// will be stored on server, or else the default name will be of the format like Body-
// Part_{GUID}. In the following implementation we simply get the FileName from
// ContentDisposition Header of the Request Body.
public class CustomMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
{
public CustomMultipartFormDataStreamProvider(string path) : base(path) { }
public override string GetLocalFileName(HttpContentHeaders headers)
{
return headers.ContentDisposition.FileName.Replace("\"", string.Empty);
}
}
Тогда
string root = HttpContext.Current.Server.MapPath("~/App_Data");
CustomMultipartFormDataStreamProvider provider = new CustomMultipartFormDataStreamProvider(root);
Спасибо,