I'm using BizTalk 2013 R2. There was no additional helpful information in the WCF-WebHttp Adapter link posted above. I had already tried everything suggested there and elsewhere.
To follow up, ultimately what I did was to create a dynamic send port rather than using a static send port as I initially tried.
First I manually encoded my output parameter to replace any spaces with the web standard "%20".
In a Message Assignment shape I set various properties on the outgoing message to configure the dynamic send. I pulled certain values from the ESSO database so they can be configured at runtime:
MsgMyAppCustSearchRequest(WCF.HttpMethodAndUrl) = "GET";
MsgMyAppCustSearchRequest(WCF.HttpHeaders) =
XXX.Common.Helpers.SSOInterface.SSOInterface.Read("YYY.MyAppAdapter", "HttpHeaderContent") +
System.Environment.NewLine +
XXX.Common.Helpers.SSOInterface.SSOInterface.Read("YYY.MyAppAdapter", "HttpHeaderAuthorization");
MsgMyAppCustSearchRequest(WCF.SuppressMessageBodyForHttpVerbs) = "GET";
// Security is set later in a separate Decide shape
MsgMyAppCustSearchRequest(BTS.SendPipelineResponseConfig) =
"<Root xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'><Stages><Stage CategoryId='9d0e4103-4cce-4536-83fa-4a5040674ad6'><Components><Component Name='Microsoft.BizTalk.Component.JsonDecoder'><Properties><RootNode vt='8'>Root</RootNode><RootNodeNamespace vt='8'>http://XXX.YYY.MyAppAdapter.MyApp_CustSearchResponse_JSON</RootNodeNamespace></Properties></Component><Component Name='Microsoft.BizTalk.Component.XmlDasmComp'><Properties><AllowUnrecognizedMessage vt='11'>-1</AllowUnrecognizedMessage></Properties></Component></Components></Stage></Stages></Root>";
MsgMyAppCustSearchRequest(WCF.VariablePropertyMapping) = System.String.Empty;
MsgMyAppCustSearchRequest(BTS.RetryCount) = 0;
MsgMyAppCustSearchRequest(WCF.MaxReceivedMessageSize) = 200000;
MsgMyAppCustSearchRequest(WCF.OpenTimeout) = "00:01:00";
MsgMyAppCustSearchRequest(WCF.CloseTimeout) = "00:01:00";
MsgMyAppCustSearchRequest(WCF.SendTimeout) = "00:01:00";
MsgMyAppCustSearchRequest(BTS.LRPMsgBodyTracking) = 1; // you could parameterize or use other message tracking settings
Since you can't use If-Then-Else in a Message Assignment shape, separately I set other properties depending on whether we were using https or http:
MsgMyAppCustSearchRequest2 = MsgMyAppCustSearchRequest;
MsgMyAppCustSearchRequest2(WCF.SecurityMode) = "Transport"; // or "None" for http
Finally I set some dynamic send port properties in an Expression shape, including crucially the properly encoded URL:
Dynamic_Send_MyApp_CustomerSearchByPhone(Microsoft.XLANGs.BaseTypes.Address) =
XXX.Common.Helpers.SSOInterface.SSOInterface.Read("YYY.MyAppAdapter", "ServerURL") +
XXX.Common.Helpers.SSOInterface.SSOInterface.Read("YYY.MyAppAdapter", "OperationGetCustomerSearch") +
"?q=" + MsgMyAppCustSearchRequest2(phoneNumber) +
"&skip=0&take=2"; // Hopefully we only ever get one, but by allowing 2 we can debug if we do get multiples
Dynamic_Send_MyApp_CustomerSearchByPhone(Microsoft.XLANGs.BaseTypes.TransportType) = "WCF-WebHttp";
You can configure the Send and Receive Pipelines on the Port shape.
This works. Seems silly that I had to do all this in order to gain control over the URL encoding of my parameter.