我尝试将文本文件从WPF RESTful客户端上传到ASP .NET MVC WebAPI 2网站.
客户代码
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://localhost:22678/api/Account/UploadFile?fileName=test.txt&description=MyDesc1"); request.Method = WebRequestMethods.Http.Post; request.Headers.Add("Authorization", "Bearer " + tokenModel.ExternalAccessToken); request.ContentType = "text/plain"; request.MediaType = "text/plain"; byte[] fileToSend = File.ReadAllBytes(@"E:\test.txt"); request.ContentLength = fileToSend.Length; using (Stream requestStream = request.GetRequestStream()) { // Send the file as body request. requestStream.Write(fileToSend, 0, fileToSend.Length); requestStream.Close(); } using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) Console.WriteLine("HTTP/{0} {1} {2}", response.ProtocolVersion, (int)response.StatusCode, response.StatusDescription);
WebAPI 2代码
[HttpPost] [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)] [Route("UploadFile")] public void UploadFile(string fileName, string description, Stream fileContents) { byte[] buffer = new byte[32768]; MemoryStream ms = new MemoryStream(); int bytesRead, totalBytesRead = 0; do { bytesRead = fileContents.Read(buffer, 0, buffer.Length); totalBytesRead += bytesRead; ms.Write(buffer, 0, bytesRead); } while (bytesRead > 0); var data = ms.ToArray() ; ms.Close(); Debug.WriteLine("Uploaded file {0} with {1} bytes", fileName, totalBytesRead); }
所以..在客户端代码下我面临着这个异常
远程服务器返回错误:(415)不支持的媒体类型.
任何线索我缺少什么?
关于Radim上面提到的内容的+1 ...根据您的操作,Web API模型绑定会注意到该参数fileContents
是一个复杂类型,并且默认情况下假定使用格式化程序读取请求正文内容.(请注意,由于fileName
和description
参数属于 string
类型,因此默认情况下它们应来自uri).
您可以执行以下操作以防止发生模型绑定:
[HttpPost] [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)] [Route("UploadFile")] public async Task UploadFile(string fileName, string description) { byte[] fileContents = await Request.Content.ReadAsByteArrayAsync(); .... }
顺便说一下,你打算用这个做fileContents
什么?你想创建一个本地文件?如果是的话,有一个更好的方法来处理这个问题.
根据您的上次评论更新:
你可以做的一个简单的例子
[HttpPost] [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)] [Route("UploadFile")] public async Task UploadFile(string fileName, string description) { Stream requestStream = await Request.Content.ReadAsStreamAsync(); //TODO: Following are some cases you might need to handle //1. if there is already a file with the same name in the folder //2. by default, request content is buffered and so if large files are uploaded // then the request buffer policy needs to be changed to be non-buffered to imporve memory usage //3. if exception happens while copying contents to a file using(FileStream fileStream = File.Create(@"C:\UploadedFiles\" + fileName)) { await requestStream.CopyToAsync(fileStream); } // you need not close the request stream as Web API would take care of it }
您正在设置ContentType = "text/plain"
,此设置驱动格式化程序选择.请查看Media Formatters以获取更多详细信息.
提取物:
在Web API中,媒体类型确定Web API如何序列化和反序列化HTTP消息体.内置对XML,JSON和表单urlencoded数据的支持,您可以通过编写媒体格式化程序来支持其他媒体类型.
因此,没有内置的text/plain格式化程序,即:不支持的媒体类型.您可以将内容类型更改为某些支持,内置或实现自定义类型(如链接中所述)