How to solve invalid Operation Exception in xml deserialization? - c#

i wan to make deserialization my below xml But it produces error: There is an error in XML document (2, 2). Inner Exception: {" was not expected."}
How can i Deserialize my xml code? How can i solve below error?
MY C# code:
class Program
{
static void Main(string[] args)
{
GetData();
}
static void GetData()
{
string actionUrl = "http://test/vrm_search?q=56071794482024887&vrm_type=corvus";
HttpWebRequest request = WebRequest.Create(actionUrl) as HttpWebRequest;
request.Method = "GET";
request.ContentType = "application/xml";
request.Accept = "application/xml";
string responseData = string.Empty;
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
responseData = reader.ReadToEnd();
Console.Write(responseData);
reader.Close();
}
response.Close();
}
Response res = XML.Deserialize<Response>(responseData);
Console.Read();
}
}
public static class XML
{
public static T Deserialize<T>(string xml)
{
if (string.IsNullOrEmpty(xml))
{
return default(T);
}
XmlSerializer serializer = new XmlSerializer(typeof(T));
XmlReaderSettings settings = new XmlReaderSettings();
using (StringReader textReader = new StringReader(xml))
{
using (XmlReader xmlReader = XmlReader.Create(textReader, settings))
{
return (T)serializer.Deserialize(xmlReader);
}
}
}
}
ERROR:

It is looking for an "x" element, not an "x" element in the xml. (note the casing)

Related

Login into iCloud via Json Post request

I'm trying to log in into iCloud using a Json Post request in C#. Before trying to implement the code I was studying a little bit the iCloud requests using Chrome Console and using an Ad-on to replicate the requests in order to obtain the same result of the website.
First of All I checked the request directly from iCloud website:
And this is the response:
{
"serviceErrors" : [ {
"code" : "-20101",
"message" : "Il tuo ID Apple o la password non sono corretti."
} ]
}
Using "Advance REST Client" ad Chrome plugin to replicate the request I ve tried the same Json request to the same Url. But I get Empty response:
I Also tried to copy and paste the whole Header (All the settings) and than send the request but the response is the same:
Anyone has an Advice?
UPDATE: I tried to implement A Json request through c# program:
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://idmsa.apple.com/appleauth/auth/signin");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{accountName: \"briesanji #gmail.com\", password: \"testPassword\", rememberMe: false, trustTokens: []}";
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
The problem is that Execution breaks when the
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
is hit and it gives me this error: System.Net.WebException: 'Error Remote Server: (400) Request not valid.'
UPDATE: I solved in this way:
void POST(string url, string jsonContent)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
Byte[] byteArray = encoding.GetBytes(jsonContent);
request.ContentLength = byteArray.Length;
request.ContentType = #"application/json";
using (Stream dataStream = request.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
}
long length = 0;
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
length = response.ContentLength;
}
}
catch (WebException ex)
{
// Log exception and throw as for GET example above
}
}
string GET(string url)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
try
{
WebResponse response = request.GetResponse();
using (Stream responseStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
return reader.ReadToEnd();
}
}
catch (WebException ex)
{
WebResponse errorResponse = ex.Response;
using (Stream responseStream = errorResponse.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
String errorText = reader.ReadToEnd();
// log errorText
}
throw;
}
}
Anyways I tested also the Answer and it was good to.. So I check it as valid thanks.
With this i dont get any error and the response content of the second request just tells me that there were too many failed logins for the test account...
private static void ICloud()
{
var cc = new CookieContainer();
var first = (HttpWebRequest)WebRequest.Create("https://idmsa.apple.com/appleauth/auth/signin?widgetKey=83545bf919730e51dbfba24e7e8a78d2&locale=de_DE&font=sf");
first.Method = "GET";
first.CookieContainer = cc;
var response1 = (HttpWebResponse)first.GetResponse();
using (var streamReader = new StreamReader(response1.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
var second = (HttpWebRequest)WebRequest.Create("https://idmsa.apple.com/appleauth/auth/signin");
second.ContentType = "application/json";
second.Method = "POST";
second.Accept = "application/json";
second.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
second.Referrer = "https://idmsa.apple.com/appleauth/auth/signin?widgetKey=83545bf919730e51dbfba24e7e8a78d2&locale=de_DE&font=sf";
second.Headers.Add("X-Requested-With", "XMLHttpRequest");
second.Headers.Add("X-Apple-Widget-Key", "83545bf919730e51dbfba24e7e8a78d2");
using (var streamWriter = new StreamWriter(second.GetRequestStream()))
{
string json = "{\"accountName\":\"test#icloud.com\",\"password\":\"test\",\"rememberMe\":false,\"trustTokens\":[]}";
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
try
{
var response2 = (HttpWebResponse)second.GetResponse();
using (var streamReader = new StreamReader(response2.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
}
catch(WebException we)
{
using (var r = new StreamReader(we.Response.GetResponseStream()))
{
var result2 = r.ReadToEnd();
}
}
}

HttpWebRequest return error 500 when GetResponse()

I'm trying to get a response from SOAP webservice, but I'm falling into a webexception Error 500.
This my class to get a response:
public static string getResponse()
{
StringBuilder xml = new StringBuilder();
//xml.Append(#"<?xml version=""1.0"" encoding=""utf-8""?>");
xml.Append(#"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:br=""http://www.totvs.com.br/br/"" >").Replace(#"\", "");
xml.Append("<soap:Envelope/>");
xml.Append("<soapenv:Body>");
xml.Append("<br:RealizarConsultaSQLAuth>");
xml.Append("<br:codSentenca>GLOBAL_054</br:codSentenca>");
xml.Append("<br:codColigada>0</br:codColigada>");
xml.Append("<br:codAplicacao>V</br:codAplicacao>");
xml.Append("<br:Usuario>xxxx</br:Usuario>");
xml.Append("<br:Senha>xxxx</br:Senha>");
xml.Append("<br:parameters>codcoligada=1;codsistema=V;codusuario=mestre</br:parameters>");
xml.Append("</br:RealizarConsultaSQLAuth>");
xml.Append("</soapenv:Body>");
xml.Append("</soapenv:Envelope>");
string s = getUKMailData(xml.ToString(), "http://xxx.xxxx.com.br:99/xxxx/wsConsultaSQL.asmx");
return s;
}
public static string getUKMailData(string xml, string address)
{
string result = "";
HttpWebRequest request = CreateWebRequest(address);
XmlDocument soapEnvelopeXml = new XmlDocument();
string teste = xml.Replace(#"\", "");
soapEnvelopeXml.LoadXml(teste);
try
{
using (Stream stream = request.GetRequestStream())
{
soapEnvelopeXml.Save(stream);
}
using (WebResponse response = request.GetResponse())
{
using (StreamReader rd = new StreamReader(response.GetResponseStream()))
{
string soapResult = rd.ReadToEnd();
result = soapResult;
}
}
}
catch (WebException wex)
{
var pageContent = new StreamReader(wex.Response.GetResponseStream()).ReadToEnd();
}
return result;
}
public static HttpWebRequest CreateWebRequest(string url)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Headers.Add("SOAP:Action");
webRequest.Headers.Add("username", "xxx");
webRequest.Headers.Add("password", "xxx");
// webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
webRequest.PreAuthenticate = true;
webRequest.Credentials = CredentialCache.DefaultCredentials;
return webRequest;
}
anyone can help me? I already read a series of articles that unfortunately did not help me. Thanks a lot!
Your request maybe true but server-side doesn't know how to process your data. Maybe parameters which are sent fault. Please check your server-side so end-point.

Processing SOAP request with USING statement not working?

I'm trying to refactor a console app that uses SOAP to get some API data. I saw that the original code isn't using any USING statements. I thought I would try to refactor the code to do so, however, I get an "Internal Server Error". I've looked this over an few times and I'm not seeing why this wouldn't work. If I switch back to the original code it works as expected.
This is the original code that works:
public static string ProcessSOAPRequest(string xml, string endPoint)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(endPoint);
req.Timeout = 100000000;
req.Method = "POST";
Stream objStream = req.GetRequestStream();
doc.Save(objStream);
objStream.Close();
WebResponse resp = req.GetResponse();
objStream = resp.GetResponseStream();
StreamReader r = new StreamReader(objStream);
string data = r.ReadToEnd();
return data;
}
This is my attempt at refactoring with USING.
public static string ProcessSOAPRequest(string xml, string endPoint)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(endPoint);
request.Timeout = 100000000;
request.Method = "POST";
using (WebResponse response = request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
UPDATE: another attempt based on the responses. This time in the second USING statement it says that I can't use stream = response.GetResponseStream(); because "stream" is in a using statement.
var data = string.Empty;
using (Stream stream = request.GetRequestStream())
{
doc.Save(stream);
using (WebResponse response = request.GetResponse())
{
stream = response.GetResponseStream();
using (StreamReader reader = new StreamReader(stream))
{
data = reader.ReadToEnd();
}
}
}
return data;
Answer to the update:
The variable declared in a using statement is treated as readonly. I suggest you to declare a new variable and assign the response to that. Why? - Why is a variable declared in a using statement treated as readonly?
var data = string.Empty;
using (Stream stream = request.GetRequestStream())
{
doc.Save(stream);
using (WebResponse response = request.GetResponse())
{
var responseStream = response.GetResponseStream();
if (responseStream != null)
{
using (StreamReader reader = new StreamReader(responseStream))
{
data = reader.ReadToEnd();
}
}
}
}
return data;
should work.

Wrap XML in SOAP envelope in .net

I need help with wrapping an XML in a SOAP envelope for a third party SOAP server. The third party has provided xsd files for the inbound request and outbound response. I've taken those XSD files and created C# classes of them using the xsd tool. My problem is that I need to wrap the serialized request with a SOAP envelope and I don't know where to start. I was looking at the Microsoft Web Service Enhancements 3, but that says that it's only for .net 2.0 and VS2005. I am using VS2012 and .net 4.5. Also, I've looked into connecting to the server by way of web service but it doesn't seem compatible and does not have a WSDL.
The following is a sample of what the SOAP server expects for an inbound request.
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Body>
<GetBasicData xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="CRS610MI">
<CONO xmlns="">1</CONO>
<CUNO xmlns="">12345</CUNO>
</GetBasicData>
</soap:Body>
</soap:Envelope>
This is what the serialized XML string looks like.
<?xml version="1.0" encoding="utf-8"?>
<GetBasicData xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="CRS610MI">
<CONO xmlns="">1</CONO>
<CUNO xmlns="">12345</CUNO>
</GetBasicData>
Code I'm using for my web request and response.
Byte[] byteArray = System.Text.UTF8Encoding.UTF8.GetBytes(data);
WebRequest webRequest = WebRequest.Create(#"http://myserver:8888");
webRequest.ContentLength = byteArray.Length;
webRequest.ContentType = #"text/xml; charset=utf-8";
webRequest.Headers.Add("SOAPAction", #"http://schemas.xmlsoap.org/soap/envelope/");
webRequest.Method = "POST";
Stream requestStream = webRequest.GetRequestStream();
requestStream.Write(byteArray, 0, byteArray.Length);
requestStream.Close();
requestStream.Dispose();
WebResponse webResponse = webRequest.GetResponse();
Stream responseStream = webResponse.GetResponseStream();
StreamReader streamReader = new StreamReader(responseStream);
String line;
while ((line = streamReader.ReadLine()) != null)
{
Debug.WriteLine(line);
}
I've tested my code by replacing my serialized string with the text in the sample file provided by the third party and it worked as expected. I also took my serialized string and inserted the envelope text in the correct places and that also worked, web request went through and I got the response I was looking for. Short of inserting the envelope text into my serialized string manually what can I do. I have to imagine there's a method or class that will take care of this for me in a standardized way?
I was able to solve this by using an XLST to wrap the XML in soap.
Here's my working test app code
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.XPath;
using System.Xml.Xsl;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
GetBasicData getBasicData = new GetBasicData();
getBasicData.CONO = "1";
getBasicData.CUNO = "201702";
XPathDocument requestXPathDocument;
if (SerializeIntoRequestXPathDocument(getBasicData, out requestXPathDocument))
{
XmlDocument requestXmlDocument;
if (CreateRequestXMLDocument(requestXPathDocument, #"Z:\Darice\M3 SOAP\GetBasicData.xsl", out requestXmlDocument))
{
XmlDocument responseXmlDocument;
if (ExecuteRequestSoap(requestXmlDocument, out responseXmlDocument))
{
MemoryStream unwrappedMemoryStream;
if (UnwrapSoapResponseXmlDocumentIntoMemoryStream(responseXmlDocument, out unwrappedMemoryStream))
{
GetBasicDataResponse getBasicDataResponse;
if (!DeserializeResponseMemoryStream(unwrappedMemoryStream, out getBasicDataResponse))
{
Debug.WriteLine("FAIL");
}
}
}
}
}
Console.ReadLine();
}
//STATIC FUNCTIONS
private static Boolean CreateRequestXMLDocument(XPathDocument xPathDocument, String xslPath, out XmlDocument xmlDocument)
{
try
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (StreamWriter streamWriter = new StreamWriter(memoryStream))
{
XmlWriter xmlWriter = XmlWriter.Create(streamWriter);
XsltSettings xsltSettings = new XsltSettings();
xsltSettings.EnableScript = true;
XslCompiledTransform xslCompiledTransform = new XslCompiledTransform();
xslCompiledTransform.Load(xslPath, xsltSettings, null);
xslCompiledTransform.Transform(xPathDocument, xmlWriter);
memoryStream.Position = 0;
using (StreamReader streamReader = new StreamReader(memoryStream))
{
XmlReader xmlReader = XmlReader.Create(streamReader);
xmlDocument = new XmlDocument();
xmlDocument.Load(xmlReader);
}
}
}
}
catch (Exception exception)
{
Debug.WriteLine(exception);
xmlDocument = null;
return false;
}
return true;
}
private static Boolean DeserializeResponseMemoryStream<T>(MemoryStream memoryStream, out T xmlObject)
{
try
{
using (StreamReader streamReader = new StreamReader(memoryStream))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
using (XmlReader xmlReader = XmlReader.Create(streamReader))
{
xmlObject = (T)xmlSerializer.Deserialize(xmlReader);
}
}
}
catch (Exception exception)
{
Debug.WriteLine(exception);
xmlObject = default(T);
return false;
}
return true;
}
private static Boolean ExecuteRequestSoap(XmlDocument requestXmlDocument, out XmlDocument responseXmlDocument)
{
try
{
Byte[] byteArray = UTF8Encoding.UTF8.GetBytes(requestXmlDocument.OuterXml);
WebRequest webRequest = WebRequest.Create(Properties.Resources.SoapServerAddress);
webRequest.ContentLength = byteArray.Length;
webRequest.ContentType = #"text/xml; charset=utf-8";
webRequest.Headers.Add("SOAPAction", #"http://schemas.xmlsoap.org/soap/envelope/");
webRequest.Method = "POST";
using (Stream requestStream = webRequest.GetRequestStream())
{
requestStream.Write(byteArray, 0, byteArray.Length);
using (WebResponse webResponse = webRequest.GetResponse())
{
using (Stream responseStream = webResponse.GetResponseStream())
{
using (StreamReader streamReader = new StreamReader(responseStream))
{
responseXmlDocument = new XmlDocument();
responseXmlDocument.LoadXml(streamReader.ReadToEnd());
}
}
}
}
}
catch (Exception exception)
{
Debug.WriteLine(exception);
responseXmlDocument = null;
return false;
}
return true;
}
private static Boolean SerializeIntoRequestXPathDocument<T>(T dataObject, out XPathDocument xPathDocument)
{
try
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
using (MemoryStream memoryStream = new MemoryStream())
{
using (StreamWriter streamWriter = new StreamWriter(memoryStream))
{
xmlSerializer.Serialize(streamWriter, dataObject);
memoryStream.Position = 0;
using (StreamReader streamReader = new StreamReader(memoryStream))
{
memoryStream.Position = 0;
xPathDocument = new XPathDocument(streamReader);
}
}
}
}
catch (Exception exception)
{
Debug.WriteLine(exception);
xPathDocument = null;
return false;
}
return true;
}
private static Boolean UnwrapSoapResponseXmlDocumentIntoMemoryStream(XmlDocument responseXmlDocument, out MemoryStream memoryStream)
{
try
{
XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(responseXmlDocument.NameTable);
xmlNamespaceManager.AddNamespace("tns", "CRS610MI");
xmlNamespaceManager.AddNamespace("SOAP", #"http://schemas.xmlsoap.org/soap/envelope/");
XmlNode xmlNode = responseXmlDocument.SelectSingleNode(#"/SOAP:Envelope/SOAP:Body/tns:GetBasicDataResponse", xmlNamespaceManager);
memoryStream = new MemoryStream(UTF8Encoding.UTF8.GetBytes(xmlNode.OuterXml));
}
catch (Exception exception)
{
Debug.WriteLine(exception);
memoryStream = null;
return false;
}
return true;
}
}
}
And here's the XSL code
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:crs="CRS610MI" exclude-result-prefixes="crs">
<xsl:output method="xml"/>
<xsl:template match="/">
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Body>
<xsl:apply-templates select="node()|#*"/>
</soap:Body>
</soap:Envelope>
</xsl:template>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
If the service provider does not provide a WSDL, then you should not do business with them. It's not rocket science, and it is the standard way that SOAP web services work. It's only been a standard for over a decade. I would seriously wonder in what other way this service provider is incompetent.
If you have no choice but to do business with incompetent business partners, then
Good luck to you
Create your own WSDL to match their service, then use "Add Service Reference" to create the proxy classes necessary to communicate to the service.
You need to mark your class with MessageContract for soap
[MessageContract]
public class ExampleResponse
{
private string _myResponse = String.Empty;
[MessageBodyMember(Name = "ResponseToGive", Namespace = "http://myserver:8888")]
public string ResponseToGive
{
get { return _myResponse; }
set { _myResponse = value; }
}
}
I don’t understand why some are so resolute that you HAVE to use the WSDL. The WSDL is simply so that you can call their methods, and use their entities, and is optional.
I’ve gotten this to work by going to the exact url for their service, such as
https://something.com/SomeService/TheService.asmx?method=DoSomething
And just analyzing the exact header and XML their API defines, including the SOAP envelope. The first section should be the header information, and then below that is the XML. Create the XML exactly how they specify, including the envelope tags. For the Header: POST, Host, Content-Type and SOAPAction, are the most important. I’ve found that some servers don’t need Content-Length, even though its listed in their API.
Here is some sample code
public void PostXMLData(string serviceUrl, XDocument requestXML)
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(serviceUrl);
req.Method = "POST";
req.Host = "SOMETHING";
req.ContentType = "text/xml; charset=utf-8";
req.Headers.Add("SOAPAction", "SOMETHING");
req.Accept = "text/xml";
using (Stream stream = req.GetRequestStream())
{
requestXML.Save(stream);
}
using (WebResponse resp = req.GetResponse())
{
using (StreamReader rd = new StreamReader(resp.GetResponseStream()))
{
var result = rd.ReadToEnd();
if (result.Contains("error"))
{
throw new Exception($"XML Submission Failed: {result}");
}
}
}
}

Poor performance when parsing JSON - JsonTextWriter as an alternative?

I'm using the code below to parse a JSON response back from the server. It's a little slow. I'm wanting to know if I should be using the JsonTextWriter as an alternative?
How would I implement this using the JsonTextWriter?
string responseString = string.Empty;
Uri uri = new Uri ("http://localhost/complex-json.json");
HttpWebRequest request = new HttpWebRequest (uri);
request.Method = "GET";
HttpWebResponse response = request.GetResponse () as HttpWebResponse;
using (StreamReader sr = new StreamReader(response.GetResponseStream())) {
responseString = sr.ReadToEnd ();
}
response.Close ();
JObject obj = JObject.Parse (responseString);
JArray a = (JArray)obj["questions"];
IList<question> questions = a.ToObject<IList<question>>();
for (int i = 0; i < a.Count; i++) {
Console.WriteLine(questions[0].answer_count);
}
System.Web.Extensions.dll has a JavaScriptSerializer. I use the following 2 extension methods to serialize and deserialize:
public static T JsonDeserialize<T>(this string json)
{
return new JavaScriptSerializer().Deserialize<T>(json);
}
public static string ToJson<T>(this T item)
{
return new JavaScriptSerializer().Serialize(item);
}
Hope this helps.

Categories