asp.net mvc 4 webapi 베타를 사용하여 나머지 서비스를 작성하고 있습니다. 클라이언트 응용 프로그램에서 POST 된 이미지 / 파일을 수락 할 수 있어야합니다. webapi를 사용하여 가능합니까? 아래는 현재 사용중인 작업입니다. 아무도 이것이 어떻게 작동하는지 예를 알고 있습니까?
[HttpPost]
public string ProfileImagePost(HttpPostedFile profileImage)
{
string[] extensions = { ".jpg", ".jpeg", ".gif", ".bmp", ".png" };
if (!extensions.Any(x => x.Equals(Path.GetExtension(profileImage.FileName.ToLower()), StringComparison.OrdinalIgnoreCase)))
{
throw new HttpResponseException("Invalid file type.", HttpStatusCode.BadRequest);
}
// Other code goes here
return "/path/to/image.png";
}
답변
http://www.asp.net/web-api/overview/formats-and-model-binding/html-forms-and-multipart-mime#multipartmime을 참조 하십시오 .하지만 기사가 조금 더 복잡해 보입니다. 정말입니다.
원래,
public Task<HttpResponseMessage> PostFile()
{
HttpRequestMessage request = this.Request;
if (!request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string root = System.Web.HttpContext.Current.Server.MapPath("~/App_Data/uploads");
var provider = new MultipartFormDataStreamProvider(root);
var task = request.Content.ReadAsMultipartAsync(provider).
ContinueWith<HttpResponseMessage>(o =>
{
string file1 = provider.BodyPartFileNames.First().Value;
// this is the file name on the server where the file was saved
return new HttpResponseMessage()
{
Content = new StringContent("File uploaded.")
};
}
);
return task;
}
답변
많은 사람들이 서버에 파일을 저장하고 싶어하는 것에 놀랐습니다. 모든 것을 메모리에 보관하는 솔루션은 다음과 같습니다.
[HttpPost("api/upload")]
public async Task<IHttpActionResult> Upload()
{
if (!Request.Content.IsMimeMultipartContent())
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
var provider = new MultipartMemoryStreamProvider();
await Request.Content.ReadAsMultipartAsync(provider);
foreach (var file in provider.Contents)
{
var filename = file.Headers.ContentDisposition.FileName.Trim('\"');
var buffer = await file.ReadAsByteArrayAsync();
//Do whatever you want with filename and its binary data.
}
return Ok();
}
답변
내가 찾을 수있는 가장 간단한 예제 코드를 보여주는 이 기사 에서 수정 한 아래 코드를 참조하십시오 . 파일 및 메모리 (빠른) 업로드가 모두 포함됩니다 .
public HttpResponseMessage Post()
{
var httpRequest = HttpContext.Current.Request;
if (httpRequest.Files.Count < 1)
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
foreach(string file in httpRequest.Files)
{
var postedFile = httpRequest.Files[file];
var filePath = HttpContext.Current.Server.MapPath("~/" + postedFile.FileName);
postedFile.SaveAs(filePath);
// NOTE: To store in memory use postedFile.InputStream
}
return Request.CreateResponse(HttpStatusCode.Created);
}
답변
ASP.NET Core 방식은 다음과 같습니다.
[HttpPost("UploadFiles")]
public async Task<IActionResult> Post(List<IFormFile> files)
{
long size = files.Sum(f => f.Length);
// full path to file in temp location
var filePath = Path.GetTempFileName();
foreach (var formFile in files)
{
if (formFile.Length > 0)
{
using (var stream = new FileStream(filePath, FileMode.Create))
{
await formFile.CopyToAsync(stream);
}
}
}
// process uploaded files
// Don't rely on or trust the FileName property without validation.
return Ok(new { count = files.Count, size, filePath});
}
답변
다음은 HTTP 본문에서 업로드 된 파일 내용을 가져 와서 파일에 쓰는 빠르고 더러운 솔루션입니다. 파일 업로드를위한 “베어 본”HTML / JS 스 니펫을 포함 시켰습니다.
웹 API 방법 :
[Route("api/myfileupload")]
[HttpPost]
public string MyFileUpload()
{
var request = HttpContext.Current.Request;
var filePath = "C:\\temp\\" + request.Headers["filename"];
using (var fs = new System.IO.FileStream(filePath, System.IO.FileMode.Create))
{
request.InputStream.CopyTo(fs);
}
return "uploaded";
}
HTML 파일 업로드 :
<form>
<input type="file" id="myfile"/>
<input type="button" onclick="uploadFile();" value="Upload" />
</form>
<script type="text/javascript">
function uploadFile() {
var xhr = new XMLHttpRequest();
var file = document.getElementById('myfile').files[0];
xhr.open("POST", "api/myfileupload");
xhr.setRequestHeader("filename", file.name);
xhr.send(file);
}
</script>
답변
webapi mvc4 프로젝트의 모든 NuGet을 업데이트하기 전에 Mike Wasson의 답변을 사용했습니다. 일단 파일 업로드 작업을 다시 작성해야했습니다.
public Task<HttpResponseMessage> Upload(int id)
{
HttpRequestMessage request = this.Request;
if (!request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.UnsupportedMediaType));
}
string root = System.Web.HttpContext.Current.Server.MapPath("~/App_Data/uploads");
var provider = new MultipartFormDataStreamProvider(root);
var task = request.Content.ReadAsMultipartAsync(provider).
ContinueWith<HttpResponseMessage>(o =>
{
FileInfo finfo = new FileInfo(provider.FileData.First().LocalFileName);
string guid = Guid.NewGuid().ToString();
File.Move(finfo.FullName, Path.Combine(root, guid + "_" + provider.FileData.First().Headers.ContentDisposition.FileName.Replace("\"", "")));
return new HttpResponseMessage()
{
Content = new StringContent("File uploaded.")
};
}
);
return task;
}
분명히 MultiPartFormDataStreamProvider에서 BodyPartFileNames를 더 이상 사용할 수 없습니다.
답변
이 같은 방향으로 WebApi, C # 4를 사용하여 Excel 파일을 보내는 클라이언트 및 서버 스 니펫을 게시합니다.
public static void SetFile(String serviceUrl, byte[] fileArray, String fileName)
{
try
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
using (var content = new MultipartFormDataContent())
{
var fileContent = new ByteArrayContent(fileArray);//(System.IO.File.ReadAllBytes(fileName));
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = fileName
};
content.Add(fileContent);
var result = client.PostAsync(serviceUrl, content).Result;
}
}
}
catch (Exception e)
{
//Log the exception
}
}
그리고 서버 webapi 컨트롤러 :
public Task<IEnumerable<string>> Post()
{
if (Request.Content.IsMimeMultipartContent())
{
string fullPath = HttpContext.Current.Server.MapPath("~/uploads");
MyMultipartFormDataStreamProvider streamProvider = new MyMultipartFormDataStreamProvider(fullPath);
var task = Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith(t =>
{
if (t.IsFaulted || t.IsCanceled)
throw new HttpResponseException(HttpStatusCode.InternalServerError);
var fileInfo = streamProvider.FileData.Select(i =>
{
var info = new FileInfo(i.LocalFileName);
return "File uploaded as " + info.FullName + " (" + info.Length + ")";
});
return fileInfo;
});
return task;
}
else
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "Invalid Request!"));
}
}
그리고 파일 이름을 사용자 정의하는 데 필요한 Custom MyMultipartFormDataStreamProvider :
PS : 다른 게시물 http://www.codeguru.com/csharp/.net/uploading-files-asynchronously-using-asp.net-web-api 에서이 코드를 가져 왔습니다 . .htm
public class MyMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
{
public MyMultipartFormDataStreamProvider(string path)
: base(path)
{
}
public override string GetLocalFileName(System.Net.Http.Headers.HttpContentHeaders headers)
{
string fileName;
if (!string.IsNullOrWhiteSpace(headers.ContentDisposition.FileName))
{
fileName = headers.ContentDisposition.FileName;
}
else
{
fileName = Guid.NewGuid().ToString() + ".data";
}
return fileName.Replace("\"", string.Empty);
}
}