wcf 服务调用从角度上传图像
Posted
技术标签:
【中文标题】wcf 服务调用从角度上传图像【英文标题】:wcf service call to upload image from angular 【发布时间】:2019-12-14 15:25:59 【问题描述】:我正在尝试通过 wcf 从 angular 前端上传图像。它工作正常,我也收到一条成功消息,但保存的图像未在任何其他图像程序的图像查看器中打开。
保存接收到的文件流的代码是从 *** 上一个答案复制的,但该答案非常旧。
public string PostImage(Stream stream)
using (var f = new FileStream(@"C:\Temp\Sample.jpg", FileMode.OpenOrCreate))
stream.CopyTo(f);
stream.Close();
return "Recieved the image on server";
如何以正确的格式保存文件。
Angular 文件是
app.component.ts
import Component from '@angular/core';
import HttpClient from '@angular/common/http';
@Component(
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
)
export class AppComponent
fileData: File = null;
constructor(private http: HttpClient)
fileProgress(fileInput: any)
this.fileData = fileInput.target.files[0] as File;
onSubmit()
console.log('Test');
const formData = new FormData();
formData.append('file', this.fileData);
this.http.post('http://localhost:50604/Service1.svc/PostImage', formData, responseType: 'text')
.subscribe(res =>
console.log(res);
alert('SUCCESS !!');
);
此服务似乎只保存了 139kb 的文件并且流正在中断。 webconfig绑定设置如下
<webHttpBinding>
<binding name="largeMessage" maxReceivedMessageSize="1000000000000" transferMode="Streamed" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" closeTimeout="00:03:00" openTimeout="00:03:00" receiveTimeout="00:10:00" sendTimeout="00:03:00">
<readerQuotas maxStringContentLength="2147483647" maxArrayLength="1000000000" maxBytesPerRead="2147483647" />
<security mode="None"/>
</binding>
</webHttpBinding>
【问题讨论】:
您的 JPEG 图像是否小于 10,000 字节?这就是您调用stream.Read(buffer, 0, 10000)
时所阅读的全部内容。
【参考方案1】:
代码仅将输入流的前 10,000 个字节复制到 C:\Temp\Sample.jpg
。您可能会在以下方面取得更大的成功:
public string PostImage(Stream stream)
using (var f = new FileStream(@"C:\Temp\Sample.jpg", FileMode.OpenOrCreate))
stream.CopyTo(f);
stream.Close();
return "Recieved the image on server";
【讨论】:
感谢您的回答。图片正在保存,但格式不正确。给出与以前不支持的格式相同的错误。 @HasanZubairi 您是否能够显示正在上传的任何客户端 Angular 代码? JPEG 图像与几乎所有图像格式一样,都是二进制文件,需要使用正确的 MIME 内容类型发送,在本例中为Content-Type: image/jpeg
。如果您使用其他 MIME 类型(例如 Content-Type: text/x-json
)上传,它可能会在传输过程中损坏。【参考方案2】:
可能是我们的图片没有保存成功,比如文件流没有完全复制。 我们最好使用异步编程模型上传图像/流。请参考我的服务接口定义和实现。IService.cs
[OperationContract]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json,BodyStyle =WebMessageBodyStyle.Wrapped)]
Task UploadStream(Stream stream);
Service1.svc.cs
public async Task UploadStream(Stream stream)
using (stream)
//save the image under the Uploads folder on the server-side(root directory).
using (var file = File.Create(Path.Combine(HostingEnvironment.MapPath("~/Uploads"), Guid.NewGuid().ToString() + ".jpg")))
await stream.CopyToAsync(file);
如果问题仍然存在,请随时告诉我。
已更新。 WCF 内置函数不支持表单数据。 我们应该将流解析为实际的文件内容。 Reading file input from a multipart/form-data POST 请参考我的示例(MultipartParser 类由他人完成)Service1.svc.cs
public async Task UploadStream(Stream stream)
MultipartParser parser = new MultipartParser(stream);
if (parser.Success)
using (var file = File.Create(Path.Combine(HostingEnvironment.MapPath("~/Uploads"), Guid.NewGuid().ToString() + ".png")))
await file.WriteAsync(parser.FileContents, 0, parser.FileContents.Length);
针对 CORS 问题。请将 Global.aspx 文件添加到 WCF 项目中。
protected void Application_BeginRequest(object sender, EventArgs e)
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With,Accept");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
HTML。
<div class="form-group">
<label for="file">Choose File</label>
<input type="file"
id="file"
(change)="handleFileInput($event.target.files)">
<input type="submit" id="mybutton" value="Upload" (click)="onSubmit();">
</div>
App.component.ts
export class AppComponent
title = 'MyAngular20190808';
fileToUpload: File = null;
constructor(private http: HttpClient)
handleFileInput(file: FileList)
this.fileToUpload=file.item(0);
onSubmit()
console.log('test');
const formData = new FormData();
formData.append('filekey', this.fileToUpload,this.fileToUpload.name);
this.http.post('http://10.157.18.36:8800/service1.svc/UploadStream', formData, responseType: 'text' )
.subscribe(res =>
console.log(res);
)
如果有什么我可以帮忙的,请随时告诉我。
已更新。
【讨论】:
感谢您的回复。我将您的代码复制到我的服务中,但是当我调用此方法时,我收到错误 400 错误请求。使此代码正常工作的任何特殊 webconfig 设置。谢谢 您使用哪种绑定?上述操作契约适用于webhttpbinding @HasanZubairi 请查看我的更新回复。如果问题仍然存在,请随时告诉我。 现在它给出错误'方法不允许'。角度显示错误 400 Bad request。 在我们构造HTTP客户端发送请求之前,是否可以通过其他工具,比如PostMan,成功上传文件?我认为我们必须确保服务在我们使用它之前正常工作。和之前一样,我们需要使用 Form 来构造 HTTP 请求。以上是关于wcf 服务调用从角度上传图像的主要内容,如果未能解决你的问题,请参考以下文章
wcf rest 服务用于安卓和ISO调用2-------文件上传