如何从 WCF 服务返回 multipart/form-data 作为响应

Posted

技术标签:

【中文标题】如何从 WCF 服务返回 multipart/form-data 作为响应【英文标题】:How to return multipart/form-data from WCF Service in response 【发布时间】:2012-12-31 15:01:28 【问题描述】:

我希望我的 WCF 服务返回多部分/表单数据。虽然响应正文确实包含所需的内容,但是当我想查看 Content-type: multipart/form-data 时,响应标头表明正文是 application/octet-stream。

代码以下面的单元测试开始。

    [TestMethod, Owner(TEST_AUTHOR), TestCategory("MIME Testing")]
    public void TempWcfService_PostMimeRequest_ExpectSuccess()
    
        //Arrange
        HttpClient client = new HttpClient();

        HttpMultipartMimeForm form = new HttpMultipartMimeForm();
        form.Add("Key1", "Value1");
        form.Add("Key2", "Value2");

        //Act
        HttpResponseMessage response = client.Post(TEST_HOST_URL + "/mime-test", form.CreateHttpContent());
        response.EnsureStatusIsSuccessful();

        Stream responseStream = response.Content.ReadAsStream();
        string sResponse = responseStream.ToString();

        //Assert
        Console.Write(sResponse);
    

上述测试使用了一个 WCF 服务,其界面如下所示。

namespace TempWcfService

    /// <summary>
    /// Interface added to support http without the WCF client class
    /// </summary>
    [ServiceContract]
    public interface ITempPing
    
        [OperationContract]
        [WebInvoke(Method = "GET", UriTemplate = "ping")]
        [Description("Pings the service for availability")]
        string ping();

        [OperationContract]
        [WebInvoke(UriTemplate = "mime-test", 
                   Method = "POST",
                   BodyStyle = WebMessageBodyStyle.Bare)]
        [Description("Tests a simple MIME request")]
        Stream TestMultipartMime(Stream data);

    

以及实现...

namespace TempWcfService

    /// <summary>
    /// Implementation added to support http without the WCF client class
    /// </summary>
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class TempPing : ITempPing
    
        public string ping()
        
            return "TempPing ping() successful";
        

        public Stream TestMultipartMime(Stream data)
        
            // Re-construct the multipart/form-data content
            MultipartFormData multipartFormData = new MultipartFormData(WebOperationContext.Current.IncomingRequest, data);
            HttpMultipartMimeForm responseForm = new HttpMultipartMimeForm(multipartFormData.Items);
            responseForm.Add("ErrorCode", "Success");
            responseForm.Add("ErrorMessage", "None");

            HttpResponseMessage responseMsg = new HttpResponseMessage();
            responseMsg.StatusCode = System.Net.HttpStatusCode.OK;
            responseMsg.Content = responseForm.CreateHttpContent();
            responseMsg.Headers.Add("Accept", "multipart/form-data");
            responseMsg.Headers.ContentType = "multipart/form-data; boundary=" + multipartFormData.Boundary;

            return responseMsg.Content.ReadAsStream();
        

    

WCF 似乎在“帮助我”,根据使用 ReadAsStream() 返回的内容,用“application/octet-stream”的内容类型覆盖代码中指定的 ContentType。有没有办法让 Content-Type 标头指示 multipart/form-data?

【问题讨论】:

这有帮助吗? blogs.msdn.com/b/dotnetinterop/archive/2008/11/04/… 【参考方案1】:

您需要在传出上下文中设置内容类型:

public Stream TestMultipartMime(Stream data)

    // Re-construct the multipart/form-data content
    MultipartFormData multipartFormData = new MultipartFormData(WebOperationContext.Current.IncomingRequest, data);
    HttpMultipartMimeForm responseForm = new HttpMultipartMimeForm(multipartFormData.Items);
    responseForm.Add("ErrorCode", "Success");
    responseForm.Add("ErrorMessage", "None");

    HttpResponseMessage responseMsg = new HttpResponseMessage();
    responseMsg.StatusCode = System.Net.HttpStatusCode.OK;
    responseMsg.Content = responseForm.CreateHttpContent();

    WebOperationContext.Current.OutgoingResponse.ContentType = "multipart/form-data; boundary=" + multipartFormData.Boundary;
    WebOperationContext.Current.OutgoingResponse.Headers["Accept"] = "multipart/form-data";

    return responseMsg.Content.ReadAsStream();

请注意,您不需要在 response 中设置 Accept 标头 - 此标头用于 requests 客户端告诉服务器哪些内容 -它想要接收的类型。

【讨论】:

以上是关于如何从 WCF 服务返回 multipart/form-data 作为响应的主要内容,如果未能解决你的问题,请参考以下文章

如何从安静的 WCF 服务返回对象列表

如何从 WCF 服务返回 multipart/form-data 作为响应

如何从 WCF 服务流下载文件?

如何从 WCF 打印数组的值以形成标签?

当操作返回元页面 html 时,如何更好地诊断 WCF 服务?

如何使用 WCF 调用从客户端 windows phone 8.0 silverlight 返回对象的方法