将文档上传到Web API
第一步:在我的MVC项目中,我有一个允许上传文件的Div。将文档上传到Web API
<div id="modalUpload" style="display:none">
Select a file:
<input id="upload" type="file" name="upload" /><br />
Description:
<input id="documentDescription" type="text" /><br />
<input type="button" value="Submit" id="submitUpload" data-bind="click:function(){ $root.upload() }">
</div>
第二步:在JavaScript我将文件上传至网络API与POST请求:(例如,与所述的XMLHttpRequest方法)
self.upload = function() {
var file = document.getElementById("upload").files[0];
var xhr = new XMLHttpRequest();
xhr.open('post', "/API/document/addDocument/", true);
xhr.send(file);
}
第三步:这是我addDocument功能上在Web API,它预计Document对象,像这样:
[HttpPost]
[Route("{controller}/addDocument")]
public string Post([FromBody]Document doc)
{
.......
}
我的问题是,我该怎么过帐凭证的API作为Documen t对象?是否可以设置POST数据的类型?
在我的JavaScript代码,我有一个Document对象:
var Document = function (data) {
this.id = ko.observable(data.id);
this.name= ko.observable(data.name);
this.size= ko.observable(data.zise);
}
但我不知道如何将它们之间进行连接。
当我尝试这样做:
var file = new Document(document.getElementById("upload").files[0]);
我得到了以下错误:
415 (Unsupported Media Type)
任何帮助将是非常赞赏。
最后,我没有发文件为对象,这就是我最后做,
self.upload = function() {
if (document.getElementById("upload").value != "") {
var file = document.getElementById("upload").files[0];
var filePath = "....";
if (window.FormData !== undefined) {
var data = new FormData();
data.append("file", file);
var encodedString = Base64.encode(filePath);
$.ajax({
type: "POST",
url: "/API/document/upload/" + file.name + "/" + encodedString ,
contentType: false,
processData: false,
data: data,
success: function (result) {
console.log(result);
},
error: function (xhr, status, p3, p4) {
var err = "Error " + " " + status + " " + p3 + " " + p4;
if (xhr.responseText && xhr.responseText[0] == "{")
err = JSON.parse(xhr.responseText).Message;
console.log(err);
}
});
}
}
}
这是我的API函数:
[HttpPost]
[Route("{controller}/upload/{fileName}/{filePath}")]
public async Task<HttpResponseMessage> UploadFile(string fileName, string filePath)
{
if (!Request.Content.IsMimeMultipartContent())
{
return Request.CreateErrorResponse(HttpStatusCode.UnsupportedMediaType, "The request doesn't contain valid content!");
}
byte[] data = Convert.FromBase64String(filePath);
filePath = Encoding.UTF8.GetString(data);
try
{
var provider = new MultipartMemoryStreamProvider();
await Request.Content.ReadAsMultipartAsync(provider);
foreach (var file in provider.Contents)
{
var dataStream = await file.ReadAsStreamAsync();
// use the data stream to persist the data to the server (file system etc)
using (var fileStream = File.Create(filePath + fileName))
{
dataStream.Seek(0, SeekOrigin.Begin);
dataStream.CopyTo(fileStream);
}
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent("Successful upload", Encoding.UTF8, "text/plain");
response.Content.Headers.ContentType = new MediaTypeWithQualityHeaderValue(@"text/html");
return response;
}
return Request.CreateResponse(HttpStatusCode.ExpectationFailed);
}
catch (Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e.Message);
}
}
完美的作品,我上心从here。
一个可能的问题是,您需要确保您的XHR请求在accept头中声明了正确的MIME类型。
直接使用XHR可能会有点痛苦。您可能需要考虑使用客户端库(如jquery)以使事情更轻松并处理任何跨浏览器的不一致问题。
你可以尝试得到它作为HttpPostedFileBase
[HttpPost]
[Route("{controller}/addDocument")]
public string Post(HttpPostedFileBase doc)
{
//Parse it to a doc and do what you gotta do
}
谢谢你,我宁愿在客户端做出改变...你有任何想法如何解析一个HttpPostedFileBase到我自己的Document对象吗? – user3378165
您可以尝试将HttpPostedFileBase.InputStream转换为字节,然后从字节创建Document – MasterJohn
感谢您的回复,我不在乎如何使用jquery,但我不知道如何去做,您能否列举一个例子?谢谢! – user3378165
我无法指导您完成。 Google'xhr文件上传'提供了很多很好的例子。您的错误消息正在由您的服务器端API生成。你需要更好地理解XHR发送文件上传的期望。 – kevintechie
我看到它会太复杂,所以最后我没有把它作为一个对象上传,然后它完美地工作。感谢您的帮助。 – user3378165