Getting the query result of LUIS - c#

I have created a LUIS account and did everything that was needed.
I have written the following code and got the result from LUIS.
I need to know how to save the result of my query to a variable, using which I would like to search the database or web.
Below is the code..
static async void MakeRequest(string qz) {
var client = new HttpClient();
var queryString = HttpUtility.ParseQueryString(string.Empty);
var luisAppId = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
var endpointKey = "XXXXXXXXXXXX";
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", endpointKey);
// The "q" parameter contains the utterance to send to LUIS
queryString["q"] = qz;
// These optional request parameters are set to their default values
queryString["timezoneOffset"] = "0";
queryString["verbose"] = "false";
queryString["spellCheck"] = "false";
queryString["staging"] = "false";
var endpointUri = "https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/" + luisAppId + "?" + queryString;
var response = await client.GetAsync(endpointUri.);
var strResponseContent = await response.Content.ReadAsStringAsync();
// Display the JSON result from LUIS
Console.WriteLine(strResponseContent.ToString());
}
And also here is the query result.
{
"query": "the best resturant in Paris",
"topScoringIntent": {
"intent": "city",
"score": 0.436210483
},
"entities": [
{
"entity": "paris",
"type": "city",
"startIndex": 22,
"endIndex": 26,
"score": 0.7153605
}
]
}
Now I want to save this
"entity": "paris",
"type": "city",
to a variable. Kindly guide me as I am completely new to MS LUIS.
example:
string result = "paris" /// which the value should be taken from luis query
string type = "city" /// which the value should be taken from luis query

One option is to reference Newtonsoft.Json NuGet package to your project.
Then you may create two classes (feel free to change the name)
public class LuisExtractionLuisResult
{
public List<LuisEntity> entities { get; set; }
}
public class LuisEntity
{
public string entity { get; set; }
public string type { get; set; }
}
Then one example of use is
var target = JsonConvert.DeserializeObject<LuisExtractionLuisResult>(strResponseContent);
requested values are then retrieved by:
string result = target.entities[0].entity;
string type = target.entities[0].type;
And one more question, if in the query we have more than one entities.
how to get that as well?
foreach(LuisEntity oneEntity in target.entities)
{
string result oneEntity.entity;
string type = oneEntity.type;
}

Related

How to read JSON data column in Entity Framework?

I created a database with JSON columns in mysql.
API defined in Swagger.
Writing JSON to the database works without problems, but when reading, the value of the JSON field is shown as an escaped string and not JSON
Here is part of model:
/// <summary>
/// Gets or Sets Doc
/// </summary>
[DataMember(Name="doc")]
public Dictionary<string, string> Doc { get; set; }
I also tried with string type and Dictionary<string, object> but unsuccessful.
Get method is here:
public virtual IActionResult GetDataById([FromRoute][Required]int? dataId, [FromRoute][Required]string jsonNode)
{
if(_context.Data.Any( a => a.Id == dataId)) {
var dataSingle = _context.Data.SingleOrDefault( data => data.Id == dataId);
return StatusCode(200, dataSingle);
} else {
return StatusCode(404);
}
}
}
And resulting JSON resposne looks like this one:
{
"field1": "value1",
"field2": "value2",
"doc": "{\"key1\":\"value1\",\"key2\":\"value2\",\"key3\":{\"subkey3-1\":\"value3-1\",\"subkey3-2\":\"value3-2\"}}"
}
but correct JOSN should be linke this one:
{
"field1": "value1",
"field2": "value2",
"doc": {
"key1":"value1",
"key2":"value2",
"key3":{
"subkey3-1":"value3-1",
"subkey3-2":"value3-2"
}
}
}
If I try to return just "Doc" (JSON) field, response JSON is properly formatted.
I tried different serialization/deserialization but unsuccessful.
If I have public Dictionary<string, string> Doc { get; set; } in Model I got error:
fail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection id "0HM1VN0F0I0IM", Request id "0HM1VN0F0I0IM:00000001": An unhandled exception was thrown by the application.
System.InvalidOperationException: The property 'Data.Doc' is of type 'Dictionary<string, string>' which is not supported by current database provider. Either change the property CLR type or ignore the property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'
and for public string Doc { get; set; } in Model I got "doc" field value as escaped string as I mention above.
What would be the best way to go about this?
A few days later I found a resolution.
You need a one helper method that converts a string to object, exactly JObject if you use Json.NET - Newtonsoft.
public static JObject getJsonOutOfData (dynamic selectedData)
{
var data = JsonConvert.SerializeObject(selectedData);
var jsonData = (JObject)JsonConvert.DeserializeObject<JObject>(data);
if (selectedData.Doc != null) {
JObject doc = JObject.Parse(selectedData.Doc);
JObject docNode = JObject.Parse("{\"doc\":" + doc.ToString() + "}");
var jsonDoc = (JObject)JsonConvert.DeserializeObject<JObject>(docNode.ToString());
jsonData.Property("doc").Remove();
jsonData.Merge(jsonDoc, new JsonMergeSettings
{
MergeArrayHandling = MergeArrayHandling.Union
});
}
return jsonData;
}
and call it in the IActionResult method
public virtual IActionResult GetDataById([FromRoute][Required]int? accidentId, [FromRoute][Required]string jsonNode)
{
if (_context.Data.Any( a => a.Id == accidentId)) {
var accidentSingle = _context.Data.SingleOrDefault( accident => accident.Id == accidentId);
var result = getJsonOutOfData(accidentSingle);
return StatusCode(200, result.ToString());
} else {
return StatusCode(404);
}
}
In order to use unescaped JSON in POST/PUT requests, you should have a string type as a property type of JSON filed in the database model, and create an additional "request" model and set JSON property as "Object" type:
Database Model:
[DataMember(Name="doc")]
public string Doc { get; set; }
Request Model:
[DataMember(Name="doc")]
public Object Doc { get; set; }
For example Create model looks like:
public virtual IActionResult CreateData([FromBody]DataCreateRequest body)
{
var accidentObject = new Data() {
ColumnOne = body.ColumnOne,
ColumnTwo = body.ColumnTwo,
ColumnThree = body.ColumnThree,
Doc = (bodyDoc != null) ? body.Doc.ToString() : "{}"
};
_context.Data.Add(accidentObject);
_context.SaveChanges();
return StatusCode(200, getJsonOutOfData(accidentObject));
}

How can I print Json values in a gridview?

I am trying to print values from a Json string in a gridview with C# using Visual Studio 2017. The problem is that I can't get the specific Value to a single word.
Here is my code:
string link = #"http://alexander.*************/test.php";
string json = new WebClient().DownloadString(link);
JObject jObject = JObject.Parse(json);
I want to print both Values from "Name" in the gridview, but how?
The Names has to put in this Item list:
myItems = (array?);
string test2 = test1.ToString(Formatting.Indented);
ArrayAdapter<string> adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, myItems);
GridviewCoins.Adapter = adapter;
And finally the json string is:
{
"Coins": [[{
"Name": "007",
"Id": "5294",
}], [{
"Name": "1337",
"Id": "20824",
}
There is a couple problems here, first is that your Coins Property is an array of arrays, and that you jsonObject is not complete it should look like :
"{ "Coins": [[{ "Name": "007", "Id": "5294", } ], [{ "Name": "1337", "Id": "20824", }]]}";
That said if this is a copy paste error I would do some thing like:
public IEnumerable<Coin> GetCoins(string json)
{
var jObject = JObject.Parse(json);
var coinPropery = jObject["Coins"] as JArray;
var coins = new List<Coin>();
foreach (var property in coinPropery)
{
var propertyList = JsonConvert.DeserializeObject<List<Coin>>(property.ToString());
coins.AddRange(propertyList);
}
return coins;
}
and the coin object:
public class Coin
{
public int Id { get; set; }
public string Name { get; set; }
}
when then you have a c# object and you can do what ever you want with it.
EDIT:
You can add to gridview by following Click here

How read value from json with out using json.net

I got a response from a webservice as shown below
{
"header": {
"sourceId": "1002",
"mndAction": "CREATE",
"msgId": "msg10022",
"errMsg": null,
"txnStatusFlg": "1",
"successMsg": "SUCCESS"
},
"response": {"responseString": "Required Data"}
}
I want to get the value of responseString from the above json data.
For the response
{"Status":"success","DocRepoId":225,"Details":"success",
"ErrorCode":"","responseString": "Required Data"}
I used the code
var deserializer = new JavaScriptSerializer();
var someObject = deserializer.Deserialize<Dictionary<string, string>>
(response);
string responseString= someObject["responseString"].ToString();
to get the value of responseString but in this case its showing error.
I'm looking for a solution without using json.net or anything similar.
My project is on .net version 3.5.
Here it goes an example of what i told you in comment.
Using this classes:
class Test
{
public Response Response { get; set; }
}
class Response
{
public string ResponseString { get; set; }
}
You can get what you want with this code:
JavaScriptSerializer s = new JavaScriptSerializer();
string json = #"{
""header"": {
""sourceId"": ""1002"",
""mndAction"": ""CREATE"",
""msgId"": ""msg10022"",
""errMsg"": null,
""txnStatusFlg"": ""1"",
""successMsg"": ""SUCCESS""
},
""response"": { ""responseString"": ""Required Data""}
}";
Test t = s.Deserialize<Test>(json);
var responseString = t.Response.ResponseString;

A better way to deserialize JSON?

I am posting to an API that may return either 1 of the following 2 formats of JSON strings:
{
"MessageType": 6,
"Message": "Unable to SAVE new record. Invalid posted data."
}
or
{
"Model": {
"Id": "1-6Q0RZ9",
...
},
"ResponseResult": {
"MessageType": 10,
"Message": "Successfully saved, Record Id = 1-6Q0RZ9"
}
}
I need to retrieve the results from MessageType and have tried every if condition I can think of to read the results, because the syntax or retrieving the key:value is different for each JSON string, and there are no other flags to trigger one or the other. So the code I used is:
string result = eml.PostData("API/Save", dataJSON.ToString());
var returnresult = new JavaScriptSerializer().Deserialize<dynamic>(result);
try {
var responseresults = returnresult["ResponseResult"];
rr = responseresults["MessageType"];
rrtxt = responseresults["Message"];
} catch (Exception ex) {
rr = returnresult["MessageType"];
rrtxt = returnresult["Message"];
}
Which works great. If there is a valid Db post it returns the second JSON which is parsed correctly by the TRY statement, if not it throws a "key not found" error and parses the returned string in the CATCH statement (the first JSON example). Obviously this is horrible code but I cannot think of another way to do this, and I was wondering if anyone had suggestions? (please?)
Thanx in advance.
How about deserializing the response to an object with all of the properties on each return type and then just checking the values?
public class ReturnObject
{
public YourModel Model {get;set;}
public ResultObject ResponseResult {get;set;}
public int? MessageType {get;set;}
public string Message {get;set;}
}
string result = eml.PostData("API/Save", dataJSON.ToString());
var returnresult = new JavaScriptSerializer().Deserialize<ReturnObject>(result);
{
if(returnresult.MessageType.HasValue)
{
var messageType = returnResult.MessageType.Value;
etc etc.
}
}

How can I catch a specific value with JSON Deserialize?

I catch a JSON with .NET:
string result = json_serializer.Deserialize(myJSON);
well the structure of JSON is such as:
result
data[0]
user
bio
name
nickname
data[1]
user
bio
name
nickname
data[2]
user
bio
name
nickname
and I'd like to get only the first nickname (as string) that have some value: I mean, it is not null and is not empty.
How can I do it?
From what I understand from your question, you would want something like this,
public string FirstUserNickname(string JsonUserInfo)
{
JavaScriptSerializer JsonSerializer = new JavaScriptSerializer();
ResultData Results = JsonSerializer.Deserialize<ResultData>(JsonUserInfo);
foreach (UserInfo UserInfo in Results.result)
{
if (string.IsNullOrEmpty(UserInfo.nickname))
return UserInfo.nickname;
}
return null;
}
public class ResultData
{
public List<UserInfo> result;
}
public class UserInfo
{
public string bio;
public string name;
public string nickname;
}
This will achieve your goal and is a strongly typed approach, using the JavaScriptSerializer class from the System.Web.Extensions assembly, more info can be found here.
You can use Linq to JSON (search NuGet for Newtonsoft Json). Assume your JSON looks like:
{ "result": [ { "bio": "foo", "name": "Robin", "nickname": "Moll" },
{ "bio": "bar", "name": "Ted", "nickname": "DoctorZ" },
{ "bio": "moo", "name": "Barney", "nickname": "Wait4it" } ]
}
Then getting name of first user:
JObject jo = JObject.Parse(json);
var name = (string)jo["result"][0]["name"]; // Robin
Of course if it is possible that you will not have any users, then you should verify that user exists:
JObject jo = JObject.Parse(json);
var user = jo["result"].FirstOrDefault();
if (user != null)
name = (string)user["name"];
Using Linq to JSON you can deserialize to .net objects, like so:
Result deserializedResult = JsonConvert.DeserializeObject<Result>(json);
After that you can use LINQ to query the objects:
User nicknameduser = deserializedResult.Users
.FirstOrDefault(r => !string.IsNullOrEmpty(r.nickname))
if (nicknameduser == null) return null;
return nicknameduser.nickname;

Categories

Resources