I have the following piece of code that loads a file with JSON from local folder and then parses it:
async public static void TryLoad(Callback Ok, Action Fail, string key, int offset)
{
try
{
var now = DateTime.Now;
ItemsCache cacheItem;
var folder = ApplicationData.Current.LocalFolder;
var stream = await folder.OpenStreamForReadAsync(key);
using (stream)
{
var result = await new StreamReader(stream).ReadToEndAsync();
Debug.WriteLine("Raw data loaded: " + (DateTime.Now - now).TotalMilliseconds);
cacheItem = JsonConvert.DeserializeObject<ItemsCache>(result);
Debug.WriteLine("Json has been parsed: " + (DateTime.Now - now).TotalMilliseconds);
stream.Close();
}
bool isOK = cacheItem.IsValid(offset);
if (isOK) Ok(cacheItem.Data); else Fail();
}
catch (Exception)
{
Fail();
}
}
And ItemsCache itself:
public class ItemsCache
{
public string Stamp { get; set; }
public JToken Data { get; set; }
public bool IsValid(int ofs)
{
DateTime moment = DateTime.Parse(Stamp);
return (DateTime.Now - moment).TotalSeconds < ofs;
}
}
Output after loading the data twice in a row:
Raw data loaded: 356,7372
Json has been parsed: 855,588
Raw data loaded: 1269,6079
Json has been parsed: 1300,8621
JSON:
{"Stamp":"26.01.2013 20:49:26","Data":[{"id":188357911,"user":123145, ... a few more more key-value pairs}, ... the rest of the objects]}
Thing is, the whole process takes about 750 milliseconds, 150 of them to load a raw data and 600 to parse it using Newtonsoft JSON library. The amount of data itself is small and contains about 20 serialized objects that are essentially a small key-value pairs (Although I've found out I could add a lot more data and it will not affect parsing time much).
Question is if it's normal to take that much time to load data and even more time to parse it? What could I do if it's not normal?
Related
I have a middleware telemetry handler, that has a method that awaits the execution of a request, and then tries to store some key data values from the response body into custom dimensions fields in application insights, so I can use graphana and potentially other 3rd party products to analyse my reponses.
public class ResponseBodyHandler : IResponseBodyHandler
{
private readonly ITelemetryPropertyHandler _telemetryPropertyHandler = new TelemetryPropertyHandler();
public void TransformResponseBodyDataToTelemetryData(RequestTelemetry requestTelemetry, string responseBody)
{
SuccessResponse<List<Booking>> result = null;
try
{
result = JsonConvert.DeserializeObject<SuccessResponse<List<Booking>>>(responseBody);
}
catch (Exception e)
{
Log.Error("Telemetry response handler, failure to deserialize response body: " + e.Message);
return;
}
_telemetryPropertyHandler.CreateTelemetryProperties(requestTelemetry, result);
}
}
public class TelemetryPropertyHandler : ITelemetryPropertyHandler
{
private readonly ILabelHandler _labelHandler = new LabelHandler();
public void CreateTelemetryProperties(RequestTelemetry requestTelemetry, SuccessResponse<List<Booking>> result)
{
Header bookingHeader = result?.SuccessObject?.FirstOrDefault()?.BookingHeader;
requestTelemetry?.Properties.Add("ResponseClientId", "" + bookingHeader?.ConsigneeNumber);
Line line = bookingHeader?.Lines.FirstOrDefault();
requestTelemetry?.Properties.Add("ResponseProductId", "" + line?.PurchaseProductID);
requestTelemetry?.Properties.Add("ResponseCarrierId", "" + line?.SubCarrierID);
_labelHandler.HandleLabel(requestTelemetry, bookingHeader);
requestTelemetry?.Properties.Add("ResponseBody", JsonConvert.SerializeObject(result));
}
}
Now, inside: _labelHandler.HandleLabel(requestTelemetry, bookingHeader);
It extracts an Image that is base64 encoded, chunks up the string in sizes of 8192 characters, and adds them to the Properties as: Image index 0 .. N (N being the total chunks)
I can debug and verify that the code works.
However, on application insights, the entire "request" entry, is missing, not just the custom dimensions.
I am assuming that this is due to a maximum size constraint, and I am likely trying to add more data than is "allowed", however, I can't for the life of me, find the documentation that enforces this restriction.
Can someone tell what rule I am breaking? so I can either truncate the image out, if it isn't possible to store that much data? Or if there is something else I am doing wrong?
I have validated, that my code works fine, as long as I truncate the data into a single Property, that of course only partially stores the Image. (Making said "feature" useless)
public class LabelHandler : ILabelHandler
{
private readonly IBase64Splitter _base64Splitter = new Base64Splitter();
public void HandleLabel(RequestTelemetry requestTelemetry, Header bookingHeader)
{
Label label = bookingHeader?.Labels.FirstOrDefault();
IEnumerable<List<char>> splitBase64String = _base64Splitter.SplitList(label?.Base64.ToList());
if (splitBase64String != null)
{
bool imageHandlingWorked = true;
try
{
int index = 0;
foreach (List<char> chunkOfImageString in splitBase64String)
{
string dictionaryKey = $"Image index {index}";
string chunkData = new string(chunkOfImageString.ToArray());
requestTelemetry?.Properties.Add(dictionaryKey, chunkData);
index++;
}
}
catch (Exception e)
{
imageHandlingWorked = false;
Log.Error("Error trying to store label in chunks: " + e.Message);
}
if (imageHandlingWorked && label != null)
{
label.Base64 = "";
}
}
}
}
The above code is responsible for adding the chunks to a requestTelemetry Property field
public class Base64Splitter : IBase64Splitter
{
private const int ChunkSize = 8192;
public IEnumerable<List<T>> SplitList<T>(List<T> originalList)
{
for (var i = 0; i < originalList.Count; i += ChunkSize)
yield return originalList.GetRange(i, Math.Min(ChunkSize, originalList.Count - i));
}
}
This is the specific method for creating a char list chunk of characters, that correspond to the application insights maximum size pr custom dimension field.
Here is an image of the truncated field being added, if I just limit myself to a single property, but truncate the base64 encoded value.
[I'm from Application Insights team]
You can find field limits documented here: https://learn.microsoft.com/en-us/azure/azure-monitor/app/data-model-request-telemetry
On ingestion side there is a limit of 64 * 1024 bytes for overall JSON payload (need to add it to documentation).
You're facing something different though - that custom dimensions are removed completely. Maybe SDK detects that 64kb is exceeded and "mitigates" it this way. Can you try to limit it to a little bit less than 64kb?
I am new to Tests in Visual Studio , normally I always used proper test tool in order to validate the json file and its data
I am stuck how to validate JSON objects , data inside in the JSON File
through following code I am Reading the JSON file , further i would like to validate the JSON objects
here is my readJSON method which reads the file but now I would like to either check if it contains any given specific value let say I would like to check if it contains the "Details" and its value "XYZG" or not
I tried to convert JSON into ToString() and then user .count method but it gives me the value 0 in output so I removed that ToString() block from the code
JSON Data
{
"Details":"XYZG",
"City":"Tokyo",
"Id":"ATOOO",
"Name":"Johny"
}
read json method
public string ReadMyJsonFile(String FilePath)
{
string storeValue = "";
using (StreamReader readerobject = new StreamReader(FilePath))
{
string jsonString = readerobject.ReadToEnd();
}
return storeValue;
}
TestMethod
public async TaskTest()
{
var json = ReadMyJsonFile(#"FilePath/Test.json");
var testobject = JsonConvert.DeserializeObject<JObject>(json);
Console.WriteLine(testobject);
try
{
if (testobject.SelectTokens("$..Id").Any(t => t.Value<string>() == "$..Id"))
{
Console.WriteLine("\n \n value exist");
}
}
catch (Exception ex)
{
Console.WriteLine("error keyword");
}
}
ยดยดยด
I am kinda stuck with the validation part of my json data
you better print a json string, not a JObject
try
{
var json = ReadMyJsonFile(#"FilePath/Test.json");
if (!string.IsNullOrEmpty(json))
{
Console.WriteLine("json file exists \n");
Console.WriteLine(json);
}
else
{
Console.WriteLine("json file not exists \n");
return;
}
var testObject = JObject.Parse(json);
if (!string.IsNullOrEmpty((string)testObject["Id"]))
{
Console.WriteLine("\n Id value exists");
Console.WriteLine((string)testObject["Id"]);
}
else
Console.WriteLine("\n Id value doesnt exist");
}
catch (Exception ex)
{
Console.WriteLine("error "+ex.Message);
}
Question Background:
Update:
I'm still not sure how to go about extracting the relevant information from this response. I have tried setting my response type to JSON but still receive the response as shown below. I have taken into account what has been said in regards to using NameValueCollection but still cant see how this will help with such a large response. Ideally I'd like this mapped to an object structure of some kind, it dosen't necessarily have to be JSON.
Question:
I'm currently using the PayPal Api 'ExpressCheckout' method to allow users to pay for items on my test site. A HTTP response from the API provides a large response containing key information I need to extract - such as the buyers address, if the payment was succesful etc.
The Issue:
Currently I'm stuck on how to work with the response. Ideally I'd convert the data to a JSON string then use Newtonsoft to map the data to C# classes thus allowing easy access to the data. Here is an example of the Httpresponse:
TOKEN=EC%2XXXXXXXXXXXXXXXXXR&BILLINGAGREEMENTACCEPTEDSTATUS=0&CHECKOUTSTATUS=PaymentActionNotInitiated&TIMESTAMP=2015%2d01%2d02T21%3a11%3a30Z&CORRELATIONID=ab184fdba7a30&ACK=Success&VERSION=88%2e0&BUILD=14443165&EMAIL=test%40aol%2ecom&PAYERID=3XXXXXXXXXX4N&PAYERSTATUS=verified&BUSINESS=Test%20Biz%27s%20Test%20Store&FIRSTNAME=Joe&LASTNAME=King&COUNTRYCODE=GB&SHIPTONAME=Joe%20King%27s%20Test%20Store&SHIPTOSTREET=1%20Main%20Terrace&SHIPTOCITY=Wolverhampton&SHIPTOSTATE=West%20Midlands&SHIPTOZIP=W12%204LQ&SHIPTOCOUNTRYCODE=GB&SHIPTOCOUNTRYNAME=United%20Kingdom&ADDRESSSTATUS=Confirmed&CURRENCYCODE=GBP&AMT=15%2e56&ITEMAMT=15%2e56&SHIPPINGAMT=0%2e00&HANDLINGAMT=0%2e00&TAXAMT=0%2e00&INSURANCEAMT=0%2e00&SHIPDISCAMT=0%2e00&L_NAME0=ItemOne&L_QTY0=4&L_TAXAMT0=0%2e00&L_AMT0=3%2e89&L_ITEMWEIGHTVALUE0=%20%20%200%2e00000&L_ITEMLENGTHVALUE0=%20%20%200%2e00000&L_ITEMWIDTHVALUE0=%20%20%200%2e00000&L_ITEMHEIGHTVALUE0=%20%20%200%2e00000&PAYMENTREQUEST_0_CURRENCYCODE=GBP&PAYMENTREQUEST_0_AMT=15%2e56&PAYMENTREQUEST_0_ITEMAMT=15%2e56&PAYMENTREQUEST_0_SHIPPINGAMT=0%2e00&PAYMENTREQUEST_0_HANDLINGAMT=0%2e00&PAYMENTREQUEST_0_TAXAMT=0%2e00&PAYMENTREQUEST_0_INSURANCEAMT=0%2e00&PAYMENTREQUEST_0_SHIPDISCAMT=0%2e00&PAYMENTREQUEST_0_INSURANCEOPTIONOFFERED=false&PAYMENTREQUEST_0_SHIPTONAME=Joe%20King%27s%20Test%20Store&PAYMENTREQUEST_0_SHIPTOSTREET=1%20Main%20Terrace&PAYMENTREQUEST_0_SHIPTOCITY=Wolverhampton&PAYMENTREQUEST_0_SHIPTOSTATE=West%20Midlands&PAYMENTREQUEST_0_SHIPTOZIP=W12%204LQ&PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE=GB&PAYMENTREQUEST_0_SHIPTOCOUNTRYNAME=United%20Kingdom&PAYMENTREQUEST_0_ADDRESSSTATUS=Confirmed&L_PAYMENTREQUEST_0_NAME0=ItemOne&L_PAYMENTREQUEST_0_QTY0=4&L_PAYMENTREQUEST_0_TAXAMT0=0%2e00&L_PAYMENTREQUEST_0_AMT0=3%2e89&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE0=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE0=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE0=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE0=%20%20%200%2e00000&PAYMENTREQUESTINFO_0_ERRORCODE=0
If anyone could give me an easy way to map this data to a C# object that would be great.
Is there any specific reason why you want it in JSON format? If its not requirement and if you can live with key value pair then here is one way you can process response as key value pair.
public partial class Form1 : Form
{
Dictionary<string, string> processedResponse = null;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string rawResponse = "TOKEN=EC%2XXXXXXXXXXXXXXXXXR&BILLINGAGREEMENTACCEPTEDSTATUS=0&CHECKOUTSTATUS=PaymentActionNotInitiated&TIMESTAMP=2015%2d01%2d02T21%3a11%3a30Z&CORRELATIONID=ab184fdba7a30&ACK=Success&VERSION=88%2e0&BUILD=14443165&EMAIL=test%40aol%2ecom&PAYERID=3XXXXXXXXXX4N&PAYERSTATUS=verified&BUSINESS=Test%20Biz%27s%20Test%20Store&FIRSTNAME=Joe&LASTNAME=King&COUNTRYCODE=GB&SHIPTONAME=Joe%20King%27s%20Test%20Store&SHIPTOSTREET=1%20Main%20Terrace&SHIPTOCITY=Wolverhampton&SHIPTOSTATE=West%20Midlands&SHIPTOZIP=W12%204LQ&SHIPTOCOUNTRYCODE=GB&SHIPTOCOUNTRYNAME=United%20Kingdom&ADDRESSSTATUS=Confirmed&CURRENCYCODE=GBP&AMT=15%2e56&ITEMAMT=15%2e56&SHIPPINGAMT=0%2e00&HANDLINGAMT=0%2e00&TAXAMT=0%2e00&INSURANCEAMT=0%2e00&SHIPDISCAMT=0%2e00&L_NAME0=ItemOne&L_QTY0=4&L_TAXAMT0=0%2e00&L_AMT0=3%2e89&L_ITEMWEIGHTVALUE0=%20%20%200%2e00000&L_ITEMLENGTHVALUE0=%20%20%200%2e00000&L_ITEMWIDTHVALUE0=%20%20%200%2e00000&L_ITEMHEIGHTVALUE0=%20%20%200%2e00000&PAYMENTREQUEST_0_CURRENCYCODE=GBP&PAYMENTREQUEST_0_AMT=15%2e56&PAYMENTREQUEST_0_ITEMAMT=15%2e56&PAYMENTREQUEST_0_SHIPPINGAMT=0%2e00&PAYMENTREQUEST_0_HANDLINGAMT=0%2e00&PAYMENTREQUEST_0_TAXAMT=0%2e00&PAYMENTREQUEST_0_INSURANCEAMT=0%2e00&PAYMENTREQUEST_0_SHIPDISCAMT=0%2e00&PAYMENTREQUEST_0_INSURANCEOPTIONOFFERED=false&PAYMENTREQUEST_0_SHIPTONAME=Joe%20King%27s%20Test%20Store&PAYMENTREQUEST_0_SHIPTOSTREET=1%20Main%20Terrace&PAYMENTREQUEST_0_SHIPTOCITY=Wolverhampton&PAYMENTREQUEST_0_SHIPTOSTATE=West%20Midlands&PAYMENTREQUEST_0_SHIPTOZIP=W12%204LQ&PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE=GB&PAYMENTREQUEST_0_SHIPTOCOUNTRYNAME=United%20Kingdom&PAYMENTREQUEST_0_ADDRESSSTATUS=Confirmed&L_PAYMENTREQUEST_0_NAME0=ItemOne&L_PAYMENTREQUEST_0_QTY0=4&L_PAYMENTREQUEST_0_TAXAMT0=0%2e00&L_PAYMENTREQUEST_0_AMT0=3%2e89&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE0=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE0=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE0=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE0=%20%20%200%2e00000&PAYMENTREQUESTINFO_0_ERRORCODE=0";
//Process response
processedResponse = ProcessResponse(rawResponse);
//Use received data e.g.
//Get First name
string fName = GetRecordValue("FIRSTNAME");
//Get Last name
string lName = GetRecordValue("LASTNAME");
}
private Dictionary<string,string> ProcessResponse(string response)
{
Dictionary<string, string> responseData = new Dictionary<string, string>();
if(!string.IsNullOrWhiteSpace(response))
{
string[] firstPass = response.Split(new char[] { '&' });
foreach(string pair in firstPass)
{
string[] secondPass = pair.Split(new char[] { '=' });
if(secondPass!=null && secondPass.Length>0)
{
responseData.Add(secondPass[0].Trim(), secondPass[1].Trim());
}
}
}
return responseData;
}
private string GetRecordValue(string record)
{
string recordValue = null;
if(processedResponse!=null)
{
if(!string.IsNullOrWhiteSpace(record) && processedResponse.ContainsKey(record))
{
recordValue= processedResponse[record];
}
}
return recordValue;
}
}
Still unsure what's the problem with dealing with it as a NameValueCollection.
E.g.
//NameValueCollection
//or use HttpUtility.ParseQueryString(some_string_of_names_values)
var foo = Request.QueryString;
var bar = foo["FIRSTNAME"]; //based on above this is "Joe"
Update:
It is response string which is being processed here and not request hence you wont be able to retrieve details using Request.QueryString
As stated in comments:
string rawResponse = "TOKEN=EC%2XXXXXXXXXXXXXXXXXR&BILLINGAGREEMENTACCEPTEDSTATUS=0&CHECKOUTSTATUS=PaymentActionNotInitiated&TIMESTAMP=2015%2d01%2d02T21%3a11%3a30Z&CORRELATIONID=ab184fdba7a30&ACK=Success&VERSION=88...."
var foo = HttpUtility.ParseQueryString(rawResponse); //NameValueCollection
var bar = foo["FIRSTNAME"]; //Joe
I'm trying to read and write data with json file.
I created some class.
public class SimpleTask{...}
public class DayTask{...}
public class DataModel
{
...
private async Task GetSimpleTaskAsync()
{
if (_daytask.Count != 0)
return;
string fileName = "a.json";
Uri appUri = new Uri("ms-appx:///"+ fileName);
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(appUri);
string jsonText = await FileIO.ReadTextAsync(file);
JsonObject jsonObject = JsonObject.Parse(jsonText);
JsonArray jsonArray = jsonObject["DayTasks"].GetArray();
foreach (JsonValue daytaskValue in jsonArray)
{
JsonObject daytaskObject = daytaskValue.GetObject();
ObservableCollection<SimpleTask> simpletask = new ObservableCollection<SimpleTask>();
foreach (JsonValue simpletaskValue in daytaskObject["Tasks"].GetArray())
{
JsonObject simpletaskObject = simpletaskValue.GetObject();
simpletask.Add(new SimpleTask( simpletaskObject["StartTime"].GetString(),
simpletaskObject["EndTime"].GetString(),
simpletaskObject["Description"].GetString()));
}
DayTask daytask = new DayTask(daytaskObject["Day"].GetString(),simpletask);
this.DayTasks.Add(daytask);
}
}
}
As you can see, i have a method that gets data form a.json file. I created a.json file:
In the MainPage.xaml.cs, there is a method which calls GetDayTaskAysnc() method and retrieves data :
private async void ReadData1(object sender, TappedRoutedEventArgs e)
{
string test = String.Empty;
var daytask = await DataModel.GetDayTaskAsync();
foreach (var tasks in daytask)
{
test += String.Format("Day:{0}:\n", tasks.Day);
foreach (var simpletask in tasks.Tasks)
{
test += String.Format("\tStart Time: {0}\n", simpletask.StartTime);
test += String.Format("\tEnd Time: {0}\n", simpletask.EndTime);
test += String.Format("\tDescription Time: {0}\n", simpletask.Description);
}
}
TextBlock.Text = test;
}
It worked fine ! But i want to write data to the same file, so i added data in hardcore way:
private List<DayTask> creatList()
{
List<DayTask> DayTasks = new List<DayTask>();
ObservableCollection<SimpleTask> simpletask1 = new ObservableCollection<SimpleTask>();
simpletask1.Add(new SimpleTask("6AM","7AM","Breakfast"));
simpletask1.Add(new SimpleTask("8AM", "9AM", "Game"));
ObservableCollection<SimpleTask> simpletask2 = new ObservableCollection<SimpleTask>();
simpletask2.Add(new SimpleTask("6AM", "7AM", "Sleep"));
simpletask2.Add(new SimpleTask("8AM", "9AM", "School"));
DayTasks.Add(new DayTask ("3/8/2014",simpletask1));
DayTasks.Add(new DayTask("4/8/2014", simpletask2));
return DayTasks;
}
private async void WriteData(object sender, TappedRoutedEventArgs e)
{
string json = "a.json";
List<DayTask> daytasks = creatList();
var serializer = new DataContractJsonSerializer(typeof(List<DayTask>));
var stream = await ApplicationData.Current.LocalFolder.OpenStreamForWriteAsync(json, CreationCollisionOption.ReplaceExisting);
using (stream)
{
serializer.WriteObject(stream, daytasks);
}
TextBlock.Text = "Write to Json file succeeded";
}
When i ran my app with window phone emulator, Firstly, it wrote to the file. Then i clicked read data button to ensure data written correctly, the emulator showed data from a.json file without being modified by WriteData() method. I continued to creat the second read data method:
private async void ReadData2(object sender, TappedRoutedEventArgs e)
{
string test = String.Empty;
string json = "a.json";
string content = String.Empty;
List<DayTask> mytasks = new List<DayTask>();
var deserializer = new DataContractJsonSerializer(typeof(List<DayTask>));
var stream = await ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(json);
using (stream)
{
mytasks = (List<DayTask>)deserializer.ReadObject(stream);
}
foreach (var tasks in mytasks)
{
test += String.Format("Day:{0}:\n", tasks.Day);
foreach (var simpletask in tasks.Tasks)
{
test += String.Format("\tStart Time: {0}\n", simpletask.StartTime);
test += String.Format("\tEnd Time: {0}\n", simpletask.EndTime);
test += String.Format("\tDescription Time: {0}\n", simpletask.Description);
}
}
TextBlock.Text = test;
}
I deployed my app several times, and this is my result:
ReadData2() : 'System.IO.FileNotFoundException'
WriteData() -> ReadData1(): Data from a.json was shown
WriteData() -> ReadData2(): Data from creatList() was shown
WriteData() -> ReadData1(): Data from a.json was shown -> ReadData2(): Data from creatList() was shown
So that, i have some question:
Do i have 2 json files, one i created by adding into my project and the other one i created when ran WriteData() method ? What is their paths ?
If my file is data.json in DataSource folder, how can i write data to it ? I can read data from it using uri like GetSimpleTaskAsync() but i don't know how to write to it correctly. (I tried to convert object into string to write but can't read it again, i guess i wrote it in wrong way)
Sorry for my long post and my bad english :) Thank you very much
But i want to write data to the same file, so i added data in hardcore way:
Your are making confusion between ms-appx:/// and ms-appdata:/// folders (or ApplicationData.Current.LocalFolder )
The ms-appx folder is read-only. You can't write to it. (or you could edit your app code without passing through the certification process)
The file you wrote must be into the ms-appdata folder.
When I visit the page with the browser it is xml but when I request the url it is json. Is there something in mvc 4 api that makes it only output json to requests through the program or can I get xml back. Note: this is happening in a desktop application and a webpage so it has to be a setting of some sort and here was the error that the desktop gave me: Data at the root level is invalid. Line 1, position 1. And yes I am loading the doc right and I checked the value by using json instead and it came back ok.
private void Plus_Click(object sender, EventArgs e)
{
string FValue = id.Text;
string SValue = id2.Text;
string ending;
string url = "http://localhost:56254/api/add?id=" + FValue + "&id2=" + SValue;
XmlDocument xdoc = new XmlDocument();
xdoc.Load(url);
XmlNode xNode = xdoc.SelectSingleNode("End");
ending = xNode.InnerText;
Answer.Text = ending;
}
This is my desktop application code.
My code it gets the xml is right here:
namespace Calculator.Controllers
{
using Calculator.Models;
public class AddController : ApiController
{
public Calcs GetAddition(int id, int id2)
{
double end = id + id2;
Calcs[] calcs = new Calcs[] { new Calcs { FValue = id, SValue = id2, End = end } };
return calcs[0];
}
}
}
Here is Calcs:
namespace Calculator.Models
{
public class Calcs
{
public int FValue { get; set; }
public int SValue { get; set; }
public double End { get; set; }
}
}
Here is what the browser puts out:
<Calcs xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Calculator.Models">
<End>60</End>
<FValue>55</FValue>
<SValue>5</SValue>
</Calcs>
You need to set the accept header type in your request. However, since you neglected to provide enough information to know how you were requesting the data, that's as far as I can help you.\
EDIT:
The problem here is that XmlDocument.Load does not send an accept header that includes xml in the accepted formats (kind of stupid really, one would think It would).
You probably have to use an WebRequest to retrieve the document, specifying an accept header indicating "application/xml;q=0.9".
You can find a solution here: C# Won't Load A Certain XML, But Works in Browser