【问题标题】:How to convert x-www-form-urlencoded post Message to JSON post Message?如何将 x-www-form-urlencoded post Message 转换为 JSON post Message?
【发布时间】:2019-03-04 15:26:57
【问题描述】:

我需要支持以x-www-form-urlencoded 的内容类型将数据发布到我们的 WCF 服务。由于 WCF 本身不喜欢这样做,所以我的想法是使用 MessageInspector 来拦截具有该内容类型的传入消息,读出正文,将其转换为 JSON 字符串,然后替换请求消息。

问题是我似乎无法创建我的服务真正喜欢的新 Message 对象。我可以获取正文并将其转换为 JSON 字符串就好了,但是我创建的新消息会导致错误,而不是通过适当的服务方法。

这是我目前所拥有的。我已经修补了一天又一点,尝试了几种不同的方法,但运气不佳。我将在当前遇到的错误下方发布。

我要调用的Web服务方法:

[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/PostTest", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
public string PostTest(TestObject thinger)
{
    return thinger.Thing;
}

消息检查器:

public class FormPostConverter : IDispatchMessageInspector
{
    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {
        var contentType = (request.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty)?.Headers["Content-Type"];

        if (!request.IsEmpty && contentType == "application/x-www-form-urlencoded")
        {
            var body = HttpUtility.ParseQueryString(new StreamReader(request.GetBody<Stream>()).ReadToEnd());
            var json = new JavaScriptSerializer().Serialize(body.AllKeys.ToDictionary(k => k, k => body[k]));

            Message newMessage = Message.CreateMessage(MessageVersion.None, "", json, new DataContractJsonSerializer(typeof(string)));
            newMessage.Headers.CopyHeadersFrom(request);
            newMessage.Properties.CopyProperties(request.Properties);
            (newMessage.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty)?.Headers.Set(HttpRequestHeader.ContentType, "application/json");
            newMessage.Properties[WebBodyFormatMessageProperty.Name] = new WebBodyFormatMessageProperty(WebContentFormat.Json);
            request = newMessage;
        }

        return null;
    }

    public void BeforeSendReply(ref Message reply, object correlationState)
    { }
}

我得到的错误:

请求错误 服务器在处理请求时遇到错误。 异常消息是 'Expecting state 'Element'.. 遇到 “文本”,名称为“”,命名空间为“”。 '。

【问题讨论】:

  • 在你走得更远之前,json 内容与 x-www-form-urlencoded 不同。你是说 application/json 吗?
  • 是的,我的意思是应用程序/json。

标签: c# json web-services wcf


【解决方案1】:

所以,我似乎并没有很好地表达我真正想要完成的事情,但在与它斗争了一些之后,我终于弄明白了。

我生成的 MessageInspector 如下所示:

public class FormPostConverter : IDispatchMessageInspector
{
    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {
        var contentType = (request.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty)?.Headers["Content-Type"];

        if (!request.IsEmpty && contentType == "application/x-www-form-urlencoded")
        {
            var body = HttpUtility.ParseQueryString(new StreamReader(request.GetBody<Stream>()).ReadToEnd());
            if (body != null && body.HasKeys())
            {
                Message newMessage = Message.CreateMessage(MessageVersion.None, "", new XElement("root", body.AllKeys.Select(o => new XElement(o, body[o]))));
                newMessage.Headers.CopyHeadersFrom(request);
                newMessage.Properties.CopyProperties(request.Properties);
                (newMessage.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty)?.Headers.Set(HttpRequestHeader.ContentType, "application/json");
                newMessage.Properties[WebBodyFormatMessageProperty.Name] = new WebBodyFormatMessageProperty(WebContentFormat.Json);
                request = newMessage;
            }
        }

        return true;
    }

    public void BeforeSendReply(ref Message reply, object correlationState)
    { }
}

事实证明,我真正需要做的只是将我的主体转换为 XML 元素,而不是尝试将其转换为 JSON。在检查了一个以 JSON 形式出现的有效 POST 后,我看到在这个阶段它已经在 Message 对象中转换为 XML。

有了这个,我可以正常编写我的服务方法(没有 Stream 参数和手动解析),并在 application/json 或 x-www-form-urlencoded 内容类型中接受发给它们的帖子。

【讨论】:

    猜你喜欢
    • 2018-06-11
    • 2015-08-16
    • 2019-12-04
    • 2020-10-06
    • 1970-01-01
    • 2012-07-02
    • 1970-01-01
    • 2018-08-18
    • 1970-01-01
    相关资源
    最近更新 更多