将 Stream 参数与其他参数一起传递以通过 POST 方法调用 WCF 服务

Passing Stream Parameter with other Parameters to invoke WCF Service through POST method

提问人:Ann 提问时间:6/4/2020 最后编辑:Ann 更新时间:6/5/2020 访问量:1255

问:

我是否可以要求另一种方法将流文件作为参数与其他参数一起传递,如下图所示,通过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; }

  }
C# asp.net WCF

评论

0赞 Cristi 6/4/2020
FileUpload1 是什么类型?
0赞 Ann 6/4/2020
它是 aspx 中的 FileUpload 工具
0赞 Cristi 6/4/2020
我不是专家,但我认为您不能通过 wcf 调用发送流。尝试从 FileUpload 工具中读取字节数组。

答:

0赞 Ding Peng 6/4/2020 #1

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

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

https://learn.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://learn.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; }
}

这是 filevariables 类。

更新

你可以这样称呼它:

        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();

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

评论

0赞 Ann 6/4/2020
我已经使用了您提出的第一个解决方案,并且它有效。非常感谢!显然,从客户端来看,我不知道如何正确传递这些参数以调用 post 方法。你也愿意帮我吗?
0赞 Ann 6/10/2020
对不起,虽然有错误。404 没有找到,你知道为什么会这样吗?
0赞 Ding Peng 6/10/2020
有两种可能性。第一个是您的服务未成功启动。你需要检查它。第二个是您的 URI 可能拼写错误。
0赞 Ding Peng 6/10/2020
可以在 WCF 中打开帮助文档以查看正确的 URI:learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/...
0赞 Ann 6/11/2020
我发现了错误。我正在将参数值传递给 username = “dom\Username”,我认为斜杠符号使 URI 无效。您能否建议如何传递带有斜杠符号的参数。谢谢!