ReadAsAsync deserializing HttpResponseMessage result - c#

This queston may possible duplicated but I am calling a service as the following below :
HttpClient httpClinet = new HttpClient();
httpClinet.DefaultRequestHeaders.Accept.Clear();
httpClinet.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));
var str = "XrayService.asmx/GetOrdData?" + string.Format("ordId={0}&code={1}", range.ordId, range.code);
HttpResponseMessage response;
httpClinet.BaseAddress = new Uri("http://172.16.203.27:6043/");
response = httpClinet.GetAsync(str).Result;
if (response.IsSuccessStatusCode)
var caseInfos = response.Content.ReadAsAsync<IEnumerable<PI>>().Result;//Here is exception
everything is going fine, but when I want to run ReadAsAsync I got the exception as below:
Error:System.AggregateException: One or more errors occurred. ---> System.AggregateException: One or more errors occurred. ---> System.Runtime.Serialization.SerializationException: Error in line 1 position 5. Expecting element 'ArrayOfPI' from namespace 'http://schemas.datacontract.org/2004/07/SATA_DTOs'.. Encountered 'Element' with name 'PI', namespace ''.
at System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.DataContractSerializer.ReadObject(XmlReader reader)
at System.Net.Http.Formatting.XmlMediaTypeFormatter.ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
at System.Net.Http.Formatting.XmlMediaTypeFormatter.ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
--- End of stack trace from previous location where exception was thrown ---
I am testing that service by Google Advanced Rest Client and see the result as :
Status : 200 OK
Response Header:
cache-control: private, max-age=0
content-length: 360
content-type: text/xml; charset=utf-8
server:Microsoft-IIS/8.5
x-aspnet-version:4.0.30319
x-powered-by: ASP.NET
date: Sun, 03 Dec 2017 08:37:21 GMT
and OutPut :
<?xml version="1.0" encoding="utf-8" ?>
<PI>
<ordId>950177248</ordId>
<fnm>بهسا</fnm>
<lnm>حسنی</lnm>
<fthNm>علی</fthNm>
<pId>p2535154</pId>
<sex>F</sex>
<brthD>2003-02-05</brthD>
<addrs />
<nId>0025351540</nId>
<srvNm>|دندان بصورت پانورک</srvNm>
<rfrPhy>مهرزاد اميري-41853</rfrPhy>
</PI>
I also decorated DTO like :
namespace SATA_DTOs
{
[DataContract(Name = "PI")]
public class PI
{
[DataMember] public string ordId { get; set; }
[DataMember] public string fnm { get; set; }
[DataMember] public string lnm { get; set; }
[DataMember] public string fthNm { get; set; }
[DataMember] public string pId { get; set; }
[DataMember] public string sex { get; set; }
[DataMember] public string brthD { get; set; }
[DataMember] public string addrs { get; set; }
[DataMember] public string nId { get; set; }
[DataMember] public string srvNm { get; set; }
[DataMember] public string rfrPhy { get; set; }
}
}
UPDATE:
Just as another try I want to get the result here either JSON or XML but this is also does not make difference:
List<PI> model = null;
var client = new HttpClient();
var task = client.GetAsync(httpClinet.BaseAddress.ToString() + str)
.ContinueWith((taskwithresponse) =>
{
var response1 = taskwithresponse.Result;
var jsonString = response1.Content.ReadAsStringAsync();
m_Logging.Log(SharedLib.LoggingMode.Prompt, "JSON string created {0}...", jsonString);
jsonString.Wait();
model = Newtonsoft.Json.JsonConvert.DeserializeObject<List<PI>>(jsonString.Result);
});
task.Wait();

After many copy pasting patch on server and improving the log I finally resolve the problem,
As the last try which #NKosi suggested with little changes:
var response1 = httpClinet.GetAsync(str).Result;
IEnumerable<PI> caseInfos1 = Enumerable.Empty<PI>();
try
{
caseInfos1 = response1.Content.ReadAsAsync<IEnumerable<PI>>().Result;
}
catch (Exception ex)
{
try
{
m_Logging.Log(SharedLib.LoggingMode.Error, "IEnumerable failed, EXP:{0}", ex);
var singleObject = response1.Content.ReadAsAsync<PI>().Result;
if (singleObject != null)
{
m_Logging.Log(SharedLib.LoggingMode.Error, "singleObject succeeded...");
caseInfos1 = new[] { singleObject };
}
}
catch (Exception exp)
{
m_Logging.Log(SharedLib.LoggingMode.Error, "singleObject failed, EXP:{0}", exp);
}
}
I crossed with the below exception also:
System.Runtime.Serialization.SerializationException: Error in line 1 position 5. Expecting element 'ArrayOfPI' from namespace 'http://schemas.datacontract.org/2004/07/SATA_DTOs'.. Encountered 'Element' with name 'PI', namespace ''....
.....
as the exception mentioned it can't be able to deserialize the result I guessed the out put type may is text/html not text/xml although Rest Client Tester specified it as text/xml,
for this reason I came to this conclusion to use ReadAsStringAsync and deserialize it to PI, so by the below snipped code I finally get the result:
PI caseInfos = null;
try
{
string strasd = response.Content.ReadAsStringAsync().Result;
m_Logging.Log(SharedLib.LoggingMode.Prompt, "ReadAsStringAsync() result:{0}", strasd);
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(PI));
using (TextReader reader = new StringReader(strasd))
caseInfos = (PI)serializer.Deserialize(reader);
m_Logging.Log(SharedLib.LoggingMode.Prompt, "Deserializing caseInfos model succeeded...");
}
catch (Exception ex)
{
m_Logging.Log(SharedLib.LoggingMode.Error, "creating model failed, EXP:{0}", ex);
}
I appreciate all crossed this question especially those who shared his/her knowledge in this discussion!!!

This is can be quite confusing. This might seem obvious the eye but still, not understandable to some.
Look at this line:
var caseInfos = response.Content.ReadAsAsync<IEnumerable<PI>>().Result
You are rendering the result as PI, which results in <pi> tag.
Thus, you get the following error:
System.Runtime.Serialization.SerializationException: Error in line 1
position 5. Expecting element 'ArrayOfPI' from namespace
'http://schemas.datacontract.org/2004/07/SATA_DTOs'.. Encountered
'Element' with name 'PI', namespace ''
The solution is this,
change your data contract and your class name:
namespace SATA_DTOs
{
[DataContract(Name = "ArrayOfPI")]
public class ArrayOfPI
{
[DataMember] public string ordId { get; set; }
[DataMember] public string fnm { get; set; }
[DataMember] public string lnm { get; set; }
[DataMember] public string fthNm { get; set; }
[DataMember] public string pId { get; set; }
[DataMember] public string sex { get; set; }
[DataMember] public string brthD { get; set; }
[DataMember] public string addrs { get; set; }
[DataMember] public string nId { get; set; }
[DataMember] public string srvNm { get; set; }
[DataMember] public string rfrPhy { get; set; }
}
}
Then assign it like this:
var caseInfos = response.Content.ReadAsAsync<IEnumerable<ArrayOfPI>>().Result
Thus, you will receive this:
<?xml version="1.0" encoding="utf-8" ?>
<ArrayOfPI>
<ordId>950177248</ordId>
<fnm>بهسا</fnm>
<lnm>حسنی</lnm>
<fthNm>علی</fthNm>
<pId>p2535154</pId>
<sex>F</sex>
<brthD>2003-02-05</brthD>
<addrs />
<nId>0025351540</nId>
<srvNm>|دندان بصورت پانورک</srvNm>
<rfrPhy>مهرزاد اميري-41853</rfrPhy>
</ArrayOfPI>
Which is what the serialization looks for and expects to find.

When using ReadAsAsync the framework tries to interpret the desired type for deserialization using the provided media type formatter.
You have IEnumerable<PI> so it assumes that the content being read is a collection ArrayOfPI based on standards.
In your example a single object is being returned while you tell it to expect a collection so it fails.
I suggest checking for collection and if that fails then check for single object given the dynamic nature of the responses that can be returned.
Simplified example
public async Task<IEnumerable<PI>> GetDataAsync() {
var httpClinet = buildClient();
var str = buildRequestUrl();
var response = await httpClinet.GetAsync(str);
IEnumerable<PI> caseInfos = Enumerable.Empty<PI>();
if (response.IsSuccessStatusCode) {
try {
caseInfos = await response.Content.ReadAsAsync<IEnumerable<PI>>();
} catch {
//Log?
}
if (caseInfos == null) {
try {
var singleObject = await response.Content.ReadAsAsync<PI>();
if (singleObject != null) {
caseInfos = new[] { singleObject };
}
} catch {
//Log?
}
}
}
return caseInfos;
}

Related

How to Convert Json Result to Object in c# mvc

I am trying to convert this response to object so that i can use access them using object in c# mvc application.
Following is the code i did:
var response = await client.GetAsync("ApiTest?Amount=" + Amount.ToString() + "&WalletAddress=" + WalletAddress.ToString() + "&TokenCode=" + TokenType.ToString());
if (response.IsSuccessStatusCode)
{
result = response.Content.ReadAsStringAsync().Result;
var test1 = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(result);
(Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(result));
result = await response.Content.ReadAsStringAsync();
var obj =Newtonsoft.Json.JsonConvert.DeserializeObject(result);
return Json(new { Message = "Your Transaction Has Been Completed Successfully!" }, JsonRequestBehavior.AllowGet);
}
Following is the Json response but its in string format:
{"Error":"Transaction amount must be greater than
0","Result":null,"IsSuccess":false,"HttpResponse":{"Headers":[{"Key":"X-Frame-Options","Value":["sameorigin"]},{"Key":"Strict-Transport-Security","Value":["max-age=31536000"]},{"Key":"Pragma","Value":["no-cache"]},{"Key":"Access-Control-Allow-Origin","Value":["*"]},{"Key":"Keep-Alive","Value":["timeout=5, max=100"]},{"Key":"Connection","Value":["Keep-Alive"]},{"Key":"Cache-Control","Value":["no-store,
must-revalidate, no-cache, post-check=0,
pre-check=0"]},{"Key":"Date","Value":["Wed, 28 Feb 2018 09:43:57
GMT"]},{"Key":"Set-Cookie","Value":["PHPSESSID=3vbjmnpea9i9n871a8knc3s89q7lufpn;
path=/; secure;
HttpOnly","visid_incap_992349=On7CIEXMQBq9AtX5/PvHQtp5lloAAAAAQUIPAAAAAACXLL2Z399YXaT6IXztsol+;
expires=Wed, 27 Feb 2019 14:49:04 GMT; path=/;
Domain=.coinpayments.net","incap_ses_478_992349=pCsbJzCRvCFLbgPwODOiBtx5lloAAAAAR8gvl6uEmcAX0kCi3b/2Ig==;
path=/;
Domain=.coinpayments.net"]},{"Key":"Server","Value":["Apache"]},{"Key":"X-Iinfo","Value":["5-23697956-23698018
NNNN CT(1461 273 0) RT(1519811034346 506) q(0 0 17 1) r(18 19)
U6"]},{"Key":"X-CDN","Value":["Incapsula"]}],"ContentBody":"{\"error\":\"Transaction
amount must be greater than
0\",\"result\":[]}","StatusCode":200,"IsSuccessStatusCode":true,"RequestUri":"https://www.coinpayments.net/api.php","RequestBody":"cmd=create_transaction\u0026amount=0\u0026currency1=USD\u0026currency2=LTCT\u0026buyer_email=3Pt5ebwZsMWV2ij1bnFv1yJYk2155PGzGx\u0026version=1\u0026key=c84f65f198e77895f3edc08e7654379785f1057c7c0c6115bee69ed68371d558"}}
any help would be highly appreciated>
Thanks
You can utilize Visual Studio's Paste Special feature:
Copy JSON and Paste Special:
You will get following classes:
public class JsonResponse
{
public string Error { get; set; }
public object Result { get; set; }
public bool IsSuccess { get; set; }
public Httpresponse HttpResponse { get; set; }
}
public class Httpresponse
{
public Header[] Headers { get; set; }
public string ContentBody { get; set; }
public int StatusCode { get; set; }
public bool IsSuccessStatusCode { get; set; }
public string RequestUri { get; set; }
public string RequestBody { get; set; }
}
public class Header
{
public string Key { get; set; }
public string[] Value { get; set; }
}
Now simply utilize Newtonsoft to deserialize:
var items = JsonConvert.DeserializeObject<JsonResponse>(json);
Output:
Try this:
using Newtonsoft.Json.Linq;
...
var jso = JObject.Parse(content);
string value = jso["propertyname"].Value<string>();

Cannot deserialize the current JSON array with metadata and records

Here is a sample of the JSON data I am getting back from a web service.
It has a single node of "odata.metadata", another single node of "value", and then the repeating records consisting of 3 fields "Code", "Name" and "XTag". This is in a string variable called Content
{"odata.metadata":"https://notthereal.domain:3148/system/OData/$metadata#pageLocationList","value":[{"Code":"LOC-A","Name":"Location A","XTag":"36;DgAAAAJ7/zEAMAAwAC0ATQBBAEkATgAAAAAA8;264943250;"},{"Code":"LOC-B","Name":"Location B","XTag":"36;DgAAAAJ7/zEAMAAxAC0ATQBBAEkATgAAAAAA8;388906690;"},{"Code":"LOC-C","Name":"Location C","XTag":"36;DgAAAAJ7/zEAMAAyAC0ATQBBAEkATgAAAAAA8;388844480;"},{"Code":"LOC-D","Name":"Location D","XTag":"36;DgAAAAJ7/zEAMAAzAC0ATQBBAEkATgAAAAAA8;388876720;"}]}
I have the following as the model, which I got by pasting the JSON data into the class.
public class ModelPageLocationList
{
public string odatametadata { get; set; }
public List<Value> value { get; set; }
}
public class Value
{
public string Code { get; set; }
public string Name { get; set; }
public string XTag { get; set; }
}
and this is the code trying to deserialise it...
DataPageLocationList =
JsonConvert.DeserializeObject<List<ModelPageLocationList>>(content);
..and this is the error message. I am stuck! Any ideas? I think the issue is around the 2 single records at the start, and then the repeating data after.
ERROR Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
Here is what I am calling
public async Task<List<ModelPageLocationList>> RefreshPageLocationListAsync ()
{
DataPageLocationList = new List<ModelPageLocationList>();
var uri = new Uri(string.Format(WebServiceSettings.WebServiceUrl, string.Empty));
try
{
var response = await client.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
Debug.WriteLine("{0}", content.ToString());
DataPageLocationList = JsonConvert.DeserializeObject<List<ModelPageLocationList>>(content);
}
} catch (Exception ex)
{
Debug.WriteLine(#"ERROR {0}", ex.Message);
}
return (DataPageLocationList);
}
Two things. Use JsonProperty to handle the odata.metadata property as the dot (.) in the property name will cause syntax problems.
public class ModelPageLocationList {
[JsonProperty("odata.metadata")]
public string odatametadata { get; set; }
[JsonProperty("value")]
public List<Value> value { get; set; }
}
Next based on the provided JSON example data you need to refactor the calling code
public async Task<ModelPageLocationList> RefreshPageLocationListAsync () {
try {
var uri = new Uri(string.Format(WebServiceSettings.WebServiceUrl, string.Empty));
var response = await client.GetAsync(uri);
if (response.IsSuccessStatusCode) {
var result = await response.Content.ReadAsAsync<ModelPageLocationList>();
return result;
}
} catch (Exception ex) {
Debug.WriteLine(#"ERROR {0}", ex.Message);
}
return null;
}
You need to serialize to your root object ModelPageLocationList, NOT a list of your root objects. Your JSON is an object not an array of objects. This will fix it:
DataPageLocationList =
JsonConvert.DeserializeObject<ModelPageLocationList>(content);
Without seeing the JSON Data you are trying to pass in, I can only provide two possible answers based on the information you have provided.
1) Make sure your JSON Looks like this:
{
"odatametadata": "SomeDataHere",
"value": [{
"code": "Code1",
"name": "Name1",
"xTag": "XTag1"
}, {
"code": "Code1",
"name": "Name1",
"xTag": "XTag1"
}, {
"code": "Code1",
"name": "Name1",
"xTag": "XTag1"
},
]
}
2 Add this attribute to your C# Class Model
public class ModelPageLocationList
{
[JsonProperty("odatametadata")]
public string odatametadata { get; set; }
[JsonProperty("value")]
public List<Value> value { get; set; }
}
public class Value
{
[JsonProperty("code")]
public string Code { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("xTag")]
public string XTag { get; set; }
}
I did the following to get my code to work with the JSON data at the start of my post. Not ideal, and I would prefer to be able to do this without having to edit the JSON string.
public async Task<List<ModelPageLocationList>> RefreshPageLocationListAsync ()
{
DataPageLocationList = new List<ModelPageLocationList>();
var uri = new Uri(string.Format(WebServiceSettings.WebServiceUrl, string.Empty));
try
{
var response = await client.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
Debug.WriteLine("BEFORE {0}", content.ToString());
content = content.Substring(content.IndexOf('['), content.IndexOf(']') - content.IndexOf('[') + 1);
Debug.WriteLine("AFTER {0}", content.ToString());
DataPageLocationList = JsonConvert.DeserializeObject<List<ModelPageLocationList>>(content);
}
}
catch (Exception ex)
{
Debug.WriteLine(#"ERROR {0}", ex.Message);
}
return (DataPageLocationList);
}
and the class from the JSON data
public class ModelPageLocationList
{
public string Code { get; set; }
public string Name { get; set; }
public string ETag { get; set; }
}
Thanks everyone for their replies.

Additional information: Unable to cast object of type 'System.IO.MemoryStream' to type 'JsonData'

i have defined this class for decoding json response
private class JsonData
{
[JsonProperty(PropertyName = "api-author")]
public string apiauthor { get; set; }
[JsonProperty(PropertyName = "api-usage")]
public string apiusage { get; set; }
[JsonProperty(PropertyName = "status")]
public string status { get; set; }
[JsonProperty(PropertyName = "language")]
public string language { get; set; }
[JsonProperty(PropertyName = "sentiment-text")]
public string sentimenttext { get; set; }
[JsonProperty(PropertyName = "sentiment-score")]
public string sentimentscore { get; set; }
}
and i am trying to call an api
string url = "https://loudelement-free-natural-language-processing-service.p.mashape.com/nlp-text/?text=";
var response = Unirest.get(url)
.header("X-Mashape-Key", "AlZVYH30C9mshLPNM7KiE48aFfTHp1h3A31jsnmVPccxBzW5uB")
.header("Accept", "application/json")
.asJson<JsonData>()
.Body
;
var status = response.sentimenttext;
where i am getting this exception
An exception of type System.InvalidCastException' occurred in
unirest-net.dll but was not handled in user code
Additional information:
Unable to cast object of type 'System.IO.MemoryStream' to type
'JsonData'.
How about writing your own methods instead of using that library
public async Task<T> Get<T>(string url)
{
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.TryAddWithoutValidation("X-Mashape-Key", "AlZVYH30C9mshLPNM7KiE48aFfTHp1h3A31jsnmVPccxBzW5uB");
client.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "application/json");
var json = await client.GetStringAsync(url);
return JsonConvert.DeserializeObject<T>(json);
}
}
Now you can call it as
string url = "https://loudelement-free-natural-language-processing-service.p.mashape.com/nlp-text/?text=apple";
var jsonData = await Get<JsonData>(url);
Output:

C# Deserializing HttpResponseMessage to Object

I'm having some problem deserializeing a HttpResponseMessage into an object.
The problem is that when the object should have deserialized all fields are null, no exceptions are thrown.
HttpContent content = new StringContent(xml);
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("text/xml");
HttpResponseMessage response = await client.PostAsync("URL", content).ConfigureAwait(false);
// Parse response
if (response.IsSuccessStatusCode)
{
XmlSerializer serializer = new XmlSerializer(typeof(ResponseObject));
Stream responseStream = await response.Content.ReadAsStreamAsync();
ResponseObject responseObject = serializer.Deserialize(responseStream) as ResponseObject;
//Possible example of wrong data
Console.WriteLine(responseObject.Message);
}
[XmlRoot("response")]
public class ResponseObject
{
[XmlElement("session")]
public string Session { get; set; }
[XmlElement("status")]
public string Status { get; set; }
[XmlElement("message")]
public string Message { get; set; }
}
Response message as a string
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>
<response>
<val n=\"session\">SESSION ID</val>
<val n=\"status\">201</val>
<val n=\"message\">Created</val>
</response>"
Have I missed something? I'm pretty new to serializing/deserializing.
Grateful for pointers.
Okay I solved it with the help of Eser and Biscuits in the comments.
I was trying to reuse code and did't really think about the response message having a different structure then the earlier project.
I changed my ResponseObject to this:
[XmlRoot("response")]
public abstract class ResponseObject
{
[XmlIgnore]
public bool Success { get; set; }
[XmlIgnore]
public string Session
{
get
{
var result = Values.FirstOrDefault(n => n.Name == "session");
return result.Value;
}
}
[XmlIgnore]
public string Status
{
get
{
var result = Values.FirstOrDefault(n => n.Name == "status");
return result.Value;
}
}
[XmlIgnore]
public string Message
{
get
{
var result = Values.FirstOrDefault(n => n.Name == "message");
return result.Value;
}
}
[XmlElement("val")]
public List<ResponseXmlWrapper<string>> Values;
}
public class ResponseXmlWrapper<T>
{
[XmlAttribute("n")]
[JsonProperty("n")]
public string Name { get; set; }
[XmlText]
[JsonProperty()]
public T Value { get; set; }
public ResponseXmlWrapper()
{
}
public ResponseXmlWrapper(string attributeName, T value)
{
Name = attributeName;
Value = value;
}
}
I don't know if this is an optimal solution but it works.

Send xml with a post request to wcf service on iis

SOLVED with this link
I'm developing a wcf service, with rest pattern. Now it is on a IIS server.
It has got a method callable with a post, which has to receive a xml data.
I'm trying to send this xml (with other parameter), but I'm getting only deserial errors:
in System.ServiceModel.Dispatcher.OperationFormatter.DeserializeRequest(Message message, Object[] parameters)
in System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(Message message, Object[] parameters)
in System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message message, Object[] parameters)
in System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc)
in System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
in System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
in System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
in System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
This is the request:
retista=0019&hashedStrig=dkfjdkfjd&dati=<ArrayOfWrapClienti xmlns="http://schemas.datacontract.org/2004/07/MultipayOnline" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><WrapClienti><CODRETE>0018</CODRETE><CODICE>20685</CODICE><NOME>A.T.E.R. Azienda Territoriale</NOME><INDIRIZZO>PIAZZA POZZA</INDIRIZZO><CITTA>Verona</CITTA><CAP>37123</CAP><PROV>VR</PROV><CODICEFISCALE>00223640236</CODICEFISCALE><PIVA>223640236</PIVA><EMAIL/><ESPOSIZ_CONTABILE>937,02</ESPOSIZ_CONTABILE><STATO>FALSE</STATO></WrapClienti></ArrayOfWrapClienti>
and this is the xml I'm trying to send:
<ArrayOfWrapClienti xmlns="http://schemas.datacontract.org/2004/07/aaa" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<WrapClienti>
<CODRETE>1111</CODRETE>
<CODICE>111</CODICE>
<NOME>AAA</NOME>
<INDIRIZZO>PIAZZA</INDIRIZZO>
<CITTA>AAA</CITTA>
<CAP>111</CAP>
<PROV>aa</PROV>
<CODICEFISCALE>111</CODICEFISCALE>
<PIVA>223611140236</PIVA>
<EMAIL/>
<ESPOSIZ_CONTABILE>1111</ESPOSIZ_CONTABILE>
<STATO>FALSE</STATO>
</WrapClienti>
</ArrayOfWrapClienti>
If you click here, you can find out how an xml is returned by my wcf. I thought I have to send the same xml with other data, but I get the deserial error.
Why?
How can I send the xml to my wcf? In this test phase, I'm using this.
If I can give to you other useful infos, ask me and I'll write them here.
UPDATE: The text of the error message says that there are invalid data at root level, row 1, pos 1. Also if I put
<?xml version="1.0" encoding="utf-8" ?>
at the root level.
Maybe are there some missing headers?
UPDATE server side:
this is how my server wcf is configured:
[OperationContract]
[WebGet(UriTemplate = "cliente.xml?retista={codret}&cliente={codiceCliente}&H={hashedString}", ResponseFormat = WebMessageFormat.Xml)]
List<WrapClienti> GetClienteXML(string codret, string codiceCliente, string hashedString);
and this is the called method:
public GenericResponse SetClientiXML(List<WrapClienti> clienti, string retista, string hashedString)
{
var api = new API();
return api.SetClienti(clienti, retista, hashedString);
}
as you can I see, I don't manage any xml/json deserialzing phase, it is managed by the wcf routine. For example, if I send a json list, it converts it to a List. This is what also with xml I want to see, but I'm getting the error at the top of this question.
ANOTHER UPDATE: I have to send 3 parameters in xml, so.... this is my last attempt, I think it is more correct than previouses. Now the server gives null reference error:
<?xml version="1.0" encoding="utf-8" ?>
<SetClientiXML
xmlns="http://tempuri.org/">
<XMLRequest>
<ArrayOfWrapClienti
xmlns="http://schemas.datacontract.org/2004/07/aaa"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<WrapClienti>
<CODRETE>111</CODRETE>
<CODICE>111</CODICE>
<NOME>aaa</NOME>
<INDIRIZZO>aaa</INDIRIZZO>
<CITTA>aaa</CITTA>
<CAP>aaa</CAP>
<PROV>aa</PROV>
<CODICEFISCALE>111</CODICEFISCALE>
<PIVA>2236401111236</PIVA>
<EMAIL/>
<ESPOSIZ_CONTABILE>111</ESPOSIZ_CONTABILE>
<STATO>FALSE</STATO>
</WrapClienti>
</ArrayOfWrapClienti>
<RETISTA>1111</RETISTA>
<HASHEDSTRING>oklkokokokok</HASHEDSTRING>
</XMLRequest>
</SetClientiXML>
I have also created this class:
[DataContract]
public class XMLRequest
{
[DataMember]
public List<WrapClienti> XML;
[DataMember]
public string RETISTA;
[DataMember]
public string HASHEDSTRING;
public XMLRequest() { }
public XMLRequest(List<WrapClienti> x, string r, string h)
{
this.HASHEDSTRING = h;
this.XML = x;
this.RETISTA = r;
}
}
and the portotype now is:
public GenericResponse SetClientiXML(XMLRequest xr)
Does this work?
string input =
"<ArrayOfWrapClienti xmlns=\"http://schemas.datacontract.org/2004/07/MultipayOnline\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">" +
"<WrapClienti>" +
"<CODRETE>0018</CODRETE>" +
"<CODICE>20685</CODICE>" +
"<NOME>A.T.E.R. Azienda Territoriale</NOME>" +
"<INDIRIZZO>PIAZZA POZZA</INDIRIZZO>" +
"<CITTA>Verona</CITTA>" +
"<CAP>37123</CAP>" +
"<PROV>VR</PROV>" +
"<CODICEFISCALE>00223640236</CODICEFISCALE>" +
"<PIVA>223640236</PIVA>" +
"<EMAIL/>" +
"<ESPOSIZ_CONTABILE>937,02</ESPOSIZ_CONTABILE>" +
"<STATO>FALSE</STATO>" +
"</WrapClienti>" +
"</ArrayOfWrapClienti>";
input = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + input;​
Here is code to serialize and de-serialize your xml
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication2
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
SetClientiXML client = new SetClientiXML()
{
xmlRequest = new XMLRequest()
{
arrayOfWrapClienti = new ArrayOfWrapClienti()
{
wrapClient = new List<WrapClient>() {
new WrapClient {
codrete = "0018",
codice = "20685",
nome = "A.T.E.R. Azienda Territoriale",
indirizzo = "PIAZZA POZZA",
citta = "Verona",
cap = "37123",
prov = "VR",
codiceFiscale = "00223640236",
piva = "223640236",
esposizContabile = "937,02",
stato = false
}
}
}
},
retista = "3303903",
hashedString = "oklkokokokok"
};
XmlSerializer serializer = new XmlSerializer(typeof(SetClientiXML));
StreamWriter writer = new StreamWriter(FILENAME);
serializer.Serialize(writer, client);
writer.Flush();
writer.Close();
writer.Dispose();
XmlSerializer xs = new XmlSerializer(typeof(SetClientiXML));
XmlTextReader reader = new XmlTextReader(FILENAME);
SetClientiXML newClient = (SetClientiXML)xs.Deserialize(reader);
}
}
[XmlRoot("SetClientiXML")]
public class SetClientiXML
{
[XmlElement("XMLRequest")]
public XMLRequest xmlRequest { get; set; }
[XmlElement("RETISTA")]
public string retista { get; set; }
[XmlElement("HASHEDSTRING")]
public string hashedString { get; set; }
}
[XmlRoot("XMLRequest")]
public class XMLRequest
{
[XmlElement("ArrayOfWrapClienti")]
public ArrayOfWrapClienti arrayOfWrapClienti { get; set; }
}
[XmlRoot("ArrayOfWrapClienti")]
public class ArrayOfWrapClienti
{
[XmlElement("WrapClient")]
public List<WrapClient> wrapClient { get; set; }
}
[XmlRoot("WrapClient")]
public class WrapClient
{
[XmlElement("CODRETE")]
public string codrete { get; set; }
[XmlElement("CODICE")]
public string codice { get; set; }
[XmlElement("NOME")]
public string nome { get; set; }
[XmlElement("INDIRIZZO")]
public string indirizzo { get; set; }
[XmlElement("CITTA")]
public string citta { get; set; }
[XmlElement("CAP")]
public string cap { get; set; }
[XmlElement("PROV")]
public string prov { get; set; }
[XmlElement("CODICEFISCALE")]
public string codiceFiscale { get; set; }
[XmlElement("PIVA")]
public string piva { get; set; }
[XmlElement("EMAIL")]
public string email { get; set; }
[XmlElement("ESPOSIZ_CONTABILE")]
public string esposizContabile { get; set; }
[XmlElement("STATO")]
public Boolean stato { get; set; }
}
}
​

Categories

Resources