I am currently struggling with a very unusual behavior with WCF.
I created a REST endpoint to use with my application, manually tested it out using curl and everything seems to be fine, until I tried to write NUnit tests for it.
The content of my test is basically creating a HttpWebRequest and hit it on my api. Whenever I run the test I get the following error
UnsupportedMediaType Cannot process the message because the content type
'application/json;charset=utf-8;' was not the expected type 'text/xml;
charset=utf-8'.
I have searched for answers, almost all of them is related to mis-configured service, however that cant be the case since a curl request will work.
None explains how come the endpoint only fails with this setup.
Any help would be appreciated
When you send the request you need to specify the type of content. Try this -
HttpWebRequest request = ...
request.ContentType = "text/xml; charset=utf-8";
Also make sure that you are sending XML and not JSON content.
Related
I am trying to consume a REST API and i have an issue that it is driving me crazy...
I created a dll to wrap the service consumption layer, and i found that if i consume the services using the c# interactive feature it works fine.
The issue is when i try to consume it from another DLL, it is throwing Bad Request exception when executing GetResponse()
The code executed is...
var url = $"{_salesForceInstance}/services/data/{_salesForceVersion}/query/?q=SELECT+Id,Name,AccountId+from+Contact+WHERE+Email+=+'{email}'";
var webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.ServicePoint.CloseConnectionGroup(webRequest.ConnectionGroupName);
webRequest.Method = "GET";
webRequest.ContentType = "application/json";
webRequest.Headers.Add("Authorization", $"Bearer {_authorizationToken}");
var webResponse = webRequest.GetResponse() as HttpWebResponse;
I also when debugging code, to send the same through POSTMAN and it works fine...
Any ideas??? I am quite frustrated at this point why it works when consuming the dll from C# interactive but not from another dll...
As spender suggested i tried with Fiddler...
I found that despite of the fact both request looks the same, (the one from c# interactive and the one from the console app), in the one that returned the HTTP 400 error code the response included the following message
"[{"message":"TLS 1.0 has been disabled in this organization. Please use TLS 1.1 or higher when connecting to Salesforce using https.","errorCode":"UNSUPPORTED_CLIENT"}]"
That message does not appear when debugging...
Finally i solved by including the line described below in my code in order to use TLS 1.2
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Now it works !!!
Hope this helps to someone else!
Thanks!
As usual, in .NET 4.5, I used a HttpClient to send a get request to restful service (a remote server)
However, this time, it returned error 415 - Unsupported Media Type.
I'm expecting the request header including Content-Type = application/json.
And I cannot find a way to set Content-Type correctly.
Anybody has experience for this case or any suggestion will be appreciated!
The code is as below and the httpResponseMessage.RequestMessage.Headers
Updated 1
As I researched, I cannot add a retricted header for Content-Type. Since this is 4.5 implementation. Is this correct?
Updated 2
I tried to add
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
However it returned Cannot send a content-body with this verb-type
I am guessing that your server is not complaining about the invalid content type you requested but about the content type you sent with that request.
That you get
Cannot send a content-body with this verb-type
seems to hint that your tried to send a GET request. It is rather unusual (allthough technically the HTTP protocol allows this) that servers require a GET request with a body. So my best guess is that there is something wrong with the server.
I'm getting a 406 error when trying to use RestSharp to post a request to a third-party application. I'm new to REST, so I have to admit I didn't even know you could add headers. I tried adding these, but I'm still getting the same issue:
var client = new RestClient(myURL);
RestRequest request = new RestRequest("restAction", Method.POST);
request.AddHeader("Accept", "text/plain");
request.AddHeader("Content-Type", "text/plain");
request.AddParameter("parameter1", param1);
request.AddParameter("parameter2", param2);
var response = client.Execute(request);
From what I've read, this may be dealing with a header named "accept". Is that right?
Any idea what could be going on?
In general in HTTP, when a client makes a request to a server, it tells the server what kinds of formats it's prepared to understand (accept). This list of acceptable formats is what the Accept header is for. If the server can't respond using any of the media types in the Accept header, it will return a 406. Otherwise, it will indicate which media type it chose in the Content-Type header of the response. Putting "*/*" in the Accept header tells the server that the client can handle any response media type.
In my original comment to your question, I said that RestSharp looks like it's including "*" in the Accept header by default, but looking closer I see now that it's actually not. So, if you don't override the Accept header like you've done here, the default header value is "application/json","application/xml","text/json","text/x-json","text/javascript","text/xml", and it appears the server you're talking to doesn't speak any of these media types.
If the server you're working with doesn't speak json or xml, I don't think you can use RestSharp, unless you create your own deserializer. I'm not sure if you can do this from the public API or if you'd have to modify the source yourself and recompile it for you own needs.
Since you're still getting HTTP errors from the server, I would recommend taking RestSharp out of the equation for right now, and just speaking HTTP directly to the server until you actually get a correct response from the server. You can use a tool like Fiddler to make a HTTP requests directly. When you send the request (for now in the debugging stage), send an Accept header of "*/*" to get around the 406. Once you've figured out what media types the server can send back to you, you should change this back to being a media type you know you can read and you know the server can send.
It sounds like the main issue here is really just not knowing the protocol of the server. If there's any documentation on the service you're talking to, I would read that very carefully to figure out what media types it's prepared to respond with and how to craft the URLs that it expects.
I've got an app in the Windows 8 store that uses a WCF service hosted on Azure. When I use my proxy program, UltraSurf, the app fails to connect to the service with this error:
The content type text/html of the response message does not match the
content type of the binding (text/xml; charset=utf-8). If using a
custom encoder, be sure that the IsContentTypeSupported method is
implemented properly. The first 472 bytes of the response were:
'
The requested URL could not be retrieved
'.
The URL mentioned in the quote is the default 'can't find the page Url' that UltraSurf produces and so the error message is probably of no use. The question is, why/how does Ultrasurf block/get in the way of my connection?
Can anybody shed some light on what's going on and why it fails connect please?
Thanks!
Working without much information here, but I'd suspect that the problem is that the proxy is just being a little picky.
I believe that your error message basically says, "I'm expecting to get back 'text/xml' data, but what I see is 'text/html' data". That's probably not because it can actually see 'text/html' data coming back, but rather, because it's not seeing the content type header from the response telling it that it is xml data.
I don't know exactly how you implemented your WCF service, or what type of data it's set up to return, but you might want to ensure that you explicitly set the content type somewhere in your code before the return and see what happens. Something like:
Response.ContentType = "text/xml";
The only other thing that springs to mind is that your application might be picky about the content type for XML in general. There's a bit of, um... subtle difference... around whether the appropriate content type for XML is 'application/xml' or 'text/xml'. It's possible that your service is presenting the one that your proxy doesn't like?
I have a web application (which I have no control over) I need to send HTTP post programatically to. Currently I've using HttpWebRequest like
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://someserver.com/blah/blah.aspx");
However the application was returning a "Unknown Server Error (not the IIS error, a custom application error page)" when posting to data. Using Fiddler to compare my Post vs IE post I can see the only difference is in the POST line of the request:
In Internet Explorer Fiddler (RAW view) shows traffic
POST /blah/blah.aspx HTTP/1.1
In my C# program fiddler (RAW view) records traffic as
POST https://someserver.com/blah/blah.aspx HTTP/1.1
This is only difference from both both requests.
From what I've researched so far it seems there is no way to make HttpWebRequest.Create post the relative URL.Note: I see many posts on "how to use relative URLs" but these suggestions do not work, as the actual post is still done using an absolute URL (when you sniff the HTTP traffic)
What is simplest way to accomplish this post with relative URL?
(Traffic is NOT going through a proxy)
Update: For the time being I'm using IE automation to do scheduled perf test, instead of method above. I might look at another scripting language as I did want to test without any browser.
No, you can't do POST without server in a Url.
One possible reason your program fails is if it does not use correct proxy and as result can't resolve server name.
Note: Fiddler shows path and host separately in the view you are talking about.
Configure you program to use Fiddler as proxy (127.0.0.1:8888) and compare requests that you are making with browser's ones. Don't forget to switch Fiddler to "show all proceses".
Here is article on configuring Fiddler for different type of environment including C# code: Fiddler: Configuring clients
objRequest = (HttpWebRequest)WebRequest.Create(url);
objRequest.Proxy= new WebProxy("127.0.0.1", 8888);