【问题标题】:wcf service call to upload image from angularwcf 服务调用从角度上传图像
【发布时间】:2019-12-14 15:25:59
【问题描述】:

我正在尝试通过 wcf 从 angular 前端上传图像。它工作正常,我也收到一条成功消息,但保存的图像未在任何其他图像程序的图像查看器中打开。

保存接收到的文件流的代码是从 stackoverflow 上一个答案复制的,但该答案非常旧。

 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) 时所阅读的全部内容。

标签: c# angular wcf file-upload service


【解决方案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 请求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-10
  • 2012-05-07
  • 2012-07-15
  • 2023-03-20
相关资源
最近更新 更多