【问题标题】:Passing Stream Parameter with other Parameters to invoke WCF Service through POST method将 Stream 参数与其他参数一起传递以通过 POST 方法调用 WCF 服务
【发布时间】:2020-09-22 15:00:24
【问题描述】:

我是否可以要求另一种方法来包含流文件,将其作为参数与其他参数一起传递,如下所示,我的代码通过 post 方法将其传递给我的 WCF 服务。我是初学者,所以我不确定如何处理这件事。我故意没有放端口号。使用我的代码,我遇到此错误“无法序列化 System.Web.HttpInputStream”。这就是为什么我需要找到其他方式来传递参数。

客户端代码:

                FileVariables fileInput = new FileVariables
                {
                    fileName = FileUpload1.FileName,
                    fileContents = FileUpload1.FileContent,
                    Username = txtUsername.Text,
                    Password = txtPassword.Text
                };


                DataContractJsonSerializer json = new DataContractJsonSerializer(typeof(FileVariables));
                MemoryStream ms = new MemoryStream();
                json.WriteObject(ms, fileInput);

                string data = Encoding.UTF8.GetString(ms.ToArray(), 0, (int)ms.Length);
                WebClient webClient = new WebClient();
                webClient.Headers["Content-type"] = "application/json";
                webClient.Encoding = Encoding.UTF8;
                webClient.UploadString("http://localhost/TestService.svc/REST/UploadFile", "POST", data);

WCF 服务:

  public interface ITestService
  {
    [OperationContract]
    [WebInvoke(Method = "POST", UriTemplate = "/UploadFile",
               BodyStyle = WebMessageBodyStyle.Wrapped,
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json)]
   string UploadFile(FileVariables file);
  }

  [DataContract]
  public class FileVariables
  {
    [DataMember(Order = 1)]
    public string fileName { get; set; }

    [DataMember(Order =2)]
    public Stream fileContents { get; set; }

    [DataMember(Order = 3)]
    public string Username { get; set; }

    [DataMember(Order = 4)]
    public string Password { get; set; }

  }

【问题讨论】:

  • FileUpload1 有什么类型?
  • 这是一个aspx中的文件上传工具
  • 我不是专家,但我认为您不能通过 wcf 调用发送流。尝试从您的 FileUpload 工具中读取一个字节数组。

标签: c# asp.net wcf


【解决方案1】:

要在 WCF 中拥有流成员,必须使用 Messagecontract。 Datacontract和messagecontract的序列化方式不同,如果在一个有流属性的类中使用Datacontract,就会出现序列化问题。

更多信息,请参考以下链接:

https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/large-data-and-streaming?redirectedfrom=MSDN

但是webhttpbinding不支持Messagecontract,所以现在你有两种方法可以解决这个问题。

第一个解决方案:

如果你必须使用 webhttpbinding,你的界面应该是这样的:

     [WebInvoke(UriTemplate = "UploadFile/{fileName}/{Username}/{Password}")]
    void UploadFile(string fileName,string Username,string Password,Stream fileContents);

您可以参考以下链接:

https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/create-a-service-arbitrary-data-using-wcf

第二种解决方案:

第二种方法是使用支持Messagecontract的绑定,而不是使用webhttpbing,比如basichttpbinding。

        [MessageContract]
public class FileVariables
{
    [MessageHeader]
    public string fileName { get; set; }
    [MessageBodyMember]
    public Stream fileContents { get; set; }
    [MessageHeader]
    public string Username { get; set; }
    [MessageHeader]
    public string Password { get; set; }
}

这是文件变量类。

更新

你可以这样称呼它:

        string fileName= "fileName", Username= "Username", Password= "Password";
        string ad = "/UploadFile/" + fileName+"/"+ Username+"/"+ Password;
        HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("http://localhost:8012/ServiceModelSamples/service"+ ad);
        req.Method = "POST";
        req.ContentType = "text/plain";
        Stream reqStream = req.GetRequestStream();
        byte[] fileToSend = new byte[12345];
        for (int i = 0; i < fileToSend.Length; i++)
        {
            fileToSend[i] = (byte)('a' + (i % 26));
        }
        reqStream.Write(fileToSend, 0, fileToSend.Length);
        reqStream.Close();
        HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

如果我的回答对您有帮助,您可以将其标记为答案。

【讨论】:

  • 我已经使用了您提出的第一个解决方案并且它有效。太感谢了!显然,从客户端,我不知道如何正确传递这些参数来调用 post 方法。你也愿意帮助我吗?
  • 抱歉,出现错误。 404 Not found,你知道为什么会这样吗?
  • 有两种可能。第一个是你的服务没有启动成功。你需要检查一下。第二个是你的URI可能拼错了。
  • 可以在WCF中打开帮助文档查看正确的URI:docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/…
  • 我发现了错误。我将参数值传递给 username = "dom\Username" 并且我认为斜线符号使 URI 无效。您能否建议我如何传递带有斜杠符号的参数。谢谢!
猜你喜欢
  • 2012-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
  • 1970-01-01
  • 2016-08-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多