Is it possible to change the data of incoming HTTP request in WCF?
I've already found out how to change HTTP method (using IDispatchOperationSelector and HttpRequestMessageProperty of the incoming message).
I'm writing behavior that would enable to make "POST" requests using GET requests (with method and data stored in query string). I can override the HTTP method, but I can't find the solution to override the data. I need to load the data stored in query string and use them as HTTP body.
Any thoughts?
You'll need to recreate the incoming message so that the message body contains the information you want to pass. The body will likely be in either XML or JSON format (supported out-of-the-box). The code below shows one example of how this can be done.
public class StackOverflow_10391354
{
[ServiceContract]
public class Service
{
[WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest)]
public int Add(int x, int y)
{
return x + y;
}
}
class MyWebHttpBehavior : WebHttpBehavior
{
protected override WebHttpDispatchOperationSelector GetOperationSelector(ServiceEndpoint endpoint)
{
return new MyOperationSelector();
}
public override void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
base.ApplyDispatchBehavior(endpoint, endpointDispatcher);
}
}
class MyOperationSelector : WebHttpDispatchOperationSelector
{
protected override string SelectOperation(ref Message message, out bool uriMatched)
{
HttpRequestMessageProperty prop = (HttpRequestMessageProperty)message.Properties[HttpRequestMessageProperty.Name];
if (message.Headers.To.LocalPath.EndsWith("/Add") && prop.Method == "GET")
{
prop.Method = "POST";
uriMatched = true;
message = CreateBodyMessage(message);
return "Add";
}
else
{
return base.SelectOperation(ref message, out uriMatched);
}
}
private Message CreateBodyMessage(Message message)
{
HttpRequestMessageProperty prop = message.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
string queryString = prop.QueryString;
NameValueCollection nvc = HttpUtility.ParseQueryString(queryString);
StringBuilder sb = new StringBuilder();
sb.Append('{');
bool first = true;
foreach (string key in nvc.Keys)
{
if (first)
{
first = false;
}
else
{
sb.Append(',');
}
sb.Append('\"');
sb.Append(key);
sb.Append("\":\"");
sb.Append(nvc[key]);
sb.Append('\"');
}
sb.Append('}');
string json = sb.ToString();
XmlDictionaryReader jsonReader = JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(json), XmlDictionaryReaderQuotas.Max);
Message result = Message.CreateMessage(MessageVersion.None, null, jsonReader);
result.Properties.Add(HttpRequestMessageProperty.Name, prop);
result.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Json));
result.Headers.To = message.Headers.To;
return result;
}
}
public static void Test()
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(Service), new WebHttpBinding(), "");
endpoint.Behaviors.Add(new MyWebHttpBehavior());
host.Open();
Console.WriteLine("Host opened");
WebClient c = new WebClient();
Console.WriteLine(c.DownloadString(baseAddress + "/Add?x=66&y=88"));
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}
You can use a message inspector: http://weblogs.asp.net/paolopia/archive/2007/08/23/writing-a-wcf-message-inspector.aspx
Related
I have a client generated from a WSDL file and uses this in a .NET core 3.1 project. I can't set the Authorization header through ClientCredentials and a BasicHttp(s)Binding. I used hookbin to see my request. This is my code:
BasicHttpsBinding binding= new BasicHttpsBinding();
//for http
//binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
EndpointAddress endpoint = new EndpointAddress("https://hookb.in/...");
var soapClient = new RandomServiceClient(binding, endpoint);
soapClient.ClientCredentials.UserName.UserName = "user";
soapClient.ClientCredentials.UserName.Password = "bla";
soapClient.CallServiceMethod(new Request { Foo = "Bar" });
I already tried using other Bindings like WSHttpBinding like the Microsoft documentation suggests: https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/transport-security-with-basic-authentication
What am i doing wrong?
Thanks to: https://stackoverflow.com/a/60714907/9124424
I found a solution, but i still wonder why the code in my question does not work
So you need to add an IClientMessageInspector and an IEndpointBehavior
public class AddHttpHeaderMessageEndpointBehavior : IEndpointBehavior
{
private readonly IClientMessageInspector _httpHeaderMessageInspector;
public AddHttpHeaderMessageEndpointBehavior(Dictionary<string, string> headers)
{
_httpHeaderMessageInspector = new HttpHeaderMessageInspector(headers);
}
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.ClientMessageInspectors.Add(_httpHeaderMessageInspector);
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
}
public void Validate(ServiceEndpoint endpoint)
{
}
}
public class HttpHeaderMessageInspector : IClientMessageInspector
{
private readonly Dictionary<string, string> _headers;
public HttpHeaderMessageInspector(Dictionary<string, string> headers)
{
_headers = headers;
}
public void AfterReceiveReply(ref Message reply, object correlationState)
{
}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
if (request.Properties.Count == 0 || request.Properties[HttpRequestMessageProperty.Name] == null)
{
request.Properties.Add(HttpRequestMessageProperty.Name, new HttpRequestMessageProperty());
}
var headersCollection = ((HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name]).Headers;
foreach (var header in _headers) headersCollection[header.Key] = header.Value;
return null;
}
}
And then you can add this IEndpointBehavior to the Endpoint in the client instance
BasicHttpsBinding binding= new BasicHttpsBinding();
//for http
//binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
EndpointAddress endpoint = new EndpointAddress("https://hookb.in/...");
var soapClient = new RandomServiceClient(binding, endpoint);
var headers = new Dictionary<string, string>
{
{"Authorization", $"Basic --INSERT TOKEN--"}
}));
var behavior = new AddHttpHeaderMessageEndpointBehavior(headers);
soapClient.Endpoint.EndpointBehaviors.Add(behavior);
soapClient.CallServiceMethod(new Request { Foo = "Bar" });
For me Stutje's solution works perfect, except:
needed to remove binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;, otherwise it asking to set credentials directly.
set binding.Security.Mode = BasicHttpSecurityMode.Transport; to use https
i 'm trying to call a post method via Postman
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "Login"]
string Login(string host, string user, string pass, string applicationId);
public string Login(string host, string user, string pass, string applicationId)
{
int res= new login().Loginn(host, user, pass, applicationId);
if (res == 1)
return "Connected";
else
return "Failed";
}
whene i pass those parameters via Postman in body request form-data the response is 400 bad request
whene i change to application/json and i put a json string in raws it works .
is there any solution to use body form-data request please whithout using one parameter with stream type
thank you
You will need to have a custom message formatter that will understand the form-urlencoded input and convert that into the parameters of your operation. The post at https://blogs.msdn.microsoft.com/endpoint/2011/05/03/wcf-extensibility-message-formatters/ has a lot of informations about formatters, and the code below shows a simple implementation of such a formatter that can deal with form data.
public class StackOverflow_35921627
{
[ServiceContract]
public interface ITest
{
[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json)]
string Login(string host, string user, string pass, string applicationId);
}
public class Service : ITest
{
public string Login(string host, string user, string pass, string applicationId)
{
return string.Format("Login result: {0} - {1} - {2} - {3}", host, user, pass, applicationId);
}
}
public class MyWebHttpBehavior : WebHttpBehavior
{
protected override IDispatchMessageFormatter GetRequestDispatchFormatter(OperationDescription operationDescription, ServiceEndpoint endpoint)
{
var originalFormatter = base.GetRequestDispatchFormatter(operationDescription, endpoint);
return new FormDataDispatchFormatter(operationDescription, originalFormatter);
}
}
public class FormDataDispatchFormatter : IDispatchMessageFormatter
{
IDispatchMessageFormatter originalFormatter;
Dictionary<string, int> parameterNames;
public FormDataDispatchFormatter(OperationDescription operation, IDispatchMessageFormatter originalFormatter)
{
var inputMessageBodyParts = operation.Messages[0].Body.Parts;
this.parameterNames = new Dictionary<string, int>();
for (int i = 0; i < inputMessageBodyParts.Count; i++)
{
if (inputMessageBodyParts[i].Type == typeof(string))
{
// For now, only support string parameters; others will be ignored
this.parameterNames.Add(inputMessageBodyParts[i].Name, i);
}
}
this.originalFormatter = originalFormatter;
}
public void DeserializeRequest(Message message, object[] parameters)
{
object httpRequestProperty;
if (!message.Properties.TryGetValue(HttpRequestMessageProperty.Name, out httpRequestProperty))
{
throw new InvalidOperationException("This formatter can only be used with HTTP");
}
var contentType = ((HttpRequestMessageProperty)httpRequestProperty).Headers[HttpRequestHeader.ContentType];
if (contentType == null || !contentType.StartsWith("application/x-www-form-urlencoded"))
{
this.originalFormatter.DeserializeRequest(message, parameters);
return;
}
object bodyFormatProperty;
if (!message.Properties.TryGetValue(WebBodyFormatMessageProperty.Name, out bodyFormatProperty) ||
(bodyFormatProperty as WebBodyFormatMessageProperty).Format != WebContentFormat.Raw)
{
throw new InvalidOperationException("Incoming messages must have a body format of Raw. Is a ContentTypeMapper set on the WebHttpBinding?");
}
XmlDictionaryReader bodyReader = message.GetReaderAtBodyContents();
bodyReader.ReadStartElement("Binary");
byte[] rawBody = bodyReader.ReadContentAsBase64();
MemoryStream ms = new MemoryStream(rawBody);
StreamReader sr = new StreamReader(ms);
string formData = sr.ReadToEnd();
string[] parts = formData.Split('&');
foreach (var part in parts)
{
// TODO: handle url-decoding
var kvp = part.Split('=');
if (kvp.Length != 2)
{
throw new InvalidOperationException("Only support simple parameters for now");
}
int index;
if (this.parameterNames.TryGetValue(kvp[0], out index))
{
parameters[index] = kvp[1];
}
}
}
public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
{
throw new NotSupportedException("This is a request-only formatter");
}
}
internal static void Test()
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ITest), new WebHttpBinding(), "");
endpoint.Behaviors.Add(new MyWebHttpBehavior());
host.Open();
Console.WriteLine("Host opened");
SendPostRequest(baseAddress + "/Login", "application/x-www-form-urlencoded", "host=myHost&user=myUser&pass=myPassword&applicationId=app123");
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
static void SendPostRequest(string url, string contentType, string body)
{
HttpWebRequest req = HttpWebRequest.CreateHttp(url);
req.Method = "POST";
req.ContentType = contentType;
byte[] bodyBytes = Encoding.UTF8.GetBytes(body);
Stream reqStream = req.GetRequestStream();
reqStream.Write(bodyBytes, 0, bodyBytes.Length);
reqStream.Close();
HttpWebResponse resp;
try
{
resp = (HttpWebResponse)req.GetResponse();
}
catch (WebException ex)
{
resp = (HttpWebResponse)ex.Response;
}
if (resp == null)
{
Console.WriteLine("Response is null");
}
else
{
Console.WriteLine("HTTP/{0} {1} {2}", resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);
foreach (string headerName in resp.Headers.AllKeys)
{
Console.WriteLine("{0}: {1}", headerName, resp.Headers[headerName]);
}
Console.WriteLine();
Stream respStream = resp.GetResponseStream();
if (respStream != null)
{
Console.WriteLine(new StreamReader(respStream).ReadToEnd());
}
else
{
Console.WriteLine("HttpWebResponse.GetResponseStream returned null");
}
}
Console.WriteLine();
Console.WriteLine(" *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* ");
Console.WriteLine();
}
}
I'm trying to POST to a REST service using the default WebHttpBinding binding. The service only accepts "text/xml" as the content-type and the WebHttpBinding is sending "application/xml, charset-utf=8". Is there a way to change the default content type without using the the HttpWebRequest?
You can use the WebOperationContext inside an operation scope to change the outgoing content type of the requests, as shown below.
public class StackOverflow_7771645
{
[ServiceContract]
public interface ITest
{
[OperationContract]
string Process();
}
public class Service : ITest
{
public string Process()
{
return "Request content type: " + WebOperationContext.Current.IncomingRequest.ContentType;
}
}
public static void Test()
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
WebServiceHost host = new WebServiceHost(typeof(Service), new Uri(baseAddress));
host.Open();
Console.WriteLine("Host opened");
WebChannelFactory<ITest> factory = new WebChannelFactory<ITest>(new Uri(baseAddress));
ITest proxy = factory.CreateChannel();
using (new OperationContextScope((IContextChannel)proxy))
{
WebOperationContext.Current.OutgoingRequest.ContentType = "text/xml";
Console.WriteLine(proxy.Process());
}
using (new OperationContextScope((IContextChannel)proxy))
{
WebOperationContext.Current.OutgoingRequest.ContentType = "application/xml";
Console.WriteLine(proxy.Process());
}
((IClientChannel)proxy).Close();
factory.Close();
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}
I have a custom header stored in a "string" variable, I need to replace the header of a outgoing SOAP request from my WCF client with the header in the "string" type variable. Based on research I see that implementing the MessageHeaders.WriteHeaderContents can work but this method accepts only XmlDictionaryWriter or XmlWriter types as input. I have a string input. How do I code in C# ..
Message headers are a SOAP concept, and SOAP requests are XML documents, so you really need some XML-ness there. But for your scenario, you actually don't need to override MessageHeaders, you can use an inspector and simply replace the header at that point, as shown in the example below (the conversion to XML will be done by the MessageHeader class).
public class StackOverflow_7141998
{
[MessageContract]
public class MyMC
{
[MessageHeader(Name = "MyHeader", Namespace = "http://my.namespace.com")]
public string HeaderValue { get; set; }
[MessageBodyMember(Name = "MyBody", Namespace = "http://my.namespace.com")]
public string BodyValue { get; set; }
}
[ServiceContract]
public interface ITest
{
[OperationContract]
void Process(MyMC mc);
}
public class Service : ITest
{
public void Process(MyMC mc)
{
Console.WriteLine("Header value: {0}", mc.HeaderValue);
}
}
public class MyInspector : IEndpointBehavior, IClientMessageInspector
{
public string NewHeaderValue { get; set; }
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.MessageInspectors.Add(this);
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
}
public void Validate(ServiceEndpoint endpoint)
{
}
public void AfterReceiveReply(ref Message reply, object correlationState)
{
}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
int originalIndex = request.Headers.FindHeader("MyHeader", "http://my.namespace.com");
if (originalIndex >= 0)
{
request.Headers.Insert(originalIndex, MessageHeader.CreateHeader("MyHeader", "http://my.namespace.com", this.NewHeaderValue));
request.Headers.RemoveAt(originalIndex + 1);
}
return null;
}
}
public static void Test()
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ITest), new WSHttpBinding(), "");
host.Open();
Console.WriteLine("Host opened");
ChannelFactory<ITest> factory = new ChannelFactory<ITest>(new WSHttpBinding(), new EndpointAddress(baseAddress));
MyInspector inspector = new MyInspector { NewHeaderValue = "Modified header value" };
factory.Endpoint.Behaviors.Add(inspector);
ITest proxy = factory.CreateChannel();
proxy.Process(new MyMC { HeaderValue = "Original header value", BodyValue = "The body" });
((IClientChannel)proxy).Close();
factory.Close();
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}
I can't pass over parameters to wcf web service. My web method:
[OperationContract]
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "playersJson2")]
List<Person> GetPlayers(string name1, string name2);
When I make http post request, I got 200 OK response with correct json form but web service seems to fail to get paramters (name1, name2). Wireshark shows following:
Do you see anything wrong?
Update: Not sure it matters but my service is using "webHttpBinding" and post request is coming from Android.
WCF doesn't support forms/encoded data out-of-the box. The other answers mentioned some alternatives (receive the input as a Stream, change the request to JSON). Another alternative, which doesn't force you to change the request or the operation is to use a custom formatter which understands form-urlencoded requests. The code below shows one which does that.
public class MyWebHttpBehavior : WebHttpBehavior
{
protected override IDispatchMessageFormatter GetRequestDispatchFormatter(OperationDescription operationDescription, ServiceEndpoint endpoint)
{
bool isRequestWrapped = this.IsRequestWrapped(operationDescription.Behaviors.Find<WebInvokeAttribute>());
IDispatchMessageFormatter originalFormatter = base.GetRequestDispatchFormatter(operationDescription, endpoint);
if (isRequestWrapped)
{
return new MyFormUrlEncodedAwareFormatter(
operationDescription,
originalFormatter,
this.GetQueryStringConverter(operationDescription));
}
else
{
return originalFormatter;
}
}
private bool IsRequestWrapped(WebInvokeAttribute wia)
{
WebMessageBodyStyle bodyStyle;
if (wia.IsBodyStyleSetExplicitly)
{
bodyStyle = wia.BodyStyle;
}
else
{
bodyStyle = this.DefaultBodyStyle;
}
return bodyStyle == WebMessageBodyStyle.Wrapped || bodyStyle == WebMessageBodyStyle.WrappedRequest;
}
class MyFormUrlEncodedAwareFormatter : IDispatchMessageFormatter
{
const string FormUrlEncodedContentType = "application/x-www-form-urlencoded";
OperationDescription operation;
IDispatchMessageFormatter originalFormatter;
QueryStringConverter queryStringConverter;
public MyFormUrlEncodedAwareFormatter(OperationDescription operation, IDispatchMessageFormatter originalFormatter, QueryStringConverter queryStringConverter)
{
this.operation = operation;
this.originalFormatter = originalFormatter;
this.queryStringConverter = queryStringConverter;
}
public void DeserializeRequest(Message message, object[] parameters)
{
if (IsFormUrlEncodedMessage(message))
{
XmlDictionaryReader bodyReader = message.GetReaderAtBodyContents();
bodyReader.ReadStartElement("Binary");
byte[] bodyBytes = bodyReader.ReadContentAsBase64();
string body = Encoding.UTF8.GetString(bodyBytes);
NameValueCollection pairs = HttpUtility.ParseQueryString(body);
Dictionary<string, string> values = new Dictionary<string, string>();
foreach (var key in pairs.AllKeys)
{
values.Add(key, pairs[key]);
}
foreach (var part in this.operation.Messages[0].Body.Parts)
{
if (values.ContainsKey(part.Name))
{
string value = values[part.Name];
parameters[part.Index] = this.queryStringConverter.ConvertStringToValue(value, part.Type);
}
else
{
parameters[part.Index] = GetDefaultValue(part.Type);
}
}
}
else
{
this.originalFormatter.DeserializeRequest(message, parameters);
}
}
public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
{
throw new NotSupportedException("This is a request-only formatter");
}
private static bool IsFormUrlEncodedMessage(Message message)
{
object prop;
if (message.Properties.TryGetValue(WebBodyFormatMessageProperty.Name, out prop))
{
if (((WebBodyFormatMessageProperty)prop).Format == WebContentFormat.Raw)
{
if (message.Properties.TryGetValue(HttpRequestMessageProperty.Name, out prop))
{
if (((HttpRequestMessageProperty)prop).Headers[HttpRequestHeader.ContentType].StartsWith(FormUrlEncodedContentType))
{
return true;
}
}
}
}
return false;
}
private static object GetDefaultValue(Type type)
{
if (type.IsValueType)
{
return Activator.CreateInstance(type);
}
else
{
return null;
}
}
}
}
[ServiceContract]
public class Service
{
[WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest)]
public string Concat(string text1, string text2)
{
return text1 + text2;
}
[WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest)]
public int Add(int x, int y)
{
return x + y;
}
}
class Program
{
public static void SendRequest(string uri, string method, string contentType, string body)
{
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(uri);
req.Method = method;
if (!String.IsNullOrEmpty(contentType))
{
req.ContentType = contentType;
}
if (body != null)
{
byte[] bodyBytes = Encoding.UTF8.GetBytes(body);
req.GetRequestStream().Write(bodyBytes, 0, bodyBytes.Length);
req.GetRequestStream().Close();
}
HttpWebResponse resp;
try
{
resp = (HttpWebResponse)req.GetResponse();
}
catch (WebException e)
{
resp = (HttpWebResponse)e.Response;
}
Console.WriteLine("HTTP/{0} {1} {2}", resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);
foreach (string headerName in resp.Headers.AllKeys)
{
Console.WriteLine("{0}: {1}", headerName, resp.Headers[headerName]);
}
Console.WriteLine();
Console.WriteLine(new StreamReader(resp.GetResponseStream()).ReadToEnd());
Console.WriteLine();
Console.WriteLine(" *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* ");
Console.WriteLine();
}
static void Main(string[] args)
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
host.AddServiceEndpoint(typeof(Service), new WebHttpBinding(), "").Behaviors.Add(new MyWebHttpBehavior());
host.Open();
Console.WriteLine("Host opened");
SendRequest(baseAddress + "/Add", "POST", "application/json", "{\"x\":22,\"y\":33}");
SendRequest(baseAddress + "/Add", "POST", "application/x-www-form-urlencoded", "x=22&y=33");
SendRequest(baseAddress + "/Add", "POST", "application/json", "{\"x\":22,\"z\":33}");
SendRequest(baseAddress + "/Add", "POST", "application/x-www-form-urlencoded", "x=22&z=33");
SendRequest(baseAddress + "/Concat", "POST", "application/json", "{\"text1\":\"hello\",\"text2\":\" world\"}");
SendRequest(baseAddress + "/Concat", "POST", "application/x-www-form-urlencoded", "text1=hello&text2=%20world");
SendRequest(baseAddress + "/Concat", "POST", "application/json", "{\"text1\":\"hello\",\"text9\":\" world\"}");
SendRequest(baseAddress + "/Concat", "POST", "application/x-www-form-urlencoded", "text1=hello&text9=%20world");
}
}
It looks like you need to parse your post data manual...
You can look here for example
The only thing that looks out of place is the playerJson2 but that is just because I have never used the UriTemplate before. Can you get it to work without the UriTemplate and just post to /WcfService1/Service1.svc/GetPlayers? Are there any other WCF services that you have working in the project?
You need to set the correct Content-Type which is application/json in this case.
Sorry for misreading your question. Update your UriTemplate as follows:
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "playersJson2?name1={name1}&name2={name2}")]