[英]How to convert application/x-www-form-urlencoded to JSON?
[英]How to convert x-www-form-urlencoded post Message to JSON post Message?
我需要支持以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)
{ }
}
我得到的錯誤:
請求錯誤服務器在處理請求時遇到錯誤。 異常消息為“預期狀態為'元素'。。遇到了名稱為”,名稱空間為”的'文本'。 ”。
因此,看來我實際上並沒有很好地說明我實際上要完成的工作,但是在與之抗爭之后,我終於弄清楚了。
我得到的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內容類型中接受它們的發布。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.