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]
Related
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);
}
}
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.
I want to create a json like this :
{'sr_no':'OH009876673','data':[{'code':'0124','findex':'3'},{'code':'0126','findex':'5'},{'code':'0125','findex':'8'}]}
I am trying to do it but got error becuase I am using postData as dictinory
code
var data = new Dictionary<int, string>();
JavaScriptSerializer jss = new JavaScriptSerializer();
axCZKEM1.EnableDevice(iMachineNumber, false);
Cursor = Cursors.WaitCursor;
axCZKEM1.ReadAllUserID(iMachineNumber);//read all the user information to the memory
axCZKEM1.ReadAllTemplate(iMachineNumber);//read all the users' fingerprint templates to the memory
while (axCZKEM1.SSR_GetAllUserInfo(iMachineNumber, out sdwEnrollNumber, out sName, out sPassword, out iPrivilege, out bEnabled))//get all the users' information from the memory
{
for (idwFingerIndex = 0,i=0; idwFingerIndex < 10; idwFingerIndex++,i++)
{
if (axCZKEM1.GetUserTmpExStr(iMachineNumber, sdwEnrollNumber, idwFingerIndex, out iFlag, out sTmpData, out iTmpLength))//get the corresponding templates string and length from the memory
{
var obj = new Dictionary<string, string>();
obj["code"] = sdwEnrollNumber;
obj["findex"] = idwFingerIndex.ToString();
data[i] = jss.Serialize(obj);
i++;
}
}
}
axCZKEM1.EnableDevice(iMachineNumber, true);
var client = new RestClient();
client.EndPoint = #"";
var postData = new Dictionary<string, string>();
postData["sr_no"] = sr_no;
postData["data"] = data; // error on this line because data is array and trying to assign to string
How to solve this because I want array of object in JSON to request to API.
You can use NewtonSoft.Json to serialize object. Since you already have a sample of expected json data, you can generate the c# class on http://json2csharp.com/
public class Datum
{
public string code { get; set; }
public string findex { get; set; }
}
public class RootObject
{
public string sr_no { get; set; }
public List<Datum> data { get; set; }
}
And use the class in your code instead creating Dictionary
RootObject obj = new RootObject();
obj.sr_no = "OH009876673";
obj.data = new List<Datum>();
......
......
while (axCZKEM1.SSR_GetAllUserInfo(iMachineNumber, out sdwEnrollNumber, out sName, out sPassword, out iPrivilege, out bEnabled))//get all the users' information from the memory
{
for (idwFingerIndex = 0,i=0; idwFingerIndex < 10; idwFingerIndex++,i++)
{
if (axCZKEM1.GetUserTmpExStr(iMachineNumber, sdwEnrollNumber, idwFingerIndex, out iFlag, out sTmpData, out iTmpLength))//get the corresponding templates string and length from the memory
{
//var obj = new Dictionary<string, string>();
//obj["code"] = sdwEnrollNumber;
//obj["findex"] = idwFingerIndex.ToString();
//data[i] = jss.Serialize(obj);
//i++;
obj.data.Add( new Datum() {code = sdwEnrollNumber, findex = idwFingerIndex.ToString()});
}
}
}
axCZKEM1.EnableDevice(iMachineNumber, true);
var client = new RestClient();
client.EndPoint = #"";
var outputJson = JsonConvert.SerializeObject(obj);
try this:
var sr_no = "";
var data =new List<Data>();
JavaScriptSerializer jss = new JavaScriptSerializer();
axCZKEM1.EnableDevice(iMachineNumber, false);
Cursor = Cursors.WaitCursor;
axCZKEM1.ReadAllUserID(iMachineNumber);//read all the user information to the memory
axCZKEM1.ReadAllTemplate(iMachineNumber);//read all the users' fingerprint templates to the memory
while (axCZKEM1.SSR_GetAllUserInfo(iMachineNumber, out sdwEnrollNumber, out sName, out sPassword, out iPrivilege, out bEnabled))//get all the users' information from the memory
{
for (idwFingerIndex = 0, i = 0; idwFingerIndex < 10; idwFingerIndex++, i++)
{
if (axCZKEM1.GetUserTmpExStr(iMachineNumber, sdwEnrollNumber, idwFingerIndex, out iFlag, out sTmpData, out iTmpLength))//get the corresponding templates string and length from the memory
{
data.Add(new Data { code = sdwEnrollNumber, findex = idwFingerIndex.ToString() });
i++;
}
}
}
var postObject = new RootObject
{
sr_no = sr_no,
data = data
};
var postData = jss.Serialize(postObject);
public class Data
{
public string code { get; set; }
public string findex { get; set; }
}
public class RootObject
{
public string sr_no { get; set; }
public List<Data> data { get; set; }
}
also i suggested to use newtonsoft instead of JavaScriptSerializer .
I have the following code:
[WebMethod]
public bool AddUser(long warnId, double longitude, double latitude)
{
try
{
string jsonFeature = string.Empty;
jsonFeature += "[{'geometry': {'x': " + longitude + ",'y': " + latitude +
",'spatialReference': {'wkid': 4326}},'attributes': {'UID': '";
jsonFeature += warnId + "','Latitude': '" + latitude + "','Longitude': '" + longitude + "'}}]";
string reqURL = System.Configuration.ConfigurationManager.AppSettings["WARNURL"] + "addFeatures";
using (System.Net.WebClient client = new System.Net.WebClient())
{
client.Headers["Content-type"] = "application/x-www-form-urlencoded";
client.Encoding = System.Text.Encoding.UTF8;
var collection = new System.Collections.Specialized.NameValueCollection();
collection.Add("f", "json");
collection.Add("features", jsonFeature);
byte[] response = client.UploadValues(reqURL, "POST", collection);
MemoryStream stream = new MemoryStream(response);
StreamReader reader = new StreamReader(stream);
string aRespStr = reader.ReadToEnd();
JavaScriptSerializer jss = new JavaScriptSerializer();
AddResult addResult = jss.Deserialize<AddResult>(aRespStr);
return aRespStr.Contains("true") && aRespStr.Contains("success");
}
}
catch(Exception e)
{
string message = e.Message;
return false;
}
}
when I run it the string aRespStr is:
"{\"addResults\":[{\"objectId\":28,\"globalId\":\"{740490C6-77EE-4AC0-9561-5EBAACE3A0A7}
\",\"success\":true}]}"
I created the following classes to hold the object once I deserialize it:
public class Error
{
public int code { get; set; }
public string description { get; set; }
}
public class AddResult
{
public int objectId { get; set; }
public object globalId { get; set; }
public bool success { get; set; }
public Error error { get; set; }
}
public class RootObject
{
public List<AddResult> addResults { get; set; }
}
but when I run the code the addResult object contains the default object values not the json object values.
The api for this particular response is here:
http://help.arcgis.com/en/arcgisserver/10.0/apis/rest/fsadd.html
any help on getting this to work is greatly appreciated
Try this
RootObject addResults=jss.Deserialize<RootObject>(aRespStr);
or similary you can try this
List<AddResult> addResults = jss.Deserialize<List<AddResult>>(aRespStr);
as you are returning list of AddResult in your json Response.
And Change the content type to application/json
change
client.Headers["Content-type"] = "application/x-www-form-urlencoded";
to
client.Headers["Content-type"] = "Application/json";
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