After I send a request with the required parameters in the response I get the following XML:
<content>
<main>
<IMGURL>image url</IMGURL>
<IMGTEXT>Click Here</IMGTEXT>
<TITLE>image title</TITLE>
<IMGLINK>image link</IMGLINK>
</main>
</content>
and I also made the following two classes:
[Serializable]
public class content
{
private Main _main;
public content()
{
_main = new Main();
}
public Main Main
{
get { return _main; }
set { _main = value; }
}
}
[Serializable]
public class Main
{
public string IMGURL { get; set; }
public string IMGTEXT { get; set; }
public string TITLE { get; set; }
public string IMGLINK { get; set; }
}
While debugging I can see that in the response I get the wanted results. However I'm having troubles deserializing the XML and populating the object.
Call to the method:
public static class ImageDetails
{
private static string _url = ConfigurationManager.AppSettings["GetImageUrl"];
public static content GetImageDetails(string ua)
{
var contenta = new content();
_url += "&ua=" + ua;
try
{
WebRequest req = WebRequest.Create(_url);
var resp = req.GetResponse();
var stream = resp.GetResponseStream();
//var streamreader = new StreamReader(stream);
//var content = streamreader.ReadToEnd();
var xs = new XmlSerializer(typeof(content));
if (stream != null)
{
contenta = (content)xs.Deserialize(stream);
return contenta;
}
}
catch (Exception ex)
{
}
return new content();
}
}
The serializer is case-sensitive. You either need to rename the property content.Main to main or add the attribute [XmlElement("main")] to it.
Related
I have a json in an Api with an error tag. Now I want to show the error content in c# when an error occurs. Does anyone have a code or an example for this?
--Edited--
string html = string.Empty;
string url = #"http://henn.worteus.eu/?tag=getdatas&token=21123&id=" + sessions;
WebRequest req = WebRequest.Create(url);
req.ContentType = "application/json";
WebResponse resp = req.GetResponse();
Stream stream = resp.GetResponseStream();
StreamReader re = new StreamReader(stream);
string json = re.ReadToEnd();
// Wrapper w = (Wrapper)new JavaScriptSerializer().Deserialize(json, typeof(Wrapper));
Wrapper w = (Wrapper)JsonConvert.DeserializeObject(json, typeof(Wrapper));
dataGrid.ItemsSource = w.data;
Here are the data models
public class Data
{
public string Skala { get; set; }
public string Wert { get; set; }
public string Bereich { get; set; }
public string Interpretationen { get; set; }
}
public class Wrapper
{
public List<Data> data { get; set; }
public string tag { get; set; }
public object error { get; set; }
}
If there is an error property on the returned model
{
"error":"...",
"data":[...]
}
then desrialize the json to a strong type and then access the property
Wrapper w = JsonConvert.DeserializeObject<Wrapper>(json);
var data = w.data;
var error = w.error;
if(error != null) {
//...perform some action
}
What I want to do is extremely simple in php. I just want to read the contents of the post. It also extremely simple on sailsjs / node ... I just return the result from within the async function.
In c# asp the answer is eluding me. I want the function to read the contents of the post before it attempts to process the post.
Sometimes the following code works. Sometimes the reading of the json from the post happens too slowly and jsonText is read as "" so nothing is processed.
In all of the test runs the json is being sent in the body of the post.
What is the best way to return a httpResponse after making sure the contents of the post is read first?
public HttpResponseMessage Post()
{
string content;
try
{
string result = String.Empty;
Newtonsoft.Json.Linq.JObject jObject = null;
string jsonText = String.Empty;
var syncTask = new Task<string>( () => {
return Request.Content.ReadAsStringAsync().Result;
});
/* I'm expecting that this will finish */
syncTask.RunSynchronously();
jsonText = syncTask.Result;
/* before this line of code executes */
System.Net.Http.HttpResponseMessage response = new HttpResponseMessage();
if (jsonText == "")
{
result = "{\"error\":\"body is empty\"}";
response.StatusCode = System.Net.HttpStatusCode.InternalServerError;
}
else
{
jObject = (Newtonsoft.Json.Linq.JObject)Newtonsoft.Json.Linq.JRaw.Parse(jsonText);
string ipAddress = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
jObject["ipAddress"] = ipAddress;
Models.JsonXML jsonXml = new JsonXML(jObject.ToString(Newtonsoft.Json.Formatting.None));
System.Xml.XmlDocument document = new System.Xml.XmlDocument();
document.LoadXml(jsonXml.xml);
result = ReferralsManager.ProcessReferral(document);
if (result == "")
{
result = "{}";
}
response.StatusCode = System.Net.HttpStatusCode.OK;
}
response.Content = new StringContent(result);
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
return response;
}
catch (Exception ex)
{
content = ErrorMessage.ServerException(Converter, ex);
return Request.ToResponseMessage(content);
}
finally
{
LogManager.GetCurrentClassLogger().Info(InfoMessage.FUNC_ENDS, "Process Referral");
}
}
The working modified code after the answer from #Mekap is
public class ProcessReferralAddressModel {
public ProcessReferralAddressModel() { }
public string address { get; set; }
public string name { get; set; }
}
public class ProcessReferralModel
{
public ProcessReferralModel()
{
}
public string uuid { get; set; }
public DateTime date { get; set; }
public ProcessReferralAddressModel from { get; set; }
public ProcessReferralAddressModel[] to { get; set; }
public string subject { get; set; }
public string text { get; set; }
public string html { get; set; }
}
/// <summary>
/// Process a referral.
/// </summary>
/// <param name="userid">The userid.</param>
/// <returns></returns>
public HttpResponseMessage Post([FromBody] ProcessReferralModel processReferralModel)
{
string content;
string jsonText = Newtonsoft.Json.JsonConvert.SerializeObject(processReferralModel) ;
try
{
string result = String.Empty;
Newtonsoft.Json.Linq.JObject jObject = null;
System.Net.Http.HttpResponseMessage response = new HttpResponseMessage();
if (jsonText == "" || jsonText == null )
{
result = "{\"error\":\"body is empty\"}";
response.StatusCode = System.Net.HttpStatusCode.InternalServerError;
}
else
{
jObject = (Newtonsoft.Json.Linq.JObject)Newtonsoft.Json.Linq.JRaw.Parse(jsonText);
string ipAddress = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
jObject["ipAddress"] = ipAddress;
Models.JsonXML jsonXml = new JsonXML(jObject.ToString(Newtonsoft.Json.Formatting.None));
System.Xml.XmlDocument document = new System.Xml.XmlDocument();
document.LoadXml(jsonXml.xml);
result = ReferralsManager.ProcessReferral(document);
if (result == "")
{
result = "{}";
}
response.StatusCode = System.Net.HttpStatusCode.OK;
}
response.Content = new StringContent(result);
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
return response;
}
catch (Exception ex)
{
content = ErrorMessage.ServerException(Converter, ex);
return Request.ToResponseMessage(content);
}
finally
{
LogManager.GetCurrentClassLogger().Info(InfoMessage.FUNC_ENDS, "Process Referral");
}
}
The json you're fetching, for our example will look something like
{ "ID" : 3,
"StringCmd" : "ls -l"
}
For starters, we are going to write a small class who's representing our data in your web api
public class StringCmdModel
{
public StringCmdModel()
{
}
public int ID { get; set; }
public string StringCmd { get; set; }
}
Now, we just have to write our Entry point in our WebAPI :
[HttpPost]
public HttpResponseMessage PostFonction([FromBody] StringCmdModel NewEntry)
You don't have to check for the existence of the data inside the function. But you should still do proper checks on theirs values, in case you get bad formated json or malicious calls.
But, if you get a call with json that is not matching the StringCmdModel you gave in parameter from the body, this function will not be executed, and the server will throw on its own a 500 error.
I am trying to parse some xml files (using LINQ) to use that data to store in DB. Following is the format for one of the service, and there are dozens of them more, each with different node patterns and structure.
Is there a way to generalize this approach, so that I can iterate all these services through a single method/lines of code? without being bothered by how the childNodes are arranged ?
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<deviceState>
<id>203948-2908093-203984902-29348020-290lk</id>
<device>Mirron</device>
<variable>
<id>Plug - Meter.VI</id>
<text>
<textValue>
<value>0.000000</value>
</textValue>
</text>
</variable>
<variable>
<id>AEB</id>
<text>
<textStr>-</textStr>
</text>
</variable>
<variable>
<id>DESCRIPTION</id>
<text>
<textStr />
</text>
</variable>
<variable>
<id>VDTTM</id>
<text>
<textDate>
<date>01042016103658</date>
</textDate>
</text>
</variable>
<variable>
<id>STATUS</id>
<text>
<textValue>
<value>1.000000</value>
</textValue>
</text>
</variable>
</deviceState>
I want to achieve a functionality, where I can access values of every variable id by specifying a search filter and then access it's value directly, without being bothered by following meaningless tags.
<text><textValue> or <text><textDate> or <text><textStr/> or <text>
<textvalue><value>
something like, lets say new devices {a.id=node("id"), a.value=node("valu")}.
Currently I am using following code which does the trick but its not efficient, neither in speed, nor in manageability.
XDocument x = XDocument.Parse(_back);
string back = "";
string xvalue, yvalue;
foreach (XElement xe in x.Descendants().Take(1))
{
var s = xe.Value.IndexOf("Plug - Meter.VI");
var val = xe.Value.Substring(s, 25);
back= val.Substring(val.LastIndexOf("I")+1, 10);
break;
}
Any guidance will be highly appreciated. Thanks
Based on Monty's feedback, this is what I am using.
public protoDCM_CornerL08UMS_View()
{
InitializeComponent();
synchronizationContext = SynchronizationContext.Current;
StartingMeter();
}
private async void StartingMeter()
{
string val="0";
max = min = 0;
await Task.Run(() =>
{
do
{
UpdateUI(val,max,min);
val = fetchData();
Double temp =0;
if (Double.TryParse(val,out temp))
{
if(min==0&&max==0)
{
min = max = temp;
}
if(temp>max)
{
max = temp;
}
if(temp<min)
{
min = temp;
}
}
val = temp.ToString();
}
while (true);
});
}
private void UpdateUI(string value, Double _max , Double _min)
{
var timeNow = DateTime.Now;
if ((DateTime.Now - previousTime).Milliseconds <= 50) return;
synchronizationContext.Post(new SendOrPostCallback(o =>
{
lblInstant.Text= (string)o;
}), value);
synchronizationContext.Post(new SendOrPostCallback(o =>
{
lblMax.Text = (string)o;
}), _max.ToString());
synchronizationContext.Post(new SendOrPostCallback(o =>
{
lblMin.Text = (string)o;
}), _min.ToString());
previousTime = timeNow;
}
public Stream GenerateStreamFromString(string s)
{
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.Write(s);
writer.Flush();
stream.Position = 0;
return stream;
}
private string fetchData()
{
String _back = HttpGet("http://xxx.xxx.xxx"+Global.Node.Current.Device.Address+"/services/devices/deviceState.xml?id=D83AE139-E0C9-4B15-B2A9-6E0B57B28ED1?type=ALL");
//_back = FormatXML(Response);
try
{
DeviceState deserializedXML = new DeviceState();
XmlSerializer serializer = new XmlSerializer(typeof(DeviceState));
using (Stream stream = GenerateStreamFromString(_back))
{
deserializedXML = (DeviceState)serializer.Deserialize(stream);
var x = (from z in deserializedXML.Variable
where z.Id == "Plug - Meter.VI"
select new
{
Id = z.Id,
value= (z.Text.TextDate == null?
(z.Text.TextStr == null
? (z.Text.TextValue == null
? "No Text Value!" : z.Text.TextValue.Value.ToString()) : z.Text.TextStr.ToString()) : z.Text.TextDate.Date.ToString()) }).FirstOrDefault();
return x.value;
}
}
catch (Exception w)
{
MessageBox.Show(w.ToString());
return "0.0";
}
}
public static string HttpGet(string URI)
{
try
{
System.Net.WebRequest req = System.Net.WebRequest.Create(URI);
req.Method = "GET";
System.Net.WebResponse resp = req.GetResponse();
System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());
return sr.ReadToEnd().Trim();
}
catch (Exception sl)
{
return sl.ToString();
}
}
Try this....
Usings
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Serialization;
Classes
[XmlRoot(ElementName = "textValue")]
public class TextValue
{
[XmlElement(ElementName = "value")]
public string Value { get; set; }
}
[XmlRoot(ElementName = "text")]
public class Text
{
[XmlElement(ElementName = "textValue")]
public TextValue TextValue { get; set; }
[XmlElement(ElementName = "textStr")]
public string TextStr { get; set; }
[XmlElement(ElementName = "textDate")]
public TextDate TextDate { get; set; }
}
[XmlRoot(ElementName = "variable")]
public class Variable
{
[XmlElement(ElementName = "id")]
public string Id { get; set; }
[XmlElement(ElementName = "text")]
public Text Text { get; set; }
}
[XmlRoot(ElementName = "textDate")]
public class TextDate
{
[XmlElement(ElementName = "date")]
public string Date { get; set; }
}
[XmlRoot(ElementName = "deviceState")]
public class DeviceState
{
[XmlElement(ElementName = "id")]
public string Id { get; set; }
[XmlElement(ElementName = "device")]
public string Device { get; set; }
[XmlElement(ElementName = "variable")]
public List<Variable> Variable { get; set; }
}
code
try
{
DeviceState deserializedXML = new DeviceState();
// Deserialize to object
XmlSerializer serializer = new XmlSerializer(typeof(DeviceState));
using (FileStream stream = File.OpenRead(#"xml.xml"))
{
deserializedXML = (DeviceState)serializer.Deserialize(stream);
// Now get all your IDs
List<string> IDs = (from xml in deserializedXML.Variable select xml.Id).ToList();
} // Put a break-point here, then mouse-over IDs and you will see all your IDs... deserializedXML contains the entire object if you want anythin else ....
}
catch (Exception)
{
throw;
}
I read your XML from a file (xml.xml) that is in the application *.exe folder, you will need to adapt this solution depending on your specific requirements....
Is this what you need?....
try
{
XmlSerializer DeserializerPlaces = new XmlSerializer(typeof(DeviceState));
string html = string.Empty;
string url = #"https://<Your URL>";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
//request.AutomaticDecompression = DecompressionMethods.GZip;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
DeviceState dezerializedXML = (DeviceState)DeserializerPlaces.Deserialize(reader);
//html = reader.ReadToEnd();
}
//Console.WriteLine(html);
}
catch (System.Exception)
{
throw;
}
You would call that every 5 seconds and update your UI (from dezerializedXML properties)
I am calling an external service using GetAsync() and passing parameters in query string. When i check the content in the response, i don't see anything returned, however it returns 200 OK and in fiddler it returns me the XML response correctly. I need the XML response to get de-serialize to an C# object and then further save it to DB.
Things tried:
1) Tried this by adding this setting in global- app_start(), It didn't help
GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;
2) Created an object and tried to sent it via GetAysnc, that didn't help either.
public class Request
{
[XmlElement]
public string XML { get; set; }
[XmlElement]
public List<string> ProNumber { get; set; }
}
2) Should i try passing parameters in query string and expect json result? if i add mediatyperformatter to application/json?
Here is my code:
public async Task<HttpResponseMessage> GetData()
{
string requestString = "&xml=Y&PRONumber=82040X,03117X";
string result = "";
string url = #"http://my.yrc.com/dynamic/national/servlet?CONTROLLER=com.rdwy.ec.rextracking.http.controller.PublicTrailerHistoryAPIController";
try
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
HttpResponseMessage response = await client.GetAsync(url+requestString);
if (response.IsSuccessStatusCode)
{
return response;
}
}
}
catch (Exception ex)
{
result = ex.Message;
}
return null;
}
EDIT:
Shipments scp = null;
XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "Shipment";
xRoot.IsNullable = true;
XmlSerializer serializer = new XmlSerializer(typeof(Shipment), xRoot);
using (Stream stream = response.Content.ReadAsStreamAsync().Result)
{
scp = (Shipments)serializer.Deserialize(stream);
}
Model:
public class Shipments
{
[XmlArrayItem(Type = typeof(Shipment))]
public Shipment[] Shipment;
}
public class Shipment
{
[XmlAttribute()]
public int returnCode { get; set; }
.................
..............
Getting error:<SHIPMENTS xmlns=''> was not expected.
Any help on this is much appreciated.
Thanks,
WH
This worked for me -
var client = new HttpClient();
var data = client.GetStringAsync("http://my.yrc.com/dynamic/national/servlet?CONTROLLER=com.rdwy.ec.rextracking.http.controller.PublicTrailerHistoryAPIController&xml=Y&PRONumber=82040X,03117X").Result;
var ser = new XmlSerializer(typeof(Shipments));
var t = (Shipments)ser.Deserialize(new StringReader(data));
public class Shipment
{
public string returnCode { get; set; }
public string returnMessage { get; set; }
public string freightBillNumber { get; set; }
//props
}
[XmlRoot(ElementName = "SHIPMENTS")]
public class Shipments
{
[XmlElement(ElementName = "SHIPMENT")]
public List<Shipment> SHIPMENT { get; set; }
}
EDIT
this works as well -
var data = client.GetStreamAsync("http://my.yrc.com/dynamic/national/servlet?CONTROLLER=com.rdwy.ec.rextracking.http.controller.PublicTrailerHistoryAPIController&xml=Y&PRONumber=82040X,03117X").Result;
EDIT
works as well -
var client = new HttpClient();
var data = client.GetAsync("http://my.yrc.com/dynamic/national/servlet?CONTROLLER=com.rdwy.ec.rextracking.http.controller.PublicTrailerHistoryAPIController&xml=Y&PRONumber=82040X,03117X").Result;
var ser = new XmlSerializer(typeof(Shipments));
var t = (Shipments)ser.Deserialize(data.Content.ReadAsStreamAsync().Result);
I'm going to use DataContractJsonSerializer for JSON serialization/deserialization.
I have two object types in the JSON array and want them both to be deserialized into corresponding object types.
Having the following class defnitions
[DataContract]
public class Post {
[DataMember(Name = "content")]
public String Content { get; set; }
}
[DataContract]
public class User {
[DataMember(Name = "user_name")]
public String UserName { get; set; }
[DataMember(Name = "email")]
public String Email { get; set; }
}
[DataContract]
public class Container {
[DataMember(Name="posts_and_objects")]
public List<Object> PostsAndUsers { get; set; }
}
how can I detect them and deserialize both into the corresponding object type and store in PostsAndUsers property?
If you specific the known types you can serialize and deserialize your class Container, try this code:
protected static Stream GetStream<T>(T content)
{
MemoryStream memoryStream = new MemoryStream();
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T), new []{typeof(Post), typeof(User)});
serializer.WriteObject(memoryStream, content);
memoryStream.Seek(0, SeekOrigin.Begin);
return memoryStream;
}
protected static T GetObject<T>(Stream stream)
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T), new[] { typeof(Post), typeof(User) });
return (T)serializer.ReadObject(stream);
}
static void Main(string[] args)
{
var container = new Container {PostsAndUsers = new List<object>()};
container.PostsAndUsers.Add(new Post{Content = "content1"});
container.PostsAndUsers.Add(new User{UserName = "username1"});
container.PostsAndUsers.Add(new Post { Content = "content2" });
container.PostsAndUsers.Add(new User { UserName = "username2" });
var stream = GetStream(container);
var parsedContainer = GetObject<Container>(stream);
foreach (var postsAndUser in parsedContainer.PostsAndUsers)
{
Post post;
User user;
if ((post = postsAndUser as Post) != null)
{
// is post
}
else if ((user = postsAndUser as User) != null)
{
// is user
}
else
{
throw new Exception("");
}
}
}