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 服务调用从角度上传图像的主要内容,如果未能解决你的问题,请参考以下文章

从 Silverlight 到 WCF 的图像文件

wcf rest 服务用于安卓和ISO调用2-------文件上传

WCF / WCF Ria 服务在“IncludedResults”中返回关系数据

从Android中的一个网络服务调用一次上传多张图像?

从活动中调用相机,捕获图像并上传到服务器

上传到服务器后,图像路径从 vuejs 项目中的 localhost 调用