如何将 x-www-form-urlencoded post Message 转换为 JSON post Message?
Posted
技术标签:
【中文标题】如何将 x-www-form-urlencoded post Message 转换为 JSON post Message?【英文标题】:How to convert x-www-form-urlencoded post Message to 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。 【参考方案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 内容类型中接受发给它们的帖子。
【讨论】:
以上是关于如何将 x-www-form-urlencoded post Message 转换为 JSON post Message?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Content-Type: application/x-www-form-urlencoded 格式的数据帧行迭代到 API POST 请求中?
将 json 转换为 x-www-form-urlencoded
如何在 SoapUI 中设置 x-www-form-urlencoded?
如何使用内容类型 ='application/x-www-form-urlencoded' 在 node.js 中发布数据