我目前正在开发WCF RESTful服务。在POST数据的验证中,如果请求XML不符合我们的业务规则,我会抛出异常。
目标是在收到被认为无效的请求时向相应的工作人员发送电子邮件。但是,除了传入的请求标头,方法和URI之外,我还想发送已发布的XML。
我无法找到访问此数据的方法。在我有机会访问它之前,WCF是否真的会破坏请求正文/数据,或者我错过了什么?
我很感激您的帮助,因为我对为什么无法访问请求数据感到困惑。
答案 0 :(得分:9)
遗憾的是,这不受支持 - 我们有类似的需求,并通过调用内部成员进行反思来实现。我们只是在错误处理程序中使用它(所以我们可以转储原始请求),但它工作正常。我不推荐它用于您不拥有和操作的系统(例如,不要将此代码发送给客户),因为它可以随时更改服务包或其他任何内容。
public static string GetRequestBody()
{
OperationContext oc = OperationContext.Current;
if (oc == null)
throw new Exception("No ambient OperationContext.");
MessageEncoder encoder = oc.IncomingMessageProperties.Encoder;
string contentType = encoder.ContentType;
Match match = re.Match(contentType);
if (!match.Success)
throw new Exception("Failed to extract character set from request content type: " + contentType);
string characterSet = match.Groups[1].Value;
object bufferedMessage = operationContextType.InvokeMember("request",
BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField,
null, oc, null);
//TypeUtility.AssertType(bufferedMessageType, bufferedMessage);
object messageData = bufferedMessageType.InvokeMember("MessageData",
BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetProperty,
null, bufferedMessage, null);
//TypeUtility.AssertType(jsonBufferedMessageDataType, messageData);
object buffer = jsonBufferedMessageDataType.InvokeMember("Buffer",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty,
null, messageData, null);
ArraySegment<byte> arrayBuffer = (ArraySegment<byte>)buffer;
Encoding encoding = Encoding.GetEncoding(characterSet);
string requestMessage = encoding.GetString(arrayBuffer.Array, arrayBuffer.Offset, arrayBuffer.Count);
return requestMessage;
}
答案 1 :(得分:9)
所以,如果你宣布你的合同是这样的:
[WebInvoke(Method = "POST", UriTemplate = "create", ResponseFormat=WebMessageFormat.Json)]
int CreateItem(Stream streamOfData);
(您可以使用XML代替) streamOfData应该是HTTP POST的主体。您可以使用以下内容对其进行反序列化:
StreamReader reader = new StreamReader(streamId);
String res = reader.ReadToEnd();
NameValueCollection coll = HttpUtility.ParseQueryString(res);
至少对我们这样的工作。您可能希望使用不同的方法将字符串转换为XMLDocument或其他内容。这适用于我们的JSON帖子。可能不是最优雅的解决方案,但它正在发挥作用。
我希望这会有所帮助。
格伦
答案 2 :(得分:2)
试试这个,
OperationContext.Current.RequestContext.RequestMessage
答案 3 :(得分:2)
以下是没有反思的方法:
using (var reader = OperationContext.Current.RequestContext.RequestMessage.GetReaderAtBodyContents ()) {
if (reader.Read ())
return new string (Encoding.ASCII.GetChars (reader.ReadContentAsBase64 ()));
return result;
}
}
如果读者是HttpStreamXmlDictionaryReader
(就像我的情况那样),该类的方法ReadContentAsBase64(byte[] buffer, int index, int count)
的实现只是将这些参数传递给Stream.Rea
d方法。
我有byte[]
后,我通过ASCII编码将字节转换为字符串。为了正确实施,您可以使用内容类型&amp;根据消息的标题编码,按照HTTP规范进行编码。
答案 4 :(得分:0)
您可以在WCF服务的自定义HttpModule中阻止.less
m,读取流并在自定义HttpModule的事件处理程序中再次将其位置设置为0。然后将其存储在会话中并在实际.css
中进一步访问。
例如:
HttpApplication.Request.InputStrea