Исходная бумага должна считаться "Безусловной GOTO, Продуманной Вредный". Это в особенности защищало форму программирования на основе условного выражения (if
) и повторяющееся (while
) конструкции, а не тест-и-переход, распространенный, чтобы рано кодировать. goto
все еще полезно на некоторых языках или обстоятельствах, где никакая соответствующая управляющая структура не существует.
Это, к сожалению, не поддерживается - у нас была аналогичная потребность, и мы сделали это, вызвав внутренние члены с отражением. Мы просто используем его в обработчике ошибок (чтобы можно было сбросить необработанный запрос), но он работает нормально. Я бы не рекомендовал его для системы, которой вы не владеете и не используете (например, не отправляйте этот код покупателю), поскольку он может измениться в любое время с помощью пакета обновления или чего-то еще.
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;
}
Итак, если вы объявляете свой контракт примерно так:
[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. Возможно, это не самое элегантное решение, но оно работает.
Надеюсь, это поможет.
Glenn