Convert JSON data to querystring in C# GET request - c#

What is the best way to convert a JSON object into querystrings to append to a GET Url? The POST is straight forward and gets read by my Web API backend.
{Name: 'Mike' } = ?Name=Mike
private static string MakeRequest(HttpWebRequest req, string data)
{
try
{
if (req.Method == Verbs.POST.ToString() || req.Method == Verbs.PUT.ToString() || req.Method == Verbs.DELETE.ToString())
{
var encodedData = Encoding.UTF8.GetBytes(data);
req.ContentLength = encodedData.Length;
req.ContentType = "application/json";
req.GetRequestStream().Write(encodedData, 0, encodedData.Length);
}
using (var response = req.GetResponse() as HttpWebResponse)
using (var reader = new StreamReader(response.GetResponseStream()))
{
return reader.ReadToEnd();
}
}
catch (WebException we)
{
if(we.Response == null)
{
return JsonConvert.SerializeObject(new { Errors = new List<ApiError> { new ApiError(11, "API is currently unavailable") }});
}
using (var response = we.Response as HttpWebResponse)
using (var reader = new StreamReader(response.GetResponseStream()))
{
return reader.ReadToEnd();
}
}
}

If the json object is flat as in your example, then
string json = #"{
""name"": ""charlie"",
""num"": 123
}";
var jObj = (JObject)JsonConvert.DeserializeObject(json);
var query = String.Join("&",
jObj.Children().Cast<JProperty>()
.Select(jp=>jp.Name + "=" + HttpUtility.UrlEncode(jp.Value.ToString())));
query would be name=charlie&num=123

I make this code to run in .Net Core:
public static string JsonToQuery(this string jsonQuery)
{
string str = "?";
str += jsonQuery.Replace(":", "=").Replace("{","").
Replace("}", "").Replace(",","&").
Replace("\"", "");
return str;
}
Example:
var _baseURI = "http://www.example.com/";
var endPoint = "myendpoint";
ExampleObjectModel requestModel = new ExampleObjectModel();
var requestModelJson = JsonConvert.SerializeObject(requestModel);
var url = string.Format("{0}{1}{2}", _baseURI, endPoint, requestModelJson.JsonToQuery());

Try this, work all object, in deep
public static class ExtensionMethods
{
public static string GetQueryString(this object obj, string prefix = "")
{
var query = "";
try
{
var vQueryString = (JsonConvert.SerializeObject(obj));
var jObj = (JObject)JsonConvert.DeserializeObject(vQueryString);
query = String.Join("&",
jObj.Children().Cast<JProperty>()
.Select(jp =>
{
if (jp.Value.Type == JTokenType.Array)
{
var count = 0;
var arrValue = String.Join("&", jp.Value.ToList().Select<JToken, string>(p =>
{
var tmp = JsonConvert.DeserializeObject(p.ToString()).GetQueryString(jp.Name + HttpUtility.UrlEncode("[") + count++ + HttpUtility.UrlEncode("]"));
return tmp;
}));
return arrValue;
}
else
return (prefix.Length > 0 ? prefix + HttpUtility.UrlEncode("[") + jp.Name + HttpUtility.UrlEncode("]") : jp.Name) + "=" + HttpUtility.UrlEncode(jp.Value.ToString());
}
)) ?? "";
}
catch (Exception ex)
{
}
return query;
}
}
To use: SomeObject.GetQueryString();

if your object(Entity) have a Children like this Entity :
public class Parent
{
public Child childs { get; set; } = new Child();
public int PageIndex { get; set; }
public int? PageSize { get; set; }
}
public class Child
{
public int Id { get; set; }
public string Name { get; set; }
}
Your Can Use This Code For Build Query:
First Convert You Enrity Model To JObject
And Call This Method :
public static string GetQueryString(this JObject jObj)
{
return String.Join("&",
jObj.Children().Cast<JProperty>()
.Select(jp =>
{
if (jp.Value.Type == JTokenType.Object)
{
var arrValue = String.Join("&",
jObj.Values().Children().Cast<JProperty>()
.Select(jp => jp.Path + "=" + HttpUtility.UrlEncode(jp.Value.ToString())));
return arrValue;
}
else
{
var arrValue = String.Join("&", jp.Name + "=" + HttpUtility.UrlEncode(jp.Value.ToString()));
return arrValue;
}
}
)) ?? "";
}
Your Can Get Like This QueryString :
childs.Id=1&childs.Name="Test"&PageIndex=1&PageSize=1

Related

Display Multiple JsonObject on Listview

I have a Json from the server as below:
{
"data": {
"komik_popular": {
"title": "Yei! Komik Awas Nyamuk Jahat jadi literasi terpopuler minggu ini lho!"
},
"buku_baru": {
"title": "Ada buku baru nih, Katalog Prasekolah"
}
},
}
I want to display the json on the listview, but I try Debug.Writeline("judul: " + highlight.Title) first
Code:
Highlight highlight = new Highlight();
string title = "";
string urlPath = link;
var httpClient = new HttpClient(new HttpClientHandler());
var values = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("SCH-API-KEY", "SCH_KEnaBiDeplebt")
};
var response = await httpClient.PostAsync(urlPath, new FormUrlEncodedContent(values));
response.EnsureSuccessStatusCode();
string jsonText = await response.Content.ReadAsStringAsync();
try
{
JsonObject jsonObject = JsonObject.Parse(jsonText);
JsonObject jsonData = jsonObject["data"].GetObject();
JsonObject bukuBObject = jsonData.ContainsKey("buku_baru") && jsonData["buku_baru"] != null ? jsonData["buku_baru"].GetObject() : JsonObject.Parse("");
try
{
title = bukuBObject["title"].GetString();
}
catch
{
}
JsonObject komikPObject = jsonData.ContainsKey("komik_popular") && jsonData["komik_popular"] != null ? jsonData["komik_popular"].GetObject() : JsonObject.Parse("");
try
{
title = komikPObject["title"].GetString();
}
catch
{
}
highlight.Title = title;
Debug.WriteLine("judul: " + highlight.Title);
}
Highlight.cs:
class Highlight
{
public string Title { get; set; }
}
I'm having a problem, when I try to debug only the title on "komik_popular" is displayed, I want all the data in "komik_popular" and "buku_baru" to be displayed. How to handle it?
private List<Highlight > HighlightList = new List<Highlight>();
string urlPath = link;
var httpClient = new HttpClient(new HttpClientHandler());
var values = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("SCH-API-KEY", "SCH_KEnaBiDeplebt")
};
var response = await httpClient.PostAsync(urlPath, new FormUrlEncodedContent(values));
response.EnsureSuccessStatusCode();
string jsonText = await response.Content.ReadAsStringAsync();
try
{
JsonObject jsonObject = JsonObject.Parse(jsonText);
JsonObject jsonData = jsonObject["data"].GetObject();
JsonObject komikPObject = jsonData.ContainsKey("komik_popular") && jsonData["komik_popular"] != null ? jsonData["komik_popular"].GetObject() : JsonObject.Parse("");
try
{
Highlight highlight = new Highlight();
string title = "";
title = komikPObject["title"].GetString();
HighlightList.Add(highlight);
}
catch
{
}
JsonObject bukuBObject = jsonData.ContainsKey("buku_baru") && jsonData["buku_baru"] != null ? jsonData["buku_baru"].GetObject() : JsonObject.Parse("");
try
{
Highlight highlight = new Highlight();
string title = "";
title = bukuBObject["title"].GetString();
HighlightList.Add(highlight);
}
catch
{
}
}
catch
{
}
foreach( Highlight items in HighlightList)
{
Debug.WriteLine("judul: " + items .Title);
}
}
for converting json data to list, first you have to create respective class model as per given data format after that you can convert or deserialize it in your list format , in cae of your json data you can follow below example :-
public class Titel
{
public string title { get; set; }
}
public class Data
{
public Titel komik_popular { get; set; }
public Titel buku_baru { get; set; }
}
public class RootObject
{
public Data data { get; set; }
}
class Program
{
static void Main(string[] args)
{
string s = "{'data':{'komik_popular':{'title':'Yei! Komik Awas Nyamuk Jahat jadi literasi terpopuler minggu ini lho!'},'buku_baru':{'title':'Ada buku baru nih, Katalog Prasekolah'}}}";
List<RootObject> dataList = JsonConvert.DeserializeObject<List<RootObject>>(s);
}
}

Filter out API results

I have a list of information that comes from an API.
I want to filter out certain things for a ListBox. I have made a public string for this and added the information I wanted in the list.
Now the way I have it set up it shows the information I would like, but leaves empty spaces in the ListBox.
I want to get rid of this spaces in the ListBox. I have tried to return a null and a string.Empty
get
{
if( Status == 1)
{
string queues = $"{SSDocument.SSDocumentID} | {LastActionUser} | {LastAccessed} | {Queue.Name}";
return queues;
}
else
{
return null;
}
}
Information using the GET:
public void DocumentList(int sender)
{
if (sender == 1)
{
StatusList f = new StatusList();
f.Show();
st = rClient.makeRequest(S9());
f.listBox1.DataSource = st;
f.listBox1.DisplayMember = "QueueList";
}
}
Request for rClient.makeRequest(s9()):
public List<stats> makeRequest(string endPoint)
{
signOn so = new signOn();
string strResponseVlaue = string.Empty;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(endPoint);
request.Method = httpMethod.ToString();
request.Method = "GET";
string userName = so.grabUser();
string passWord = so.grabPass();
string domain = System.Configuration.ConfigurationManager.AppSettings["Domain"];
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes($"{domain}{userName}:{passWord}"));
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
{
throw new ApplicationException("Error Code: " + response.StatusCode.ToString());
}
//Process the response stream
using (Stream responseStream = response.GetResponseStream())
{
if (responseStream != null)
{
using (StreamReader reader = new StreamReader(responseStream))
{
strResponseVlaue = reader.ReadToEnd();
}
}
} //End of Response Stream
}// End Of Using Reponse
var obj = JsonConvert.DeserializeObject<List<stats>>(strResponseVlaue);
return obj;
}
The getter of a class property used as the DisplayMember of a ListBox control, tries to filter out the elements that do not satisfy a condition.
The condition is verified in the property getter, forcing to return null or string.Empty when the current element doesn't satisfy the condition.
This behaviour produces empty elements in the ListBox.
The proposed solution is, of course, to pre-filter the elements that define the ListBox data source before the property used as DisplayMember, can format the elements to display:
[ListBox].DataSource = st.Where(cls => [Condition]).ToList();
A probaly better solution is to build a class that can perform the filtering on its own.
An example:
int Sender = 1;
TestClass test = new TestClass();
test.AddRange(new []
{
new TestClass() { Status = 0, QueueName = "Queue1", SSDocumentID = 1 },
new TestClass() { Status = 1, QueueName = "Queue1", SSDocumentID = 1 },
new TestClass() { Status = 1, QueueName = "Queue2", SSDocumentID = 2 },
new TestClass() { Status = 0, QueueName = "Queue3", SSDocumentID = 3 },
new TestClass() { Status = 1, QueueName = "Queue4", SSDocumentID = 4 },
});
listBox1.DisplayMember = "DisplayMember";
listBox1.DataSource = test.Filter(Sender).ToList();
public class TestClass
{
public TestClass() => this.Members = new List<TestClass>();
public int Status { get; set; }
public int SSDocumentID { get; set; }
public string QueueName { get; set; }
public string DisplayMember => $"{this.SSDocumentID} | {this.QueueName}";
public List<TestClass> Members { get; }
public void Add(TestClass element) => this.Members.Add(element);
public void AddRange(IEnumerable<TestClass> elements) =>
this.Members.AddRange(elements.ToArray());
public IEnumerable<TestClass> Filter(int status)
{
if (this.Members.Count == 0) return null;
return this.Members.Where(st => st.Status == status);
}
}

Get the ID of file just streamed to SharePoint Document Folder

Please read the bottom of this post, since the question has been modified.
I have been successful in taking a file off of my computer and sending it to a document library in SharePoint. However, the "Title" column in the document is blank. I would like to set the "Title" column to a certain value, but not sure how to go about it.
Here is the code I use to upload the file
public static async Task PutFileAsync()
{
string genName = App.Generator;
genName = genName.Replace(" ", "-");
StorageLibrary videoLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Videos);
string readFolder = videoLibrary.SaveFolder.Path;
StorageFolder videoFolder = await StorageFolder.GetFolderFromPathAsync(readFolder);
string readFileName = App.Date + "-" + App.StartTime + "-" + App.IBX + "-" + genName + ".xlsx";
StorageFile readFile = await videoFolder.GetFileAsync(readFileName);
byte[] result;
using (Stream stream = await readFile.OpenStreamForReadAsync())
{
using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
result = memoryStream.ToArray();
}
}
var (authResult, message) = await Authentication.AquireTokenAsync();
var httpClient = new HttpClient();
HttpResponseMessage response;
string posturl = MainPage.spfileurl + readFile.Name + ":/content";
var request = new HttpRequestMessage(HttpMethod.Put, posturl);
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authResult.AccessToken);
request.Content = new ByteArrayContent(result);
response = await httpClient.SendAsync(request);
var responseString = await response.Content.ReadAsStringAsync();
await Task.Run(() =>
{
File.Delete(readFile.Path);
return TaskStatus.RanToCompletion;
});
}
Any suggestions would be great!
Thanks!
Other information
public static string rooturl = "https://graph.microsoft.com/v1.0/sites/mycompanyinc.sharepoint.com,495435b4-60c3-49b7-8f6e-1d262a120ae5,0fad9f67-35a8-4c0b-892e-113084058c0a/";
string submiturl = rooturl + "lists/18a725ac-83ef-48fb-a5cb-950ca2378fd0/items";
public static string spfileurl = rooturl + "drive/root:/Generator_Runs/";
public static string fileurl = rooturl + "lists/edd49389-7edb-41db-80bd-c8493234eafa/drive/items/01JDP7KXPY64K4C3P4YJC2CJ2IUFG7DAP7/content";
Since it is not possible to add column data while uploading, I need to figure out what the listitem ID is for the file that I just uploaded is.
This is the responseString after the submission
[JSON]
#odata.context: "https://graph.microsoft.com/v1.0/$metadata#sites('mycompanyinc.sharepoint.com%2C495435b4-60c3-49b7-8f6e-1d262a120ae5%2C0fad9f67-35a8-4c0b-892e-113084058c0a')/drive/root/$entity"
#microsoft.graph.downloadUrl: "https://mycompanyinc.sharepoint.com/sites/GeneratorApp/_layouts/15/download.aspx?UniqueId=...&ApiVersion=2.0"
createdDateTime: "12/29/2018 6:43:00 PM"
eTag: ""{BB51689A-9FF5-412C-8B45-D01D2B61A789},2""
id: "01JDP7KXM2NBI3X5M7FRAYWROQDUVWDJ4J"
lastModifiedDateTime: "12/29/2018 6:43:00 PM"
name: "FileNameJ.xlsx"
webUrl: "https://mycompanyinc.sharepoint.com/sites/GeneratorApp/_layouts/15/Doc.aspx?sourcedoc=%7BBB51689A-9FF5-412C-8B45-D01D2B61A789%7D&file=FileName.xlsx&action=default&mobileredirect=true"
cTag: ""c:{BB51689A-9FF5-412C-8B45-D01D2B61A789},4""
size: 47079
createdBy
lastModifiedBy
parentReference
file
fileSystemInfo
Okay, it took a lot of trial and error. I had to create another class to be able to parse out the data:
public class SharePointDocumentNew
{
public class RootObject
{
public string eTag { get; set; }
public string id { get; set; }
public string name { get; set; }
public string webUrl { get; set; }
}
}
AND
public class SharePointDocumentItems
{
public class Value
{
[JsonProperty("#odata.etag")]
public string OdataEtag { get; set; }
public string ETag { get; set; }
public string Id { get; set; }
public string WebUrl { get; set; }
}
public class RootObject
{
[JsonProperty("#odata.context")]
public string OdataContext { get; set; }
public List<Value> value { get; set; }
}
}
Then I found the matching data between the two and used REGEX to get the matching data with this code:
public static async Task PutFileAsync()
{
List<SharePointListItems.Lookup> Lookups = new List<SharePointListItems.Lookup>();
string genName = App.Generator;
genName = genName.Replace(" ", "-");
StorageLibrary videoLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Videos);
string readFolder = videoLibrary.SaveFolder.Path;
StorageFolder videoFolder = await StorageFolder.GetFolderFromPathAsync(readFolder);
string readFileName = App.Date + "-" + App.StartTime + "-" + App.IBX + "-" + genName + ".xlsx";
StorageFile readFile = await videoFolder.GetFileAsync(readFileName);
byte[] result;
using (Stream stream = await readFile.OpenStreamForReadAsync())
{
using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
result = memoryStream.ToArray();
}
}
var (authResult, message) = await Authentication.AquireTokenAsync();
var httpClient = new HttpClient();
HttpResponseMessage response;
string posturl = MainPage.spfileurl + readFile.Name + ":/content";
var request = new HttpRequestMessage(HttpMethod.Put, posturl);
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authResult.AccessToken);
request.Content = new ByteArrayContent(result);
response = await httpClient.SendAsync(request);
var responseString = await response.Content.ReadAsStringAsync();
JObject json = JObject.Parse(responseString);
var result3 = JsonConvert.DeserializeObject<SharePointDocumentNew.RootObject>(responseString);
eTag = result3.eTag.ToString();
eTag = eTag.Replace("\"{", "");
string replacement = "";
string endPattern = "}.*";
Regex rgxend = new Regex(endPattern);
eTag = rgxend.Replace(eTag, replacement);
eTag = Regex.Replace(eTag, #"[A-Z]+?", m => m.ToString().ToLower());
await Task.Run(() =>
{
File.Delete(readFile.Path);
return TaskStatus.RanToCompletion;
});
}
public static async Task GetFileDataAsync()
{
List<SharePointDocumentItems.Value> Value2 = new List<SharePointDocumentItems.Value>();
var (authResult2, message2) = await Authentication.AquireTokenAsync();
var httpClient2 = new HttpClient();
HttpResponseMessage response2;
string geturl = "https://graph.microsoft.com/v1.0/sites/mycoinc.sharepoint.com,495435b4-60c3-49b7-8f6e-1d262a120ae5,0fad9f67-35a8-4c0b-892e-113084058c0a/lists/edd49389-7edb-41db-80bd-c8493234eafa/items";
var request2 = new HttpRequestMessage(HttpMethod.Get, geturl);
request2.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authResult2.AccessToken);
response2 = await httpClient2.SendAsync(request2);
var responseString2 = await response2.Content.ReadAsStringAsync();
JObject json2 = JObject.Parse(responseString2);
var result2 = JsonConvert.DeserializeObject<SharePointDocumentItems.RootObject>(responseString2);
foreach (var d in result2.value)
{
string ETAG = d.ETag;
string startPattern = "^\\\"";
string replacement = "";
string endPattern = ",.*";
Regex rgxstart = new Regex(startPattern);
ETAG = rgxstart.Replace(ETAG, replacement);
Regex rgxend = new Regex(endPattern);
ETAG = rgxend.Replace(ETAG, replacement);
if (ETAG == eTag)
{
fileID = d.Id;
}
}
}
Now I have the ID I need to update the other columns associated with the file.

how to add multiple items in the model in the mvc

i have 2 devices , each device having 10 lattitude and 10 longitude values. im having 2 devices which has 10 lat long values of each , but only 10 items are adding another 10 items of device 2 data are getting replaced in the model. how to add 2 devices data in the model like this without creating 2 different classes for each.
im accessing the model values in the view like this
#Model[0].latitude.ToString()....#Model[9].latitude.ToString(),
#Model[1].longitude.ToString()....#Model[9].latitude.ToString(),
i should be able to access the 2 different devices data in the view like this
#Model[0][0]...[0][9];
#Model[1][0]...[1][9];
code
public ActionResult Index()
{
List<AssetTrackerViewModel> model = new List<AssetTrackerViewModel>();
model.AddRange(getAssetDetails("ED"));
model.AddRange(getAssetDetails("EE"));
return View(model);
}
private List<AssetTrackerViewModel> getAssetDetails(string deviceID)
{
List<AssetTrackerViewModel> model = new List<AssetTrackerViewModel>();
try
{
WebRequest req = WebRequest.Create(#"url");
req.Method = "GET";
req.Headers["Authorization"] = "Basic " + "a2VybmVsc3BoZXJlOmtlcm5lbHNwaGVyZQ==";
HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
var encoding = resp.CharacterSet == "" ? Encoding.UTF8 : Encoding.GetEncoding(resp.CharacterSet);
using (var stream = resp.GetResponseStream())
{
var reader = new StreamReader(stream, encoding);
var responseString = reader.ReadToEnd();
var Pirs = Newtonsoft.Json.JsonConvert.DeserializeObject<List<AssetDetail>>(responseString);
var items = Pirs.Where(a => !a.dataFrame.EndsWith("AAAAAAAAAAA="))
.GroupBy(a => a.dataFrame.Substring(a.dataFrame.Length - 12))
.Select(g => g.First()) .OrderByDescending(a => a.timestamp).Take(10);
foreach (var item in items)
{
byte[] data = Convert.FromBase64String(item.dataFrame.ToString());
string hex = BitConverter.ToString(data);//converting base 64 to hexcode
string formattedHex = BitConverter.ToString(data).Replace(#"-", string.Empty);
string longitude = formattedHex.Substring(14, formattedHex.Length - 14);//04AC07EB
long longitudeValue = Convert.ToInt64(longitude, 16);
string longvalue = longitudeValue.ToString();
longvalue = longvalue.Insert(2, ".");
string latitude = formattedHex.Substring(6, formattedHex.Length - 14); //010A366B
long lat = Convert.ToInt64(latitude, 16);
string latvalue = lat.ToString();
latvalue = latvalue.Insert(2, ".");
AssetTrackerViewModel assetModel = new AssetTrackerViewModel();
assetModel.deviceid = deviceID;
assetModel.latitude = latvalue;
assetModel.longitude = longvalue;
model.Add(assetModel);
}
}
}
return model;
}
view model
public class AssetDetail
{
public long id { get; set; }
public DateTime timestamp { get; set; }
public string dataFrame { get; set; }
}
Modify you classes:
// this is class that represents single device
public class AssetTracker
{
public AssetTracker()
{
latitude = new List<string>();
longitude = new List<string>();
}
public string deviceid {get; set;}
public List<string> latitude {get; set;}
public List<string> longitude {get; set;}
}
Then you viewmodel:
public class AssetTrackersViewModel
{
public AssetTrackersViewModel()
{
AssetTrackers = new List<AssetTracker>();
}
public List<AssetTracker> AssetTrackers {get;set}
}
Then your getAssetDetails method:
private AssetTracker getAssetDetails(string deviceID)
{
var assetTracker = new AssetTracker { deviceid = deviceID };
try
{
WebRequest req = WebRequest.Create(#"url");
req.Method = "GET";
req.Headers["Authorization"] = "Basic " + "a2VybmVsc3BoZXJlOmtlcm5lbHNwaGVyZQ==";
HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
var encoding = resp.CharacterSet == "" ? Encoding.UTF8 : Encoding.GetEncoding(resp.CharacterSet);
using (var stream = resp.GetResponseStream())
{
var reader = new StreamReader(stream, encoding);
var responseString = reader.ReadToEnd();
var Pirs = Newtonsoft.Json.JsonConvert.DeserializeObject<List<AssetDetail>>(responseString);
var items = Pirs.Where(a => !a.dataFrame.EndsWith("AAAAAAAAAAA="))
.GroupBy(a => a.dataFrame.Substring(a.dataFrame.Length - 12))
.Select(g => g.First()) .OrderByDescending(a => a.timestamp).Take(10);
foreach (var item in items)
{
byte[] data = Convert.FromBase64String(item.dataFrame.ToString());
string hex = BitConverter.ToString(data);//converting base 64 to hexcode
string formattedHex = BitConverter.ToString(data).Replace(#"-", string.Empty);
string longitude = formattedHex.Substring(14, formattedHex.Length - 14);//04AC07EB
long longitudeValue = Convert.ToInt64(longitude, 16);
string longvalue = longitudeValue.ToString();
longvalue = longvalue.Insert(2, ".");
string latitude = formattedHex.Substring(6, formattedHex.Length - 14); //010A366B
long lat = Convert.ToInt64(latitude, 16);
string latvalue = lat.ToString();
latvalue = latvalue.Insert(2, ".");
assetTracker.latitude.Add(latvalue);
assetTracker.longitude.Add(longvalue);
}
return assetTracker;
}
}
}
Then:
public ActionResult Index()
{
var model = new AssetTrackersViewModel();
model.AssetTrackers.Add(getAssetDetails("ED"));
model.AssetTrackers.Add(getAssetDetails("EE"));
return View(model);
}
Then, you can call in Razor:
#model AssetTrackersViewModel
for first 'device'
#Model.AssetTrackers[0].latitude[0]
#Model.AssetTrackers[0].longitude[0]
#Model.AssetTrackers[0].latitude[9]
#Model.AssetTrackers[0].longitude[9]
for second 'device'
#Model.AssetTrackers[1].latitude[0]
#Model.AssetTrackers[1].longitude[0]
#Model.AssetTrackers[1].latitude[9]
#Model.AssetTrackers[1].longitude[9]

How can I get data from a HTTP post in C# Xamarin?

I am trying to POST some data using HTTPClient. I have managed to use the following code when simply getting data in JSON format, but it doesn't seem to work for a POST.
This is the code I'm using:
public static async Task<SwipeDetails> SaveSwipesToCloud()
{
//get unuploaded swips
IEnumerable<SwipeDetails> swipesnotsved = SwipeRepository.GetUnUploadedSwipes();
foreach (var item in swipesnotsved)
{
//send it to the cloud
Uri uri = new Uri(URL + "SaveSwipeToServer" + "?locationId=" + item.LocationID + "&userId=" + item.AppUserID + "&ebCounter=" + item.SwipeID + "&dateTimeTicks=" + item.DateTimeTicks + "&swipeDirection=" + item.SwipeDirection + "&serverTime=" + item.IsServerTime );
HttpClient myClient = new HttpClient();
var response = await myClient.GetAsync(uri);
//the content needs to update the record in the SwipeDetails table to say that it has been saved.
var content = await response.Content.ReadAsStringAsync();
}
return null;
}
This is the method it's trying to contact. As you can see, the method also returns some data in JSON format so as well as a POST it's also getting some data back which I need to be able to work with:
[HttpPost]
public JsonResult SaveSwipeToServer(int locationId, int userId, int ebCounter, long dateTimeTicks, int swipeDirection, int serverTime)
{
bool result = false;
string errMsg = String.Empty;
int livePunchId = 0;
int backupPunchId = 0;
IClockPunch punch = null;
try
{
punch = new ClockPunch()
{
LocationID = locationId,
Swiper_UserId = userId,
UserID = ebCounter,
ClockInDateTime = DateTimeJavaScript.ConvertJavascriptDateTime(dateTimeTicks),
ClockedIn = swipeDirection.Equals(1),
};
using (IDataAccessLayer dal = DataFactory.GetFactory())
{
DataAccessResult dalResult = dal.CreatePunchForNFCAPI(punch, out livePunchId, out backupPunchId);
if (!dalResult.Result.Equals(Result.Success))
{
throw dalResult.Exception;
}
}
result = true;
}
catch (Exception ex)
{
errMsg = "Something Appeared to go wrong when saving punch information to the horizon database.\r" + ex.Message;
}
return Json(new
{
result = result,
punchDetails = punch,
LivePunchId = livePunchId,
BackUpPunchId = backupPunchId,
timeTicks = DateTimeJavaScript.ToJavaScriptMilliseconds(DateTime.UtcNow),
errorMessage = errMsg
}
,JsonRequestBehavior.AllowGet);
}
At the moment the data being stored in 'content' is just an error message.
You can post the parameters in the body of the request.
public static async Task<SwipeDetails> SaveSwipesToCloud() {
//get unuploaded swips
var swipesnotsved = SwipeRepository.GetUnUploadedSwipes();
var client = new HttpClient() {
BaseAddress = new Uri(URL)
};
var requestUri = "SaveSwipeToServer";
//send it to the cloud
foreach (var item in swipesnotsved) {
//create the parameteres
var data = new Dictionary<string, string>();
data["locationId"] = item.LocationID;
data["userId"] = item.AppUserID;
data["ebCounter"] = item.SwipeID;
data["dateTimeTicks"] = item.DateTimeTicks;
data["swipeDirection"] = item.SwipeDirection;
data["serverTime"] = item.IsServerTime;
var body = new System.Net.Http.FormUrlEncodedContent(data);
var response = await client.PostAsync(requestUri, body);
//the content needs to update the record in the SwipeDetails table to say that it has been saved.
var content = await response.Content.ReadAsStringAsync();
}
return null;
}
I am not sure how you host your service, it is not clear from your code. I hosted mine in Web API controller SwipesController in application HttpClientPostWebService. I don't suggest to use JsonResult. For mobile client I would just return the class you need.
You have 2 options:
Use get not post.
Use post.
Both cases are below
Controller:
namespace HttpClientPostWebService.Controllers
{
public class SwipesController : ApiController
{
[System.Web.Http.HttpGet]
public IHttpActionResult SaveSwipeToServer(int locationId, int userId, int ebCounter, long dateTimeTicks, int swipeDirection, int serverTime)
{
return Ok(new SwipeResponse
{
TestInt = 3,
TestString = "Testing..."
});
}
[System.Web.Http.HttpPost]
public IHttpActionResult PostSwipeToServer([FromBody] SwipeRequest req)
{
return Ok(new SwipeResponse
{
TestInt = 3,
TestString = "Testing..."
});
}
}
public class SwipeRequest
{
public string TestStringRequest { get; set; }
public int TestIntRequest { get; set; }
}
public class SwipeResponse
{
public string TestString { get; set; }
public int TestInt { get; set; }
}
}
Client:
async private void Btn_Clicked(object sender, System.EventArgs e)
{
HttpClient client = new HttpClient();
try
{
var result = await client.GetAsync(#"http://uri/HttpClientPostWebService/Api/Swipes?locationId=1&userId=2&ebCounter=3&dateTimeTicks=4&swipeDirection=5&serverTime=6");
var content = await result.Content.ReadAsStringAsync();
var resp = JsonConvert.DeserializeObject<SwipeResponse>(content);
}
catch (Exception ex)
{
}
try
{
var result1 = await client.PostAsync(#"http://uri/HttpClientPostWebService/Api/Swipes",
new StringContent(JsonConvert.SerializeObject(new SwipeRequest() { TestIntRequest = 5, TestStringRequest = "request" }), Encoding.UTF8, "application/json"));
var content1 = await result1.Content.ReadAsStringAsync();
var resp1 = JsonConvert.DeserializeObject<SwipeResponse>(content1);
}
catch (Exception ex)
{
}
}

Categories