C# Service Client - Transfer-Encoding: Chunked - c#

I'm currently trying to fix my SOAP-Client in C#, but got somehow stuck with the Transfer-Encoding. I'm more or less a newbie to C#, so it's completly possible that im just missing something minor here.
I consumed a SOAP service from our local Tomcat Server following this: https://web.archive.org/web/20180506023052/http://www.csharptutorial.in/37/csharp-net-how-to-consume-a-web-service-in-csharp-net-visual-studio-2010
My current code:
using System;
using ConsoleApp1.Lims;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
LimsZugriffService client = new LimsZugriffService();
// FunktionsErgebnis response = client.connect();
// Console.WriteLine("Connect" + response.meldung);
String[] bond = new String[] { "versuch.auftrag.nr=2014/0031" };
String[] bondFail = new String[] { "abc" };
VersuchsschrittErgebnis reponseVersuch = client.ermittleVersuchsschritte(bond);
Console.WriteLine(reponseVersuch.ermittelteVersuchsschritte.Length);
Console.WriteLine(reponseVersuch.meldung);
}
}
}
After some testing I found out, that something does not work as intended. My Response-Array of <ermittelteVersuchsschritte> seems to be empty, while the "control"-Flags are parsed normally.
I captured the traffic between client and server to figure out what was wrong and it was actually completly there. Just chunked into 8192 Byte blocks.
Could it be, that the C# implementation of the WebClient got some problems with Transfer-Encoding: Chunked?
After googling for some hours i could not find a satisfiying solution to this issue. I hope somebody, who knows C# and WebServices better than me has the answer.
For the sake of completeness:
My WSDL
My Traffic - Request->Response

After some researching, trial and error and much time I finally figured out my mistake.
C# seems not to have a problem with the Transfer-Encoding: Chunked
The mistake was on the service side. The consumed wsdl was generated from java code with the help of Axis(the first Axis not Axis2). Axis generated a wsdl 1.0 while C# seems to expect wsdl 2.0. So in the end, the XML-structure described in the wsdl was flawed and could not be automatically consumed.
We fixed this problem by switching from Axis to Apache CXF. The newly generated wsdl was than consumed without a problem at our C# - client side.

Related

UnityWebRequest.Post to send a task to ClickUp's API, encoding JSON improperly

So I'm writing a program in Unity that sends tasks to a ClickUp list. I've been able to send the request through Postman for testing properly, but whenever I try to send that request through Unity I get an error with the Json encoding:
{"err":"Unexpected token % in JSON at position 0","ECODE":"JSON_001"}
The code for the method is as follows. It's just a very basic tester method, so I know it's a little messy as is, but once I'm able to actually send the requests properly I want I'll re-write it with the full functionality.
private void SendDemoTask()
{
string jsonString = "{\"name\": \"Unity send from postman\",\"description\": \"Sent on May 24 2022\"}";
UnityWebRequest demoTaskRequest =
UnityWebRequest.Post($"https://api.clickup.com/api/v2/list/{listID}/task",jsonString);
demoTaskRequest.SetRequestHeader("Authorization",accessToken);
demoTaskRequest.SetRequestHeader("Content-Type","application/json");
var operation = demoTaskRequest.SendWebRequest();
// Wait for request to return
while (!operation.isDone)
{
CheckWebRequestStatus("Task creation failed.", demoTaskRequest);
}
Debug.Log(demoTaskRequest.result);
Debug.Log(demoTaskRequest.downloadHandler.text);
}
It seems to be an issue with the JSON encoding. Unfortunately the POST method doesn't have an argument to take a byte array. The PUT method does, but ClickUp's API won't accept the same types of requests through Put.
Is there a way for me to send this request that will correct the encoding issue? Or is the problem somewhere else?
Apologies if any part of this isn't clear. I'm fairly new to using UnityWebRequest and a total noob to webdev in general.
Thank you for any help you all can offer, I very much appreciate it!

No WCF service response - C#

I have added a service reference, directed to a WSDL which loaded all existing WSDLs from the location. I am trying to request data by calling one of the methods like this:
protected void Page_Load(object sender, EventArgs e)
{
string fLastname, folder, status, header, responsible;
int date;
PyramidServices.ServiceSoapClient client = new PyramidServices.ServiceSoapClient();
string activity = client.GetUserActivity("xxxx", "xxxx", out fLastname, out folder, out status, out date, out header, out responsible);
}
When debugging, the vars are all null. . I have a hard time understanding trace messages since this is not my field. I don't know what to look for, so here is pretty much all the information I get when tracing (Sorry for the Swedish version!):
Sending:
Receiving:
Answer # Channel:
Stop:
[EDIT]
I tested the method using WCF Test Client and received following:
So it's kind of obvious that I am doing something wrong with the code when parsing the data from the response? My question is, how do I accomplish this?
With a lot of help from #TomW, we finally found out what the problem was. The code for the WSDL is created in a system that lets me add XML nodes surrounding the data like below:
<wrap>
<data1></data1>
<data2></data2>
<data3></data3>
</wrap>
instead of:
<data1></data1>
<data2></data2>
<data3></data3>
<data1></data1>
<data2></data2>
<data3></data3>
<data1></data1>
<data2></data2>
<data3></data3>
Therefor, the code generated by Visual Studio in Service Reference did not like the way I wrapped the data with unwanted tags. After removing the tag from my code in the system, I received exactly what I wanted with the code at the top.

accessing php soapservice from C#

well i wanted to make a simple webservice that searches the db and return the data i know i can do it with mysql connector but this is just to learn how to use soaps here is the code for php soap server
require_once ('lib/nusoap.php');
$namespace = "http://localhost/webservice/index.php?wsdl";
$server = new soap_server();
$server->configureWSDL("DBQuery");
$server->wsdl->schemaTargetNamespace = $namespace;
$server->register(
'QueryMsg',
array('name'=>'xsd:string'),
array('return'=>'xsd:string'),
$namespace,
false,
'rpc',
'encoded',
'returns data from database');
function QueryMsg($query)
{
$con=mysqli_connect('localhost','root','','webserivce');
if (mysqli_connect_errno()) {
return "Failed to connect to MySQL: " . mysqli_connect_error();
}
if(!isset($query) or strpos(strtolower($query),'select')<=-1)
{
return "invalid order";
}
else
{
mysqli_real_escape_string($con,$query);
$result = mysqli_query($con,$query);
while($row = mysqli_fetch_array($result)) {
$data[] = $row;}
return json_encode($data);
}
}
// create HTTP listener
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);
exit();
?>
it works when i try calling it from a php soap client but when i try adding this http:// localhost /webservice/index.php in visual studio as service refernce to consume it from C# application i get an error here it is
The HTML document does not contain Web service discovery information.
Metadata contains a reference that cannot be resolved: 'http://localhost/webservice/index.php'.
The content type text/xml; charset=ISO-8859-1 of the response message does not match the content type of the binding (application/soap+xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly. The first 700 bytes of the response were: '<?xml version="1.0" encoding="ISO-8859-1"?><SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body><SOAP-ENV:Fault><faultcode xsi:type="xsd:string">SOAP-ENV:Client</faultcode><faultactor xsi:type="xsd:string"></faultactor><faultstring xsi:type="xsd:string">Operation &apos;&apos; is not defined in the WSDL for this service</faultstring><detail xsi:type="xsd:string"></detail></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>'.
The remote server returned an error: (500) Internal Server Error.
If the service is defined in the current solution, try building the solution and adding the service reference again.
solved : well it was easy actually there is two ways either use WCF and change encoding to ISO-8859-1
or change encoding of the web service itself by adding this line $server->soap_defencoding = 'UTF-8'; after creating the soap server
I would try adding the service WSDL with a tool like SOAP U.I. and see what kind of errors you get back from that. It's a little more agnostic than adding a web reference with C#, and might disclose more details about why at the client level you can't consume this.
I'm happy to help you troubleshoot this with a little more information. Are you running this service on the same machine where you're running the client from? If it's complaining about being unable to correlate the file http://localhost/webservice/index.php to something I wonder if the discovery process is trying to evaluate a file that can't be found. I.E. an import operation in your source WSDL that points to a URL the client can't resolve.

IIS & Chrome: failed to load resource: net::ERR_INCOMPLETE_CHUNKED_ENCODING

I recently came across a Chrome issue which I think is worth sharing it with you.
I worked on a self written API using an HttpHandler which primary should return json data. But when an error occures I wanted to display an html file. That worked pretty well in IE and FF, but not in Chrome.
Looking to the developer tools revealed this error: net::ERR_INCOMPLETE_CHUNKED_ENCODING
Google said not very much about this issue while it was seen very much. All I got to know was, that it was magically disappearing after some time.
I found out it lays on this lines of code:
result.StoreResult(context);
context.Response.Flush();
context.Response.Close(); //<-- this causes the error
After removing the last line it worked well. I don´t know why only Chrome had/has an issue with that, but it seemed as if I closed the response stream before chrome finished reading it.
I hope it helps those of you coming across the same or a similar issue.
Now my question:
How is the best pratice in closing/flushing the response stream? Are there any rules?
According to ASP.NET sets the transfer encoding as chunked on premature flushing the Response:
ASP.NET transfers the data to the client in chunked encoding (Transfer-Encoding: chunked), if you prematurely flush the Response stream for the Http request and the Content-Length header for the Response is not explicitly set by you.
Solution: You need to explicitly set the Content-Length header for the Response to prevent ASP.NET from chunking the response on flushing.
Here's the C# code that I used for preventing ASP.NET from chunking the response by setting the required header:
protected void writeJsonData (string s) {
HttpContext context=this.Context;
HttpResponse response=context.Response;
context.Response.ContentType = "text/json";
byte[] b = response.ContentEncoding.GetBytes(s);
response.AddHeader("Content-Length", b.Length.ToString());
response.BinaryWrite(b);
try
{
this.Context.Response.Flush();
this.Context.Response.Close();
}
catch (Exception) { }
}
I was running into this error when generating a file and pushing it to the user for download, but only occasionally. When it didn't fail, the file was consistently 2 bytes short. Close() forcibly closes the connection, whether it's finished or not, and in my case it was not. Leaving it out, as suggested in the question, meant the resulting file contained both the generated content as well as the HTML for the entire page.
The solution here was replacing
context.Response.Flush();
context.Response.Close();
with
context.Response.End();
which does the same, but without cutting the transaction short.
In my case, the problem was cache-related and was happening when doing a CORS request.
Forcing the response header Cache-Control to no-cache resolved my issue:
[ using Symfony HttpFoundation component ]
<?php
$response->headers->add(array(
'Cache-Control' => 'no-cache'
));
I was also getting same error. This issue was with web server user permission on cache folder.
On the offchance that someone is landing here as a result of issues with their ASP.net Core project, I was able to resolve by adding the IIS middleware.
This is done by adding UseIISIntegration when instantiating your webhost instance.
Once I had the same problem and the main reason was lying in my controller return type.
If you try to return a C# object just as-is, you will only get net::ERR_INCOMPLETE_CHUNKED_ENCODING so don't forget to serialize your complex objects before sending them out for java script client (or View).
i.e. my controller return type was :
public async Task<List<ComplexModel>> GetComplexModelList(){
return new List<ComplexModel>()
}
Which caused INCOMPLETE_CHUNKED_ENCODING error, so I tried to fix my mistake with something like:
using Newtonsoft.Json;
...
public async Task<string> GetComplexModelList(){
return JsonConvert.SerializeObject(new List<ComplexModel>())
}

Posting using POST from C# over https

After wasting two days with this question (and trying to make it work), I've decided to take a step back and ask a more basic question, because apparently there's something I don't know or I'm doing wrong.
The requirements are simple, I need to make an HTTP post (passing a few values) over https from C#.
The website (if given the appropriate values) will return some simple html and a response code. (i'll show these later).
It's really that simple. The "webservice" works. I have a php sample that works and successfully connects to it. I also have a Dephi "demo" application (with source code) that also works. And finally I have the demo application (binary) from the company that has the "service", that also works of course.
But I need to do it through C#. That that sounds so simple, it is not working.
For testing purposes I've created a simple console app and a simple connect method. I've tried like 7 different ways to create an HTTP request, all more or less the same thing, different implementation (Using WebClient, using HttpWebRequest, etc).
Every method works, except when the URI begins with 'https'.
I get a webexception saying that the remote server returned 404. I've installed Fiddler (as suggested by a SO user), and investigated a little bit the traffic. The 404 is because I am passing something wrong, because as I mentioned later, the 'service' works. I'll talk about the fiddler results later.
The URL where I have to POST the data is: https://servicios.mensario.com/enviomasivo/apip/
And this is the POST data: (the values are fakes)
usuario=SomeUser&clave=SomePassword&nserie=01234567890123456789&version=01010000&operacion=220
The server might return a two/three lines response (sorry about the spanish, but the company is from Spain). Here's a sample of a possible response:
HTTP/1.1 200 OK
Content-Type: text/plain
01010000 100 BIEN
998
And here's another
HTTP/1.1 200 OK
Content-Type: text/plain
01010000 20 AUTENTIFICACION NEGATIVA
Ha habido un problema en la identificación ante el servidor. Corrija sus datos de autentificacion.
The 1st one means OK, and the 2nd one is Auth Failure.
As you can see the task is quite easy, only it doesn't work. If I use fiddler, I see that there's some sort of SSL stuff going on in the connection and then everything works fine. However, as far as I've read, .NET handles all that stuff for us (yes, i've added the callback to always validate invalid certs). I don't understand what I'm doing wrong. I can post/email the code, but what I'd like to know is very simple:
How can you make a POST over SSL using C# and a "simple" HttpWebRequest and later have the response in a string/array/Whatever for processing?
Trust me when I say I've been googling and Stackoverflowing for two days. I don't have any sort of proxy. The connection passes through my router. Standard ports. Nothing fancy. My Machine is inside a VMWare virtual machine and is Windows Vista, but given that the sample applications (php, delphi, binary) all work without an issue, I cannot see that as a problem).
The different samples (sans the binary) are available here if anyone wants to take a look at them.
I'd appreciate any help. If anyone wants to try with a "real" username, I have a demo user and I could pass you the user/pass for testing purposes. I only have one demo user (the one they gave me) and that's why I'm not pasting it here. I don't want to flood the user with tests ;)
I've tried (within the samples) using UTF8 and ASCII, but that didn't change anything.
I am 100% positive that there's something I have to do with SSL and I am not doing it because I don't know about it.
Thanks in advance.
Martín.
I was battling with the exact same problem a bit earlier (although in compact framework). Here's my question and my own answer to it:
Asynchronous WebRequest with POST-parameters in .NET Compact Framework
My version is asynchronous, so it's a bit more complex than what you're looking for, but the idea remains.
private string sendRequest(string url, string method, string postdata) {
WebRequest rqst = HttpWebRequest.Create(url);
// only needed, if you use HTTP AUTH
//CredentialCache creds = new CredentialCache();
//creds.Add(new Uri(url), "Basic", new NetworkCredential(this.Uname, this.Pwd));
//rqst.Credentials = creds;
rqst.Method = method;
if (!String.IsNullOrEmpty(postdata)) {
//rqst.ContentType = "application/xml";
rqst.ContentType = "application/x-www-form-urlencoded";
byte[] byteData = UTF8Encoding.UTF8.GetBytes(postdata);
rqst.ContentLength = byteData.Length;
using (Stream postStream = rqst.GetRequestStream()) {
postStream.Write(byteData, 0, byteData.Length);
postStream.Close();
}
}
((HttpWebRequest)rqst).KeepAlive = false;
StreamReader rsps = new StreamReader(rqst.GetResponse().GetResponseStream());
string strRsps = rsps.ReadToEnd();
return strRsps;
}
see my answer to your other question. I believe your problem may not be your C# code. The web service URL accually returns a 404 with several other tools I used, but it returns the response you indicated if you leave off the trailing slash from the web service URL, so I suggest trying that.
Oddly, it doesn't seem to matter if the trailing URL is there when not doing SSL. Something strange with that web server, I guess.
dont know if u already resolved this issue, it´s a post from one year ago. I am Spanish and I am using mensario too.
to send and http request: (this is in ASP but the process is the same one)
Function enviarMsg2
Dim oHTTP,inicio
Dim strParametros
Dim devolver
Set oHTTP= server.CreateObject("Msxml2.ServerXMLHTTP")
strParametros = "usuario="&usuario&"&clave="&clave&"&nserie="&nserie&"& version=01010000&operacion=300&sms=1%0934635035526%0920041231233000%09Clinica+Paz%09Clinica+Paz+le+desea+Feliz+Navidad%2E&sms=2%0934612345678%0920041231233001%09Clinica+Paz%09Clinica+Paz+le+desea+Feliz+Navidad%2E"
'response.Write strParametros
'response.End
'Abrimos la conexión con el método POST, ya que estamos enviando una petición.
oHTTP.open "POST", "https://servicios.mensario.com/enviomasivo/apip", False
'Agregamos encabezados HTTP requeridos...
oHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
'Enviamos la petición
oHTTP.send strParametros
devolver = oHTTP.responsetext
'Comprobamos si fue correcto
inicio = Instr(devolver, "100 BIEN")
'response.Write "--->"&inicio
'response.End
if inicio <=0 then
enviarSMS2 = "Ha ocurrido un error en el envío del SMS."
else
enviarSMS2 = Mid(devolver,inicio+9,len(devolver))
end if
Set oHTTP = Nothing
The only thing i dont have is a user /password for a try :)
Basicaly, when the response is "100 bien" the function returns that, otherwise it returns error.Hope it helps :)

Categories