如何读取发送到REST Web服务的HttpRequest POST请求的正文 - C# WCF

4

我有一个Apex类(SalesForce中的一个类),它调用一个REST web服务。

public class WebServiceCallout 
{
    @future (callout=true)
    public static void sendNotification(String aStr) 
    {
        HttpRequest req = new HttpRequest();
        HttpResponse res = new HttpResponse();
        Http http = new Http();

        req.setEndpoint('http://xx.xxx.xxx.xx:41000/TestService/web/test');
        req.setMethod('POST');
        req.setHeader('Content-Type', 'application/json');
        req.setBody(aStr); // I want to read this in the web service

        try 
        {
            res = http.send(req);
        } 
        catch(System.CalloutException e) 
        {
            System.debug('Callout error: '+ e);
            System.debug(res.toString());
        }
    }
}

REST Web服务(C#,WCF)如下所示:

public interface ITestService
{
    [OperationContract]
    [WebInvoke(Method = "POST",
     ResponseFormat = WebMessageFormat.Json,
     BodyStyle = WebMessageBodyStyle.Bare,
     UriTemplate = "/test")]
    string Test(string aStr);
}

Test() 方法执行基本操作。

当我运行时

WebServiceCallout.sendNotification("a test message")

POST请求发送到Web服务,但是我如何读取在sendNotification()方法中设置的req.setBody(aStr);HttpRequestbody中设置的内容呢?

也就是说,string Test(string aStr);方法的参数应该是什么?

我需要指定其他任何配置/属性吗,在我的WebInvokeApp.config中(例如,binding)?

1个回答

6
如果您想要读取传入请求的原始正文,应将参数类型定义为 Stream,而不是 string。下面的代码展示了一种实现场景的方式,而这篇文章 http://blogs.msdn.com/b/carlosfigueira/archive/2008/04/17/wcf-raw-programming-model-receiving-arbitrary-data.aspx 中有更多关于此“原始”模式的信息。
public class StackOverflow_25377059
{
    [ServiceContract]
    public interface ITestService
    {
        [OperationContract]
        [WebInvoke(Method = "POST",
         ResponseFormat = WebMessageFormat.Json,
         BodyStyle = WebMessageBodyStyle.Bare,
         UriTemplate = "/test")]
        string Test(Stream body);
    }

    public class Service : ITestService
    {
        public string Test(Stream body)
        {
            return new StreamReader(body).ReadToEnd();
        }
    }

    class RawMapper : WebContentTypeMapper
    {
        public override WebContentFormat GetMessageFormatForContentType(string contentType)
        {
            return WebContentFormat.Raw;
        }
    }

    public static void Test()
    {
        var baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        var host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        var binding = new WebHttpBinding { ContentTypeMapper = new RawMapper() };
        host.AddServiceEndpoint(typeof(ITestService), binding, "").Behaviors.Add(new WebHttpBehavior());
        host.Open();
        Console.WriteLine("Host opened");

        var req = (HttpWebRequest)HttpWebRequest.Create(baseAddress + "/test");
        req.Method = "POST";
        req.ContentType = "application/json";
        var reqStream = req.GetRequestStream();
        var body = "a test message";
        var bodyBytes = new UTF8Encoding(false).GetBytes(body);
        reqStream.Write(bodyBytes, 0, bodyBytes.Length);
        reqStream.Close();
        var resp = (HttpWebResponse)req.GetResponse();
        Console.WriteLine("HTTP/{0} {1} {2}", resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);
        foreach (var header in resp.Headers.AllKeys)
        {
            Console.WriteLine("{0}: {1}", header, resp.Headers[header]);
        }

        Console.WriteLine();
        Console.WriteLine(new StreamReader(resp.GetResponseStream()).ReadToEnd());
        Console.WriteLine();
    }
}

顺便提一下,你的请求不符合技术要求 - 通过 Content-Type 你指明发送的是 JSON 数据,但请求体(a test message)并不是一个有效的 JSON 字符串(应该用引号将其包裹起来 - "a test message" 才能成为有效的 JSON 字符串)。


感谢您澄清测试消息不是有效的 JSON,我一直在想为什么需要对字符串加双引号! - Serge P
是的,你应该像这样传递JSON数据:var body = "msg:\"a test message\""; - David R Tribble

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接