WCF stream response returning garbage characters - wcf

Hello guys,
i have a web service returning XML response as a stream, it's a string that later i convert into memory stream before returning it as a response. The problem is, string has some chinese characters which work fine if my return type of service is plain string, but they show garbage characters if i convert them into stream and then choose stream as my return type.
Stream strmResponse = new MemoryStream(Encoding.UTF8.GetBytes(xmlstringResponse));
above code is converting all the chinese characters into garbage characters and this is the response i get. changing encoding into ASCII will simply replace chinese characters with "??"
<data contentType="application/octet-stream" contentLength="1808"><![CDATA[<MESSAGE_BODY><RESPONSE><RESULT>�功</RESULT></RESPONSE></MESSAGE_BODY>]]></data>
however the correct chinese is "成功" which means Success. Below is the signature of my method
[WebInvoke(Method = "POST", UriTemplate = "SendDCFileResponse", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml)]
[OperationContract]
Stream SendDCFileResponse(Stream xmlParam);
changing return type to "string" will make things working but using stream is the requirement for me. I have checked my binding and it's basicHttpBinding which means it supports UTF8 by default, still i have explictly specified UTF-8 as content type but there is no luck. Please help me out.

I tried webhttpbinding and basichttpbinding but did not encounter the problem you said:
webhttpbinding
[WebInvoke(Method = "POST", UriTemplate = "SendDCFileResponse", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml)]
[OperationContract]
Stream SendDCFileResponse(Stream xmlParam);
public Stream SendDCFileResponse(Stream xmlParam)
{
string xmlstringResponse = " < data contentType = \"application/octet-stream\" contentLength = \"1808\" >< ![CDATA[< MESSAGE_BODY >< RESPONSE >< RESULT >成功</ RESULT ></ RESPONSE ></ MESSAGE_BODY >]] ></ data >";
Stream strmResponse = new MemoryStream(Encoding.UTF8.GetBytes(xmlstringResponse));
return strmResponse;
}
basichttpbinding
[OperationContract]
Stream SendDCFileResponse(Stream xmlParam);
public Stream SendDCFileResponse(Stream xmlParam)
{
string xmlstringResponse =" < data contentType = \"application/octet-stream\" contentLength = \"1808\" >< ![CDATA[< MESSAGE_BODY >< RESPONSE >< RESULT >成功</ RESULT ></ RESPONSE ></ MESSAGE_BODY >]] ></ data >";
Stream strmResponse = new MemoryStream(Encoding.UTF8.GetBytes(xmlstringResponse));
return strmResponse;
}
Feel free to let me know if the problem persists.

Related

Rest API return response XML format, but same xml not get in result by using httpclient

I have created web api which return xml format response. like below
<TXLife xmlns="http://ACORD.org/Standards/Life/2">
<TXLifeResponse>
<TransRefGUID>61ec7f39-5744-410e-b601-dcd89d8d6f27</TransRefGUID>
<TransType tc="510">Form Instance Update</TransType>
<TransSubType tc="1022500310">Annuity Application for Mani ManiM</TransSubType>
<TransExeDate>2016-08-25-04:00</TransExeDate>
<TransExeTime>16:36:41.157-04:00</TransExeTime>
<TransMode tc="2">Original</TransMode>
<NoResponseOK tc="0"/>
<TransResult>
<ResultCode tc="3">Received Pending</ResultCode>
</TransResult>
But when call API using httpclient, I received response but response data is not same as above instead i got decode of special character.
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/"><?
xml version="1.0" encoding="utf-8"?>
<TXLife xmlns:acord="http://ACORD.org/Standards/Life/2">
<TXLifeResponse>
<TransRefGUID>dd8973e3-ac03-4690-908b-
65da3d6a770f</TransRefGUID>
<TransType tc="510">Form Instance Update</TransType>
<TransSubType tc="1022500310">
Annuity Application for SUZANNE M PERSON</TransSubType>
<TransExeDate>2020-08-17</TransExeDate>
<TransExeTime>15:28:24Z</TransExeTime>
<TransMode tc="2">Original</TransMode>
<NoResponseOK tc="0" />
<TransResult>
<ResultCode tc="3">Received Pendinge</ResultCode>
</TransResult>
</TXLifeResponse>
</TXLife></string>
I am using below code to call API
string response = string.Empty;
using (var client = new HttpClient())
{
client.BaseAddress = parameters.DestinationUri;
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
var responseTask = client.PostAsXmlAsync(parameters.DestinationUri, request);
responseTask.Wait();
var result = responseTask.Result;
if (result.IsSuccessStatusCode)
{
response = result.Content.ReadAsStringAsync().Result;
}
Resolved. I fixed by just in API response. I return HttpResponseMessage instead of return string object. Changes in API like below
string response = "response string info";
return new HttpResponseMessage()
{
Content = new StringContent(response, Encoding.UTF8, "application/xml")
};

VBA sending foreign characters to .net core 2 web api returns http code 400

net core 2 Web API that receives data from a VBA application. This works well until the data being sent is with foreign characters. what i get from vba is that it sends this
UpdateTagForDocument?documentName=PDK415.doc&tagType=custom&newValue=DK-tag; Title-here 1; Mintetestćć;
(note that the actual domain has been removed for security purposes)
However i can see from Wireshark that the polish character 'ć' has been replaced with the this: \304\207 as shown here:
UpdateTagForDocument?documentName=PDK415.doc&tagType=custom&newValue=DK-tag;%20Title-here%201;%20test\304\207;
The following vba code sends the request:
Public Function request(requestName As String, thisRequestType As requestType, Optional postParameters As String = "", Optional format As ResponseFormat = ResponseFormat.Json) As String
Dim xml
Dim requestType As String
requestType = GetRequestType(thisRequestType)
asd = url & requestName
Debug.Print asd
Set xml = CreateObject("WinHttp.WinHttpRequest.5.1")
xml.Open requestType, url & requestName, False
'xml.setRequestHeader "Content-Type", "application/json; charset=iso-8859-1"
xml.setRequestHeader "Accept", "application/json"
xml.setRequestHeader "Cache-Control", "max-age=0"
If postParameters <> "" Then
xml.send (postParameters)
Else
xml.send
End If
pResponseText = xml.ResponseText
pStatusCode = xml.Status
pStatusText = xml.StatusText
If pStatusCode = "200" Then
request = True
Else
request = False
End If
End Function
Web API Action code:
[Route("UpdateTagForDocument")]
[HttpPost]
public IActionResult UpdateTagForDocument (string documentName, string tagType, string newValue)
{
TagType convertedTagType;
if (!Enum.TryParse<TagType>(tagType, true, out convertedTagType))
{
return StatusCode(500, "Error converting to enum");
}
if(service.UpdateTag(documentName, convertedTagType, newValue))
return Ok();
return StatusCode(500);
}
The Web API should just return a http code 200 and that's that.
However what i get is that it can't reach the server. Somehow MVC can't find the right Action in the controller and so just returns a http code 400 bad request.
However when i send the same request through Postman, with or withour the \304\207 code, there is no problem.
Please let me know if you need further clarification.

GDAX Post Call returns invalid signature

I am trying to make a post request on GDAX.
But I always receive a "invalid signature" message.
GDAX API Docs for creating request + signing: https://docs.gdax.com/#creating-a-request
Preshash string returns the following:
1500627733POST/orders{"price":"1000.0","size":"0.02","type":"limit","side":"sell","product_id":"BTC-EUR"}
My signature method:
public String generateSignature(String requestPath, String method, String body, String timestamp) {
try {
String prehash = timestamp + method.toUpperCase() + requestPath + body;
byte[] secretDecoded = Base64.getDecoder().decode(secretKey);
SecretKeySpec keyspec = new SecretKeySpec(secretDecoded, "HmacSHA256");
Mac sha256 = (Mac) Mac.getInstance("HmacSHA256").clone();
sha256.init(keyspec);
return Base64.getEncoder().encodeToString(sha256.doFinal(prehash.getBytes()));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
My request method:
private boolean placeLimitOrder(String currencyPair, String side, String price, String size)
throws UnirestException {
String timestamp = Instant.now().getEpochSecond() + "";
String api_method = "/orders";
String path = base_url + api_method; //base_url = https://api.gdax.com
String method = "POST";
String b = "{\"price\":\"1000.0\",\"size\":\"0.02\",\"type\":\"limit\",\"side\":\"sell\",\"product_id\":\"BTC-EUR\"}";
JsonNode n = new JsonNode(b);
String sig = generateSignature(api_method, method,b, timestamp);
HttpResponse<JsonNode> rep = Unirest.post(path).header("accept", "application/json")
.header("content-type", "application/json")
.header("CB-ACCESS-KEY", publicKey)
.header("CB-ACCESS-PASSPHRASE", passphrase)
.header("CB-ACCESS-SIGN", sig)
.header("CB-ACCESS-TIMESTAMP", timestamp)
.body(n)
.asJson();
System.out.println(rep.getStatusText()); //Bad Request
System.out.println(rep.getBody().toString()); //invalid signature
System.out.println(sig); //returns something
return false;
}
I also tried to make a API Request Call with Insomnia but it returns the same message ("invalid signature").
Any clues?
Thank you very much in advance!
Looks like you are signing the price order data which is a string, but for the body in the post you are turning it into a json node. Which may not match when gdax decodes the signing and compares the payload data to the decrypted(signed body) when they receive it.
Why not just send the string as the body and remove the ".asJson"?
.body(b)
I was stuck on a similar issue when I was testing the API in C#. After 3 afternoons of trying. I tested sending the data as a string and I was able to get pass the invalid signature error.
I had the same problem.
I used http:
but the right one httpS:
Problem solved.

SMS integration web api consume by XML via HTTP RAW POST in c#.net

I need to integrate send sms api using like this URL. but I am getting the message XML is incorrect format.
http://<url>/action?application=msg&action=sendmsg&responsetype=xml
I am sending XML code like this
<data>
<phone> 1234567890 </phone>
<api_key 1234567890 </api_key>
<message_body> This is message text </message_body>
</data>
My code is
HttpWebRequest httpWReq =
(HttpWebRequest)WebRequest.Create(#"http:\\domain.com\page.asp");
ASCIIEncoding encoding = new ASCIIEncoding();
string postData = "username=user";
postData += "&password=pass";
byte[] data = encoding.GetBytes(postData);
httpWReq.Method = "POST";
httpWReq.ContentType = "application/x-www-form-urlencoded";
httpWReq.ContentLength = data.Length;
using (Stream stream = httpWReq.GetRequestStream())
{
stream.Write(data,0,data.Length);
}
HttpWebResponse response = (HttpWebResponse)HttpWReq.GetResponse();
string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
Please suggest how to resolve.strong text
Looks like just a typo.
Add > to end of the front api_key and the balance XML needs will work.

XmlReader chopping off whitespace after ampersand entity?

This is strange. I've got a WCF Message and I'm trying to read the contents of the body into an XmlDocument. The contents of the message body look like this on the wire (when inspected with WCF tracing turned on):
<abc>
<timeZone>(GMT-05:00) Eastern Time (US & Canada)</timeZone>
</abc>
The code for the reader looks like this:
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreWhitespace = false;
settings.CheckCharacters = false;
XmlReader bodyReader = XmlReader.Create(
message.GetReaderAtBodyContents().ReadSubtree(), settings);
XmlDocument messageDoc = new XmlDocument();
messageDoc.Load(bodyReader);
The resulting XML in messageDoc looks like this:
<abc>
<timeZone>(GMT-05:00) Eastern Time (US &Canada)</timeZone>
</abc>
So where did the extra whitespace after the original & go?
You can simplify the code by removing the XmlReader. Then set the PreserveWhiteSpace on the XmlDocument. You can replace all of your code with:
XmlDocument messageDoc = new XmlDocument() { PreserveWhitespace = true };
messageDoc.Load(message.GetReaderAtBodyContents().ReadSubtree());