С большим количеством проб и ошибок я нашел очень уродливое и абсолютно нелогичное решение моей проблемы. Но все же ... Может быть, этот пост может помочь кому-то в будущем. Обратите внимание, что это «решение» работает для меня в .NET 4.5. Я не гарантирую, что это сработает для вас.
Проблема сводится к следующему:
- это невозможно (AFAIK), чтобы положить бежал косую черту в Ури в .NET
- для связи с внешним обслуживанием (RabbitMQ) Мне действительно нужно быть в состоянии поместить% 2f (т.е. вперед слэш) в моем URL запроса
следующий пост поставил меня в «правильном» направлении: How to stop System.Uri un-escaping forward slash characters
I Пытался решение, предложенное в этой должности, но ... не дали никаких результатов
Тогда после того, как много ругательств, прибегая к помощи, инженерные и так далее я придумал следующий фрагмент кода:
/// <summary>
/// Client enpoint behavior that enables the use of a escaped forward slash between 2 forward slashes in a url
/// </summary>
public class EncodeForwardSlashBehavior:IEndpointBehavior
{
public void Validate(ServiceEndpoint endpoint)
{
}
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.ClientMessageInspectors.Add(new ForwardSlashUrlInspector());
}
}
/// <summary>
/// Inspector that modifies a an Url replacing /// with /%2f/
/// </summary>
public class ForwardSlashUrlInspector:IClientMessageInspector
{
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
string uriString = request.Headers.To.ToString().Replace("///", "/%2f/");
request.Headers.To = new Uri(uriString);
AddAllowAnyOtherHostFlagToHttpUriParser();
return null;
}
/// <summary>
/// This is one of the weirdest hacks I ever had to do, so no guarantees can be given to this working all possible scenarios
/// What this does is, it adds the AllowAnyOtherHost flag to the private field m_Flag on the UriParser for the http scheme.
/// Replacing /// with /%2f/ in the request.Headers.To uri BEFORE calling this method will make sure %2f remains unescaped in your Uri
/// Why does this work, I don't know!
/// </summary>
private void AddAllowAnyOtherHostFlagToHttpUriParser()
{
var getSyntaxMethod =
typeof(UriParser).GetMethod("GetSyntax", BindingFlags.Static | BindingFlags.NonPublic);
if (getSyntaxMethod == null)
{
throw new MissingMethodException("UriParser", "GetSyntax");
}
var uriParser = getSyntaxMethod.Invoke(null, new object[] { "http" });
var flagsField =
uriParser.GetType().BaseType.GetField("m_Flags", BindingFlags.Instance|BindingFlags.NonPublic);
if (flagsField == null)
{
throw new MissingFieldException("UriParser", "m_Flags");
}
int oldValue = (int)flagsField.GetValue(uriParser);
oldValue += 4096;
flagsField.SetValue(uriParser, oldValue);
}
public void AfterReceiveReply(ref Message reply, object correlationState)
{
}
}
Так в основном я создаю пользовательскую EndpointBehavior, которая использует отражение, чтобы добавить флаг enum в приватную переменную внутри UriParser. Это, по-видимому, предотвращает сбежавшую косую черту в моем запросе. Хозяева. Чтобы ури не был скрыт.
Возможный дубликат [Как передать символы слэш и другие символы с URL-адресами в службу WCF REST?] (Http://stackoverflow.com/questions/7176726/how-can-i-pass-slash-and -other-url-sensitive-characters-to-a-wcf-rest-service) –
Ответ в связанном вопросе не является допустимым ответом на этот вопрос, так как я не контролирую внешнюю службу, которая вызывается, поэтому изменение uritemplate в контракте на обслуживание невозможно. Я изменил свой вопрос, чтобы отразить это ограничение. – Stif