Internal 500 error in WCf service get response method - wcf

Below is my request i get a 500 internal server error at getresponse
string requestData = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Header><h:HeaderItem xmlns:h=\"http://tempuri.org/\">a header item</h:HeaderItem><ActivityId CorrelationId=\"090c553b-bfcc-4e4f-94cd-1b4333fe82a9\" xmlns=\"http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics\">377a454b-b543-4c6f-b4ac-3981029b60e6</ActivityId></s:Header><s:Body><string xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/\">a body item</string></s:Body></s:Envelope>";
byte[] requestDataBytes = Encoding.UTF8.GetBytes(requestData);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost/WebService/");
request.Method = "POST";
request.ContentType = "text/xml; charset=utf-8";
request.Headers.Add("SOAPAction", "http://tempuri.org/IWebService/GetMessage");
request.ContentLength = requestDataBytes.Length;
StreamWriter streamWriter = new StreamWriter(request.GetRequestStream());
streamWriter.Write(requestData);
streamWriter.Flush();
streamWriter.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader streamReader = new StreamReader(response.GetResponseStream());
string responseBody = streamReader.ReadToEnd();

I may have an answer for you.
Move the line where you set your headers to the point before you set the content type, and retry your code, as follows:
request.Headers.Add("SOAPAction", "http://tempuri.org/IWebService/GetMessage");
request.ContentType = "text/xml; charset=utf-8";
I make this suggestion based on the documentation for the ContentType property for the WebRequest object from MS:
MS docs on WebRequest
The value for this property is stored in WebHeaderCollection . If
WebHeaderCollection is set, the property value is lost.
Now, I realize we're not expressly setting the WebHeaderCollection, but you are setting a header in that collection, and it made me suspect at least the possibility of this being a problem - rendering your existing ContentType blank, and being interpreted as some default on the inbound side of the web service.
Maybe a long shot, but it might be worth a try.

You should enable WCF trace logging on your server and see if it indicates an error. Typically errors that occur during deserialization or in the WCF layers before hitting your app code will write to this log.
For more info on setting up WCF trace logging, see here or here.

Related

Post request error when sending "application/octet-stream" to an ASP.NET Core Web API service

I need to create an ASP.NET Core 3 Web API that understand this URL
http://myapp.com/MyASPNetCore3WebApi/myController/myWebMethod?user=A0001
and one zipfile which goes as a content. This is the code that calls the needed API, which I need to create:
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(URI);
httpWebRequest.Timeout = -1;
httpWebRequest.KeepAlive = false;
httpWebRequest.Method = "POST";
httpWebRequest.ProtocolVersion = HttpVersion.Version10;
httpWebRequest.ContentType = "application/octet-stream";
httpWebRequest.Accept = "application/octet-stream";
httpWebRequest.ContentLength = data.Length;
Stream requestStream = httpWebRequest.GetRequestStream();
requestStream.Write(data, 0, data.Length);
requestStream.Close();
HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
The code above is working fine, it is used everyday, sending data to a java web service, now I am replacing that system for a new one in ASP.NET Core and I can't change the caller's code, that's why I need to create a Web API that understand that URL.
I have wrote this code in my Web API, but I guess I am missing something that I canĀ“t figure it out because I get an error ion the client (code above)
[HttpPost("myWebMethod")]
public FileStreamResult myWebMethod(string user, [FromBody] Stream compress)
{
byte[] zip = ((MemoryStream)compress).ToArray();
byte[] data = ZipHelper.Uncompress(zip);
.....................
}
The error I get in the client is this:-
[System.Net.WebException] {"The remote server returned an error: (415)
Unsupported Media Type."} System.Net.WebException
Thanks in advance for any help
If the goal is to read the raw request content, this can be done using HttpContext controller property. HttpContext has Request property that provides access to the actual HTTP request.
No additional model properties or controller arguments are needed to access raw request stream. It's important to note that FromBody and FromForm binding should not be used in this case.
There are couple notes regarding the code in the example from the original question.
byte[] zip = ((MemoryStream)compress).ToArray();
byte[] data = ZipHelper.Uncompress(zip);
The HttpContext.Request.Body property does not return MemoryStream, it returns its own implementation of a Stream. It means that there is no ToArray method.
When reading the entire content of a request directly into the server's memory, it is better to check the content length, otherwise the client can crash the server by sending a large enough request.
Using *Async methods when reading the content of the request will improve performance.

How to add parameter to HttpWebRequest

I'm trying to get some data from Spotify's API, but I receive some errors from compilator and I think it may happen because I didn't add parameter grant_type=client_credentials.
The question is how can I add this parameter into HttpWebRequest object?
var token = GetToken();
var request = HttpWebRequest.CreateHttp($"{BaseAddress}search?q=Batman&type=playlist&market=US&limit=10&offset=5&access_token={token}");
request.Method = WebRequestMethods.Http.Get;
request.Headers.Add(HttpRequestHeader.Authorization, "Basic " + token);
request.ContentType = "application/json";
request.Accept = "application/json";
When you get the Token is where you need to add this parameter, your GetToken method will be sending the Client Credentials Flow of the Client Id and Client Secret and it is there where the grant_type of client_credentials needs to be sent as a HttpWebRequest with the ContentType of application/x-www-form-urlencoded this is what the documentation refers to as a Request Body Parameter.
I've used HttpClient that allows FormUrlEncodedContent to do this but you should be able to send that information using HttpWebRequest the way you are doing it with a POST request but the GetToken code will need to be modified, that isn't shown in the question

Unable to consume OpenShift REST API in C#.net

I want to know how can I consume OpenShift Rest API into C#.net based application. I have gone through URL
https://access.redhat.com/documentation/en-US/OpenShift_Online/2.0/pdf/REST_API_Guide/OpenShift_Online-2.0-REST_API_Guide-en-US.pdf, in this there mentioned example for Ruby, Python and cRUL. but not mentioned for .Net. so I have created sample application for consuming this api.
below is the code -
string URL = "https://openshift.redhat.com/broker/rest/api";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.Method = "GET";
request.ContentType = "application/xml;";
try
{
WebResponse webResponse = request.GetResponse();
Stream webStream = webResponse.GetResponseStream();
StreamReader responseReader = new StreamReader(webStream);
string response = responseReader.ReadToEnd();
Console.Out.WriteLine(response);
responseReader.Close();
}
catch (Exception e)
{
Console.Out.WriteLine("-----------------");
Console.Out.WriteLine(e.Message);
}
While executing above code I am getting following error -
"The remote server returned an error: (406) Not Acceptable."
Please let me where I am doing wrong.
Thanks in advance
Jyoti
You are using the wrong HTTP header. ContentType is used for POST/PUT operations to tell server what to expect. When you GET a resource you must specify an Accept header.
request.Accept = "application/xml";

Unable to connect web exception mvc4

we are doing a facebook posting application using HttpWebRequest.
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
//doing some stuff here.
}
This code is failing at line uisng with unable to connect to server exception.
This is not failing always, but it is failing in 90% cases.
Can somebody advise how best this can be addressed?
Try this (this may not be an answer; just trying to debug your issue), see if it fails like your other one does; then try replacing google.com with your own URL:
WebRequest g = HttpWebRequest.Create("http://www.google.com");
var response = g.GetResponse();

How do I send SOAP Request to WCF Service?

Can anyone point me to an example how to post a SOAP Request to a WCF Service and return a SOAP Response? Basically a Travel client sends a SOAP request with search parameters and the WCF Service checks within the database and then sends the appropriate holidays.
I keep getting this error, with the method I have used: "The remote server returned an error: (400) Bad Request"
The error you got is because the server does not understand the HTTP request.
It could be the binding you configured or the service proxy is incorrect at client level.
Or the service you defined expects HTTP GET rather than HTTP POST. Sometimes the add service reference may not generate correct HTTP verb for some [WebGet] attributed operations. You may need to add [WebGet] for the operation at client side manually.
Either have a look at SoapUI, or locate the WcfTestClient buried deep in your Visual Studio folders (C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE).
Both can connect to a WCF service and send/receive SOAP messages.
Or create your own little client, using svcutil.exe:
svcutil.exe (service URL)
will create a little *.cs file and a *.config file for you, which you can then use to call the service.
Marc
You haven't given many details as to how far along you are with the service, so it's hard to say.
If this is literally the first hit to the service, this error could occur if WCF has not been registered properly with IIS. Specifically the .svc extension needs to be mapped to the ASP.NET ISAPI module.
thanks for taking the time out to answer this.
The service works fine, if a client creates a reference to my WCF Service and makes a method call, the appropriate response is sent.
I forgot to add, that my client is sends a HTTP Post Request to my WCF Service.
The appropriate response is then created and returned to the Client.
I can read the HTTP Request, however when i try and access the HTTP response, i get error -"The remote server returned an error: (400) Bad Request"
The error happens when the code reaches this line:
// Get the response.
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
See code below:
private void CreateMessage()
{
// Create a request using a URL that can receive a post.
WebRequest request = WebRequest.Create("http://www.XXXX.com/Feeds");
string postData = "<airport>Heathrow</airport>";
// user function
request.Method = "POST";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentType = "application/soap+xml; charset=utf-8";
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
// Get the response.
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
// Display the status.
HttpContext.Current.Response.Write(((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
// Display the content.
HttpContext.Current.Response.Write(responseFromServer);
// Clean up the streams.
reader.Close();
dataStream.Close();
response.Close();
}
regards
Kojo
Note
The recommended way of accessing WCF Service from other .NET application is by using the "Connected Services" reference. Below I describe how you can create and send SOAP requests in a more manual (and not recommended for production code) manner.
In short
You need:
Content-Type: text/xml; charset=utf-8 header
SOAPAction: http://tempuri.org/YourServiceClass/YourAction header
Request content wrapped in SOAP envelope.
Longer version (example)
Lets take a WCF Service Application scaffolding as an example.
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
}
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
}
Using Wireshark, I found out that the requests made the default way (connected service reference) contain Content-Type: text/xml; charset=utf-8 and SOAPAction: http://tempuri.org/IService1/GetData headers and following SOAP envelope:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<GetData xmlns="http://tempuri.org/"> <!-- Action name -->
<value>123</value> <!-- Parameters -->
</GetData>
</s:Body>
</s:Envelope>
Using Insomnia, I tested that it's all we need in order to make the request pass successfully, so now just need to port it to the C#:
// netcoreapp3.1
static async Task<string> SendHttpRequest(string serviceUrl, int value)
{
// Example params:
// serviceUrl: "http://localhost:53045/Service1.svc"
// value: 123
using var client = new HttpClient();
var message = new HttpRequestMessage(HttpMethod.Post, serviceUrl);
message.Headers.Add("SOAPAction", "http://tempuri.org/IService1/GetData"); // url might need to be wrapped in ""
var requestContent = #$"
<s:Envelope xmlns:s=""http://schemas.xmlsoap.org/soap/envelope/"">
<s:Body>
<GetData xmlns=""http://tempuri.org/"">
<value>{value}</value>
</GetData>
</s:Body>
</s:Envelope>
";
message.Content = new StringContent(requestContent, System.Text.Encoding.UTF8, "text/xml");
var response = await client.SendAsync(message);
if (!response.IsSuccessStatusCode)
throw new Exception("Request failed.");
var responseContent = await response.Content.ReadAsStringAsync();
/*
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<GetDataResponse xmlns="http://tempuri.org/">
<GetDataResult>You entered: {value}</GetDataResult>
</GetDataResponse>
</s:Body>
</s:Envelope>
*/
// Just a really ugly regex
var regex = new Regex(#"(<GetDataResult>)(.*)(<\/GetDataResult>)");
var responseValue = regex.Match(responseContent).Groups[2].Value;
return responseValue;
}
You can ofc. use WebClient instead of HttpClient if preferred.