How is such a request interpreted in the code? - c#

I have a JSON request like this:
{
"locations" : [
"53.44059300,-2.22992800",
"53.36246000,-2.26683200"
],
}
How I got it from Postmana:
var body = #"{
" + "\n" +
#" ""locations"" : [
" + "\n" +
#" ""53.44059300,-2.22992800"",
" + "\n" +
#" ""53.36246000,-2.26683200""
" + "\n" +
#" ]
" + "\n" + #"}";
And now I wanted to rewrite the string query into a structured one:
var request = new Request();
foreach (var address in incomingRequest.Addresses)
{
request .Locations.Add(new Locations
{
Latitude = address.Latitude,
Longitude = address.Longitude
});
}
Request class looks like this:
internal class Request : DerivedA
{
public List<Locations> Locations { get; set; } = new List<Locations>();
}
But, in the end, my output is different from the initial request:
{
"Locations":[
{
"Latitude":51.469575800000,
"Longitude":-0.449607200000
},
{
"Latitude":53.361936300000,
"Longitude":-2.272971700000
}
]
}

This is just a string:
"53.44059300,-2.22992800"
So locations would be just an array of strings:
internal class Request : DerivedA
{
public List<string> Locations { get; set; } = new List<string>();
}
Which you'd populate with strings:
var request = new Request();
foreach (var address in incomingRequest.Addresses)
{
request.Locations.Add($"{address.Latitude},{address.Longitude}");
}
As an aside...
Naming is important. You currently have (but may no longer need) a class called Locations which represents a single location. Mixing up plurality is a bug waiting to happen.

Related

ASP.NET Core 2.1 Calling Rest API in a schedule

I have this ASP.NET Core 2.1 web application. The admin gets online game codes from the page below. Selecting the game (Razer Gold Pin), quantity and email to send those codes.
A Rest API call is made for the purchase. There is a limit for purchasing, a maximum of 200 purchases can be made at one time.
At first, there wasn't much to buy so there was no problem. But the demand has increased, when there are 10 thousand, 20 thousand purchases, it is necessary to purchase from this screen for hours. I wonder can we make a large number of purchases without waiting in front of the screen with scheduling?
Here is the the Javascript in the cshtml:
$("#btn_add").html(
'<span class="spinner-border spinner-border-sm" role="status" id="spinner" aria-hidden="true"></span> Loading...'
);
var selText = $("#validationCustom04").val();
var gameName = $("#validationCustom04 option:selected").text();
var quantity = $("#quantity").val();
var email = $("#email").val();
var price = $("#total").val();
var company = $("#validationCustom05").val();
if ($("#total").val() !== '') {
price = $("#total").val();
}
var serviceUrl = '/GameBanks/A101PinAsync?quantity=' + quantity + '&game=' + selText + '&email=' + email + '&prc=' + price + '&gameName=' + gameName + '&company=' + company;
$.ajax({
type: "GET",
url: serviceUrl,
dataType: 'json',
success: function (data) {
//alert(JSON.stringify(data));
ShowResult(data);
$("#spinner").remove();
$("#btn_add").html('Add');
}, error: function (xhr, status, error) {
$("#spinner").remove();
$("#btn_add").html('Add');
var errorMessage = xhr.responseText;
alert('Error - ' + errorMessage);
}
});
Here is the controller method:
[HttpGet]
public async Task<IActionResult> A101PinAsync(int quantity, string game, string email, int prc, string gameName, string company)
{
var price = 0;
try
{
string result = null;
var dList = new DemoList();
if (prc > 0)
{
price = prc;
}
var games = new Game { Product = game, Quantity = quantity };
var content = await games.CallGameAsync("Test", "12345", game, quantity, company);
var deserializedResult = JObject.Parse(content);
var root = JsonConvert.DeserializeObject<Root>(content);
if ((string)deserializedResult["coupons"]?[0]?["Serial"] == null)
{
result = result + gameName + ":" + (string)deserializedResult["Message"] + "\n";
}
else
{
foreach (var coupon in root.coupons)
{
result = result + gameName + " Serial:" + coupon.Serial + " Pin:" + coupon.Pin + "\n";
}
}
dList.gameList = result;
// NLOG
NLogPin(logger, User.Identity.Name, DateTime.Now, result, email);
return new JsonResult(dList);
}
catch (Exception e)
{
// NLOG
NLog(logger2, "OyunPalas " + e.Message, DateTime.UtcNow,0);
return StatusCode(500,e.Message);
}
}
Here is the Web API calling method:
public class Game
{
public string Username { get; set; }
public string Password { get; set; }
public string Product { get; set; }
public int Quantity { get; set; }
public string ShopNo { get; set; }
private static readonly Logger logger2 = LogManager.GetLogger("exceptionFile");
public async Task<string> CallGameAsync(string username, string password, string product, int quantity, string company)
{
try
{
HttpWebRequest request = null;
request = (HttpWebRequest)WebRequest.Create("http://111.111.111.111:1907//api/v2/web/purchase");
var svcCredentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(username + ":" + password));
request.Headers.Add("Authorization", "Basic " + svcCredentials);
request.Method = "POST";
request.KeepAlive = false;
request.ContentType = "application/x-www-form-urlencoded";
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("productCode", product),
new KeyValuePair<string, string>("quantity", quantity.ToString()),
new KeyValuePair<string, string>("shopNo", company),
new KeyValuePair<string, string>("safeNo", company),
new KeyValuePair<string, string>("cashierNo", company)
});
var urlEncodedString = await content.ReadAsStringAsync();
using (var streamWriter = new StreamWriter(await request.GetRequestStreamAsync()))
{
await streamWriter.WriteAsync(urlEncodedString);
}
var httpResponse = (HttpWebResponse) (await request.GetResponseAsync());
var response = new HttpResponseMessage
{
StatusCode = httpResponse.StatusCode,
Content = new StreamContent(httpResponse.GetResponseStream()),
};
//Read response
var htmlResponse = await response.Content.ReadAsStringAsync();
return htmlResponse;
}
catch (Exception e)
{
//NLOG
NLog(logger2, "Test" + e.Message);
throw;
}
}
public void NLog(Logger logger, string user)
{
var sb = new StringBuilder();
sb.AppendLine("Test: " + user);
logger.Info(sb.ToString());
}
}
I have to pass product (game type) to the job. I read the https://www.quartz-scheduler.net/documentation/quartz-3.x/tutorial/more-about-jobs.html#jobdatamap documentation but not fully understand how to use in my case. And I wonder if I can stop/cancel the job from this page before its end time?
I really appreciate any help you can provide. I'm sorry if the question is too silly as I have no experience with this scheduling.
Edit:
I thought of a solution like this, but I'm not sure if it's viable.
The user will enter which game, how many they want to buy, and their e-mail address on the screen.
This data will be saved in a table (BulkRequest) containing this information and the status field in the SQL database. (game: ABC, quantity:20000, status:0)
One IHostedService will get the saved data in a schedule which status=0 from the BulkRequest table and the save requests with status information in a new table (GameRequests) in multiples of 100. (game: ABC, quantity:100, status:0)
Another IHostedService will get the records in 10 minutes schedule which status=0 from the GameRequests table and make the 3rd party API call. Write a response to another table (GameResponses) and set the status=1 if there is no error.
When all requests are completed (status = 1), the status in the BulkRequest table will also be updated to 1.
A third IHostedService will check the status of BulkRequest, if status=1 then maybe a fourth service will prepare a file and send the responses to the e-mail.
I do suggest reviewing message queuing tools such RabbitMQ. With this architecture you will do all the jobs using messaging protocols with no need for "scheduling" and any "x minutes schedule" s would be ommited. Also it is more stable and error handling could be done using best practice standards. More important, it is scalable and you can have multiple hostedServices even on different servers process items in queue:
When request is registered send a message (publish) to the queue.
The hostedService1 receives the item and process it (consume). Multiple services may subscribe to process requests.
The hostedService1 may do all the job it self or even dispatch some parts to other services using the same method
The solution you proposed is doing the same job with an ad-hoc process. In fact you are reinventing the wheel. Hope it helps.

Unexpected character encountered while parsing value, JSON Object

I have an JSON object that looks like this:
"field2_body":null,"field3_body":null,"field4_body":null,"h_phrases":[{"h_phrase":"H222"},{"h_phrase":"H411"},{"h_phrase":"H361"},{"h_phrase":"H315"}]
But this is only a part of the JSON object because it is very big.
What I want to do is to access the h_phrase string values but when i try i get this error:
ERROR Unexpected character encountered while parsing value: {. Path '[0].h_phrases', line 64, position 7.
And this is my code:
public class PhrasesData
{
[JsonProperty(PropertyName = "h_phrases")]
public string H_Phrases { get; set; }
}
public async void getPhrasesForSpecificProduct(string productId)
{
var baseUrl = "http://www.kemtest.com/rest/organisations";
var specProductUrl = baseUrl + "/" + activeOrganisationId + "/" + "products/" + productId;
try
{
var baseAddress = new Uri(specProductUrl);
var cookieContainer = new CookieContainer();
using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
{
validToken = System.Net.WebUtility.UrlEncode(validToken);
cookieContainer.Add(baseAddress, new Cookie("access_token", string.Format(validToken)));
var result = client.GetAsync(specProductUrl).Result;
result.EnsureSuccessStatusCode();
if (result.IsSuccessStatusCode)
{
var content = await result.Content.ReadAsStringAsync();
var array = JArray.Parse(content);
PhrasesData[] myPhrasesData = JsonConvert.DeserializeObject<PhrasesData[]>(array.ToString());
if (myPhrasesData == null)
throw new JsonException();
string[] H_PhrasesArr = new string[myPhrasesData.Length];
for (int i = 0; i < myPhrasesData.Length; i++)
{
H_PhrasesArr[i] = myPhrasesData[i].H_Phrases;
var H_PhrasesVar = H_PhrasesArr[i];
Debug.WriteLine("God Damn PHRASES: " + H_PhrasesVar);
}
}
}
}catch (Exception ex) { Debug.WriteLine(#" ERROR {0}", ex.Message); }
}
What's the problem with my code?
Your JSON string is invalid. You need to enclose it with { and }.
Use http://jsonlint.com/ before coding with JSON objects.
{
"field2_body": null,
"field3_body": null,
"field4_body": null,
"h_phrases": [{
"h_phrase": "H222"
}, {
"h_phrase": "H411"
}, {
"h_phrase": "H361"
}, {
"h_phrase": "H315"
}]
}

GnU GPL v2 DHTMLX ASP.net C# - How to read data from data base (JSON) returned by a class

I read that I can do something like this
scheduler.parse([
{ start_date:"2013-05-13 6:00", end_date:"2009-05-13 8:00", text:"Event 1"},
{ start_date:"2013-06-09 6:00", end_date:"2009-06-09 8:00", text:"Event 2"}
],"json");
on http://docs.dhtmlx.com/scheduler/api__scheduler_parse.html
but I dont want to manually place all data, I want it to read data from my database
so what I did is that I have this method on Data.ashx
public string getJson(int ID)
{
XXXContext db = new XXXContext();
var YYYY = db.Y.Where(p => p.YYYID == ID).Include(p => p.ZZZZ).ToList();
List<CalendarEvent> cEvent = new List<CalendarEvent>();
foreach (var evnt in YYYYY)
{
cEvent.Add(new CalendarEvent() { id = evnt.AAAAID, text = evnt.PPPPP.FirstName.ToString() + " " + evnt.PPPPP.MiddleName.ToString() + " " + evnt.PPPPP.LastName.ToString() + "<br />" +
evnt.Reason.ToString() + "<br />" + evnt.Details.ToString(), start_date = evnt.XXXXXDateTime??DateTime.Now, end_date = evnt.XXXXXDateTime??DateTime.Now });
}
IEnumerable<CalendarEvent> toIEnum = cEvent;
string json = new JavaScriptSerializer().Serialize(toIEnum);
return json;
}
This returns a JSON formatted output
but i dont know what to do next<
this is what i got on my html file, which I called using IFrame on my aspx class
<script type="text/javascript" charset="utf-8">
function init() {
scheduler.config.multi_day = true;
scheduler.config.xml_date="%Y-%m-%d %H:%i";
scheduler.init('scheduler_here',new Date(2015,0,10),"week");
scheduler.load("../../Data.ashx");
}
You need to specify data format in arguments of scheduler.load, otherwise it would expect xml by default:
scheduler.load("../../Data.ashx", "json");
Also note that the client side will expect start_date/end_date dates to be serialized in the format specified in scheduler.config.xml_date config ("%Y-%m-%d %H:%i" according to your code) while JavaScriptSerializer will stringify DateTime into something following:
"start_date": "/Date(1355496152000)/"
there are a couple of possible workarounds, for example, you can override a method that parses dates and parse them manually:
scheduler.templates.xml_date = function (dateString) {
var timestamp = dateString.substring(6, dateString.length - 2);
return new Date(timestamp * 1);
};
scheduler.load("../../Data.ashx", "json");

Format values as a valid json file in C#

I'm trying to write lines in a valid JSON format using C# in a efficient way
What the file should look like:
[
{
"uuid": "c92161ba-7571-3313-9b59-5c615d25251c",
"name": "thijmen321"
},
{
"uuid": "3b90891d-e6fc-44cc-a1a8-e822378ec148",
"name": "TehGTypo"
},
{
"uuid": "5f820c39-5883-4392-b174-3125ac05e38c",
"name": "CaptainSparklez"
}
]
I already have the names and the UUIDs, but I need a way to write them to a file. I want to do this one by one, so, first the file looks like this:
[
{
"uuid": "c92161ba-7571-3313-9b59-5c615d25251c",
"name": "thijmen321"
}
]
Then like this:
[
{
"uuid": "c92161ba-7571-3313-9b59-5c615d25251c",
"name": "thijmen321"
},
{
"uuid": "3b90891d-e6fc-44cc-a1a8-e822378ec148",
"name": "TehGTypo"
}
]
etc. But of course, the UUIDs and the names are different, so how can I do this in a efficient way without using any APIs etc.?
My current (really inefficient) code:
public void addToWhitelist()
{
if (String.IsNullOrEmpty(whitelistAddTextBox.Text)) return;
string player = String.Empty;
try
{
string url = String.Format("https://api.mojang.com/users/profiles/minecraft/{0}", whitelistAddTextBox.Text);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(url));
request.Credentials = CredentialCache.DefaultCredentials;
using (WebResponse response = request.GetResponse())
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
player = reader.ReadToEnd();
}
catch (WebException ex)
{
Extensions.ShowError("Cannot connect to http://api.mojang.com/! Check if you have a valid internet connection. Stacktrace: " + ex, MessageBoxIcon.Error);
}
catch (Exception ex)
{
Extensions.ShowError("An error occured! Stacktrace: " + ex, MessageBoxIcon.Error);
}
if (String.IsNullOrWhiteSpace(player)) { Extensions.ShowError("This player doesn't seem to exist.", MessageBoxIcon.Error); return; }
player = player.Replace(",\"legacy\":true", "")
.Replace("\"id", " \"uuid")
.Replace("\"name", " \"name")
.Replace(",", ",\n")
.Replace("{", " {\n")
.Replace("}", "\n },");
File.WriteAllText(Program.programPath + #"\Servers\" + servers[currentIndex].Name + #"\whitelist.json", "");
try
{
using (StreamWriter sw = File.AppendText(Program.programPath + #"\Servers\" + servers[currentIndex].Name + #"\whitelist.json"))
{
sw.WriteLine("[");
foreach (string s in File.ReadAllLines(Program.programPath + #"\Servers\" + servers[currentIndex].Name + #"\whitelist.json"))
if (s.Contains("[") || s.Contains("]") || s.Equals(Environment.NewLine)) continue;
else sw.WriteLine(s);
sw.WriteLine(player);
sw.WriteLine("]");
whitelistListBox.Items.Add("\n" + whitelistAddTextBox.Text);
}
}
catch (Exception ex) { Extensions.ShowError("An error occured while update whitelist.json! Stacktrace: " + ex); }
whitelistAddTextBox.Clear();
}
The recommand "Microsoft" way is with a data contract and the DataContractJsonSerializer.. see here
https://msdn.microsoft.com/de-de/library/system.runtime.serialization.json.datacontractjsonserializer%28v=vs.110%29.aspx
an example of the contact would be:
[DataContract]
internal class Person
{
[DataMember]
internal string name;
[DataMember]
internal string Uuid ;
}
you use the class in the following way (obviously)
Person p = new Person();
p.name = "John";
p.Uuid = "3b90891d-e6fc-44cc-a1a8-e822378ec148";
and serialize it with the Contract Serializer
MemoryStream stream1 = new MemoryStream();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Person));
ser.WriteObject(stream1, p);
example to show the serialzed data:
stream1.Position = 0;
StreamReader sr = new StreamReader(stream1);
Console.WriteLine(sr.ReadToEnd());
Try json.net it will do the serialization job for you: http://www.newtonsoft.com/json
I would use a JSON Serializer like http://www.newtonsoft.com/json
This would allow you to roll your uuid/name as a class, instead of doing the parsing yourself
So something like:
internal class UuidNamePair
{
string Uuid { get; set; }
string Name { get; set; }
}
Then when calling this, you would just do something like this:
List<UuidNamePair> lst = new List<UuidNamePair>();
lst.Add(new UuidNamePair() { Name = "thijmen321", Uuid = "c92161ba-7571-3313-9b59-5c615d25251c" });
lst.Add(new UuidNamePair() { Name = "TehGTypo", Uuid = "3b90891d-e6fc-44cc-a1a8-e822378ec148" });
string json = JsonConvert.SerializeObject(lst, Formatting.Indented);
Console.WriteLine(json);
Instead of the Console.WriteLine, you could do your POST to a web service or however you're trying to use this json.

VersionOne: query.v1 how to generate a .V1.Ticket.VersionOne.Web ticket for client.Headers["Cookie"]

I have access to Summer2013 of Versionone.
I am trying to access it via new query.v1 using the Json Example which uses a client header cookie that looks like this:
_client.Headers["Cookie"] = ".V1.Ticket.VersionOne.Web=" + ticket;
How do I generate a .V1.Ticket.VersionOne.Web ticket for the cookie?
Json Example: https://github.com/versionone/versionone-oauth2-examples/blob/master/csharp/YamlClient/Program.cs
Note: I have generated a OAuth 2 token via these directions but it doesn't contain a ticket.
https://community.versionone.com/Developers/Developer-Library/Documentation/API/Security/Oauth_2.0_Authentication/Using_OAuth_2.0_for_Web_Server_Applications
Here's the code:
namespace V1Json
{
class JsonClient
{
private readonly Uri _url;
private readonly string _ticket;
private WebClient _client;
public JsonClient(string url, string ticket)
{
_url = new Uri(url);
_ticket = ticket;
_client = new WebClient { Encoding = Encoding.UTF8 };
_client.Headers["Cookie"] = ".V1.Ticket.VersionOne.Web=" + ticket;
}
public List<List<dynamic>> GetResultSets(string querybody)
{
var resultbody = _client.UploadString(_url, "SEARCH", querybody);
return JsonConvert.DeserializeObject<List<List<dynamic>>>(resultbody);
}
}
class Program
{
static void Main(string[] args)
{
var url = "https://versionone-test.acme.com/summer13_demo/query.v1";
var authTicket = "AAEAAGvqd3ylmW0FphkxxxHASSMoCrEa...";
var client = new JsonClient(url, authTicket);
I've just updated that example for you, including making it work with the new OAuth2Client code that Joe Koberg created recently.
The new version of the sample includes stored_credentials.json and client_secrets.json files that have already been set up to work against our public test server at http://www14.v1host.com/v1sdktesting. To see the projects there or modify some of the data, use admin / admin to login.
It includes a simple JsonClient which utilizes Newtonsoft to parse the JSON returned from the server.
It's still located at https://github.com/versionone/versionone-oauth2-examples/blob/master/csharp/YamlClient/Program.cs
Using the JsonClient example looks like this:
IStorage credentials = new Storage.JsonFileStorage(
"../../client_secrets.json", "../../stored_credentials.json");
const string scopes = "query-api-1.0 apiv1";
const string url = "https://www14.v1host.com/v1sdktesting/query.v1";
var client = new JsonClient(credentials, url, scopes);
const string queryBody = #"
from: Scope
select:
- Name
- Workitems.#Count
- Workitems:PrimaryWorkitem.#Count
- Workitems:PrimaryWorkitem[Estimate>'0'].#Count
- Workitems:PrimaryWorkitem[Estimate='0'].#Count
- Workitems:PrimaryWorkitem[Estimate>'0'].Estimate.#Sum
- from: Workitems:PrimaryWorkitem[Estimate>'0']
select:
- Name
- Estimate
";
var resultSets = client.GetResultSets(queryBody).ToArray();
foreach (var result in resultSets[0]) // Rember that query.v1 returns a resultSet of resultSets!
{
Console.WriteLine(result["Name"]);
Console.WriteLine("Total # of workitems: " + result["Workitems.#Count"]);
Console.WriteLine("Total # of Primary workitems: " + result["Workitems:PrimaryWorkitem.#Count"]);
Console.WriteLine("Total # of Estimated Primary workitems: " +
result["Workitems:PrimaryWorkitem[Estimate>'0'].#Count"]);
Console.WriteLine("Total # of Unestimated Primary workitems: " +
result["Workitems:PrimaryWorkitem[Estimate='0'].#Count"]);
Console.WriteLine("Sum of all Estimated Primary workitems: " +
result["Workitems:PrimaryWorkitem[Estimate>'0'].Estimate.#Sum"]);
foreach (var estimatedWorkitem in result["Workitems:PrimaryWorkitem[Estimate>'0']"])
{
Console.WriteLine(estimatedWorkitem["Name"] + " : " + estimatedWorkitem["Estimate"]);
}
Console.WriteLine("\n");
}
Console.Write("Press any key to exit...");
Console.ReadLine();
}
}

Categories

Resources