Microsoft Cognitive Services Web Search API - DeSerialization Issues - botframework

I want to learn Cognitive Services Web Search APIs so I started creating a bot application . I already have a account sub- key and other required information also I read many articles and watch build 2016 videos on this as well.I am having trouble while deserializing the result .
I am not able to find the proxy class that I can use to do that .
The url I am using is https://api.cognitive.microsoft.com/bing/v5.0/search/
and I found a proxy class for previous api version . Can anybody tell me how to get proxy class of the api request / response in VS 2015 for these service.
My Code look like this:
string BingSearchUrl = "https://api.cognitive.microsoft.com/bing/v5.0/search/";
const string bingKey = "Key";
public static async Task<string> Search(string query)
{
var client = HttpClientFactory.Create();
var queryString = BingSearchUrl + "?q=" + query + "&count=10";
// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", bingKey);
client.DefaultRequestHeaders.Add("Accept", "application/json");
// Request parameters
string r = await client.GetStringAsync(queryString);
var jsonResult = JsonConvert.DeserializeObject<Bing.ExpandableSearchResult>(r);
return jsonResult.Web.First().Title;

Try below code
public string BingSearchUrl = "https://api.cognitive.microsoft.com/bing/v5.0/search/";
const string bingKey =[KEY];
public async void Search()
{
var client = new HttpClient();
var queryString = HttpUtility.ParseQueryString(string.Empty);
// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", bingKey);
// Request parameters
queryString["q"] = "microsoft";
queryString["count"] = "10";
queryString["offset"] = "0";
queryString["mkt"] = "en-us";
queryString["safeSearch"] = "Moderate";
var uri = "https://api.cognitive.microsoft.com/bing/v5.0/news/search?" + queryString;
var response = await client.GetStringAsync(uri);
var jsonResult = JsonConvert.DeserializeObject<BingJson>(response);
string title = jsonResult.value[0].name.ToString();
}
With the jsonResult.value[0] you can loop through the results. First results is at [0] position.
I Created a model class looking at the bing search response json. It looks like,
public class BingJson
{
public string _type { get; set; }
public Instrumentation instrumentation { get; set; }
public string readLink { get; set; }
public int totalEstimatedMatches { get; set; }
public Value[] value { get; set; }
}
public class Instrumentation
{
public string pingUrlBase { get; set; }
public string pageLoadPingUrl { get; set; }
}
public class Value
{
public string name { get; set; }
public string url { get; set; }
public string urlPingSuffix { get; set; }
public Image image { get; set; }
public string description { get; set; }
public About[] about { get; set; }
public Provider[] provider { get; set; }
public DateTime datePublished { get; set; }
public string category { get; set; }
}
public class Image
{
public Thumbnail thumbnail { get; set; }
}
public class Thumbnail
{
public string contentUrl { get; set; }
public int width { get; set; }
public int height { get; set; }
}
public class About
{
public string readLink { get; set; }
public string name { get; set; }
}
public class Provider
{
public string _type { get; set; }
public string name { get; set; }
}

With this model, I am able to get the desired result. The Model which is presented in the other answer is not working in my case.
namespace BingSearchBot
{
public class RootObject
{
public string _type { get; set; }
public WebPages webPages { get; set; }
public RelatedSearches relatedSearches { get; set; }
public RankingResponse rankingResponse { get; set; }
}
public class WebPages
{
public string webSearchUrl { get; set; }
public int totalEstimatedMatches { get; set; }
public List<Value> value { get; set; }
}
public class Value
{
public string id { get; set; }
public string name { get; set; }
public string url { get; set; }
public List<About> about { get; set; }
public string displayUrl { get; set; }
public string snippet { get; set; }
public List<DeepLink> deepLinks { get; set; }
public string dateLastCrawled { get; set; }
public List<SearchTag> searchTags { get; set; }
}
public class About
{
public string name { get; set; }
}
public class DeepLink
{
public string name { get; set; }
public string url { get; set; }
public string snippet { get; set; }
}
public class SearchTag
{
public string name { get; set; }
public string content { get; set; }
}
public class Value2
{
public string text { get; set; }
public string displayText { get; set; }
public string webSearchUrl { get; set; }
}
public class RelatedSearches
{
public string id { get; set; }
public List<Value2> value { get; set; }
}
public class Value3
{
public string id { get; set; }
}
public class Item
{
public string answerType { get; set; }
public int resultIndex { get; set; }
public Value3 value { get; set; }
}
public class Mainline
{
public List<Item> items { get; set; }
}
public class RankingResponse
{
public Mainline mainline { get; set; }
}
}

Related

Receiving Multi-part form data in dotnet core web API

I'm working on an web API, where it needs to receive the multi-part form data with in a model. As of now it's not receiving the request and showing the Bad request When I tried from the Postman.
My model :
public class InvoiceDetails
{
public int? po_id { get; set; }
public DateTime created_date { get; set; }
public string grn_status { get; set; }
public int utilization_amount { get; set; }
public int currency_id { get; set; }
public string currency_code { get; set; }
public string currency_symbol { get; set; }
[FromForm(Name = "invoice_file")]
public List<IFormCollection> invoice_file { get;set;}
[FromForm(Name = "other_files")]
public List<IFormCollection> other_files { get; set; }
}
In the above class/model "invoice_file" and "other_files" can have multiple file uploads so I made it List.
My Action Method :
[HttpPost]
[Route("CreateInvoice")]
public IActionResult CreateInvoice([FromForm]InvoiceDetails idobj )
{
//var modelData = Request.Form["invoice_file"];
Response resobj = new Response();
try
{
if (idobj.invoice_file.Count > 0)
{
resobj = _dataContext.AddInvoice(idobj);
if (resobj.flag == true)
{
Upload(idobj);
}
}
else
{
resobj.flag = false;
resobj.message = "please upload atleast one invioce file";
}
}
catch (Exception ex)
{
}
return Ok(resobj);
}
How can I make the action method or model, in such a way that user can upload the model with multiple files to the properties other_files & invoice_file.
Reference of postman Image
As CodeCaster says,add Content-Type:multipart/form-data; and change List<IFormCollection> to List<IFormFile>.It is not changing the whole model to List.So you can also retrieve other information which exists in your model with idobj.xxx.Change
public class InvoiceDetails
{
public int? po_id { get; set; }
public DateTime created_date { get; set; }
public string grn_status { get; set; }
public int utilization_amount { get; set; }
public int currency_id { get; set; }
public string currency_code { get; set; }
public string currency_symbol { get; set; }
[FromForm(Name = "invoice_file")]
public List<IFormCollection> invoice_file { get;set;}
[FromForm(Name = "other_files")]
public List<IFormCollection> other_files { get; set; }
}
to
public class InvoiceDetails
{
public int? po_id { get; set; }
public DateTime created_date { get; set; }
public string grn_status { get; set; }
public int utilization_amount { get; set; }
public int currency_id { get; set; }
public string currency_code { get; set; }
public string currency_symbol { get; set; }
[FromForm(Name = "invoice_file")]
public List<IFormFile> invoice_file { get; set; }
[FromForm(Name = "other_files")]
public List<IFormFile> other_files { get; set; }
}
result:
IFormCollection is used to retrieve all the values from posted form data.refer to the official document.
If you want to use c,you can try to use it,you can do like this
public IActionResult CreateInvoice([FromForm]IFormCollection idobj)
and you need to get the data you want to foreach keys of IFormCollection,so public List<IFormCollection> invoice_file { get;set;} is better than use IFormCollection.

Why Entity Framework replaces provided value with a new incremental value

I'm trying to work my way through a Dot Net Core MVC project, but I am facing a problem I couldn't solve.
And honestly, I didn't know what to search for.
The project is a simple vehicle registry,
Each vehicle has a Make, a Model, a some Features.
Here are the domain models:
public class Make
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Model> Models { get; set; }
public Make()
{
Models=new Collection<Model>();
}
}
public class Model
{
public int Id { get; set; }
public string Name { get; set; }
public Make Make { get; set; }
public int MakeId { get; set; }
public Model()
{
Make=new Make();
}
}
public class Feature
{
public int Id { get; set; }
public string Name { get; set; }
}
[Table(name:"VehicleFeatures")]
public class VehicleFeature
{
public int VehicleId { get; set; }
public int FeatureId { get; set; }
public Feature Feature { get; set; }
public Vehicle Vehicle { get; set; }
public VehicleFeature()
{
Feature=new Feature();
Vehicle=new Vehicle();
}
}
public class Vehicle
{
public int Id { get; set; }
public Model Model { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ModelId { get; set; }
public ICollection<VehicleFeature> VehicleFeatures { get; set; }
public string ContactName { get; set; }
public string ContactPhone { get; set; }
public string ContactEmail { get; set; }
public DateTime LastUpdate { get; set; }
public bool IsRegistered { get; set; }
public Vehicle()
{
Model=new Model();
VehicleFeatures=new Collection<VehicleFeature>();
}
}
The problem is that when I send the following request to the corresponding controller, EF is replacing the provided value with a new incremental value.
The request I send:
{
"ModelId":10,
"VehicleFeatures":[
{"featureId":45},
{"featureId":46}
],
"ContactName":"Alice",
"ContactPhone":"1234",
"ContactEmail":"Alice#local",
"LastUpdate":"1980-01-01",
"IsRegistered":true
}
And this is what happens:
The controller receives correct values,
Correct values are added to the context,
And then suddenly all hell breaks loose.
This is the controller code:
[HttpPost]
public async Task<IActionResult> CreateVehicle([FromBody] Vehicle v)
{
context.Vehicles.Add(v);
await context.SaveChangesAsync();
return Ok(v.ModelId);
}
What am I missing here?

Parsing a google directions json

I am working with google directions Api...But I am facing problems for read the Json response...Does Someone know about this Api and can help me?
I need get all route points to draw my polyline...which datas is important to get for it? How can I receive and parse it?
This is a json as example
https://maps.googleapis.com/maps/api/directions/json?origin=-22.8895625,-47.0714089&destination=-22.892376,-47.027553&key=
my code that doesn't work...
public static async Task<List<Model.Localizacao>> GetDirectionsAsync(Localizacao locUser, Localizacao locLoja)
{
using (var client = new HttpClient())
{
try
{
List<Model.Localizacao> lstLoc = new List<Model.Localizacao>();
var json = await client.GetStringAsync("https://maps.googleapis.com/maps/api/directions/json?origin=" + locUser.latitude + "," + locUser.longitude + "&destination="+ locLoja.latitude+","+locLoja.longitude+"&key="+ GOOGLEMAPSKEY);
// json = json.Substring(json.IndexOf('['));
// json = json.Substring(0, json.LastIndexOf(']') + 1);
lstLoc = JsonConvert.DeserializeObject<List<Model.Localizacao>>(json);
return lstLoc;
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
return null;
}
}
}
I really need a help
I have searched and the results hasn't helped me yet
its a xamarin forms project
Thank you
Don't try to pull out part of the json, deserialize the whole thing and grab the data you need from the C# object graph.
You can use json2csharp.com to generate a C# class structure.
I pasted in the json you linked to and it generated the following:
public class GeocodedWaypoint
{
public string geocoder_status { get; set; }
public string place_id { get; set; }
public List<string> types { get; set; }
}
public class Northeast
{
public double lat { get; set; }
public double lng { get; set; }
}
public class Southwest
{
public double lat { get; set; }
public double lng { get; set; }
}
public class Bounds
{
public Northeast northeast { get; set; }
public Southwest southwest { get; set; }
}
public class Distance
{
public string text { get; set; }
public int value { get; set; }
}
public class Duration
{
public string text { get; set; }
public int value { get; set; }
}
public class EndLocation
{
public double lat { get; set; }
public double lng { get; set; }
}
public class StartLocation
{
public double lat { get; set; }
public double lng { get; set; }
}
public class Distance2
{
public string text { get; set; }
public int value { get; set; }
}
public class Duration2
{
public string text { get; set; }
public int value { get; set; }
}
public class EndLocation2
{
public double lat { get; set; }
public double lng { get; set; }
}
public class Polyline
{
public string points { get; set; }
}
public class StartLocation2
{
public double lat { get; set; }
public double lng { get; set; }
}
public class Step
{
public Distance2 distance { get; set; }
public Duration2 duration { get; set; }
public EndLocation2 end_location { get; set; }
public string html_instructions { get; set; }
public Polyline polyline { get; set; }
public StartLocation2 start_location { get; set; }
public string travel_mode { get; set; }
public string maneuver { get; set; }
}
public class Leg
{
public Distance distance { get; set; }
public Duration duration { get; set; }
public string end_address { get; set; }
public EndLocation end_location { get; set; }
public string start_address { get; set; }
public StartLocation start_location { get; set; }
public List<Step> steps { get; set; }
public List<object> traffic_speed_entry { get; set; }
public List<object> via_waypoint { get; set; }
}
public class OverviewPolyline
{
public string points { get; set; }
}
public class Route
{
public Bounds bounds { get; set; }
public string copyrights { get; set; }
public List<Leg> legs { get; set; }
public OverviewPolyline overview_polyline { get; set; }
public string summary { get; set; }
public List<object> warnings { get; set; }
public List<object> waypoint_order { get; set; }
}
public class RootObject
{
public List<GeocodedWaypoint> geocoded_waypoints { get; set; }
public List<Route> routes { get; set; }
public string status { get; set; }
}

ServiceStack validators not firing

I am trying to use fluent validation in ServiceStack. I've added the validation plugin and registered my validator.
Plugins.Add(new ValidationFeature());
container.RegisterValidators(typeof(CreateLeaveValidator).Assembly);
I have implemented a validator class for my service model:
public class CreateLeaveValidator : AbstractValidator<CreateLeave>
{
public CreateLeaveValidator()
{
RuleFor(cl => cl.StudentId).NotEmpty();
RuleFor(cl => cl.LeaveDepart).NotEmpty().GreaterThan(DateTime.Now).WithMessage("Leave must begin AFTER current time and date.");
RuleFor(cl => cl.LeaveReturn).NotEmpty().GreaterThan(cl => cl.LeaveDepart).WithMessage("Leave must end AFTER it begins.");
RuleFor(cl => cl.ApprovalStatus).Must( status => ( ("P".Equals(status)) || ("C".Equals(status)) || ("A".Equals(status)) || ("D".Equals(status)) ) );
}
}
Service Model:
[Route("/leaves", "POST")]
public class CreateLeave : IReturn<LeaveResponse>, IUpdateApprovalStatus
{
public int StudentId { get; set; }
public DateTime RequestDate { get; set; }
public DateTime LeaveDepart { get; set; }
public DateTime LeaveReturn { get; set; }
public string Destination { get; set; }
public string HostRelationship { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Postal { get; set; }
public string Hostphone { get; set; }
public string Cellphone { get; set; }
public string Transport { get; set; }
public string Driver { get; set; }
public string Companions { get; set; }
public string Reason { get; set; }
public string ApprovalStatus { get; set; }
public DateTime ApprovalDate { get; set; }
public string ApprovalComment { get; set; }
public string ApprovalReason { get; set; }
public int ApprovalUser { get; set; }
}
But when I create a request with no StudentId or an invalid ApprovalStatus, the validator does not appear to fire and catch the invalid request.
How can I go about troubleshooting the cause of this?
UPDATE: Correction it appears validators are working with my actual service but not in my unit tests. I'm guessing I must not be configuring my apphost correctly in the unit test setup. Here's my test constructor:
public LeaveTests()
{
Licensing.RegisterLicense(#"[license key]");
appHost = new BasicAppHost(typeof(ApiServices).Assembly).Init();
ServiceStack.Text.JsConfig.DateHandler = ServiceStack.Text.DateHandler.ISO8601;
appHost.Plugins.Add(new ValidationFeature());
appHost.Container.RegisterValidators(typeof(CreateLeaveValidator).Assembly);
}
ServiceStack Validation filters are executed in a Global Request Filter which require a full integration test to run, e.g:
public class MyIntegrationTests
{
ServiceStackHost appHost;
public MyIntegrationTests()
{
appHost = new AppHost()
.Init()
.Start("http://localhost:8000/");
}
[OneTimeTearDown] void OneTimeTearDown() => appHost.Dispose();
[Test]
public void Execute_validation_filters()
{
var client = new JsonServiceClient("http://localhost:8000/");
try
{
var response = client.Post(new CreateLeave { ... });
}
catch(WebServiceException ex)
{
//...
}
}
}

RestSharp - WP7 - Cannot deserialize XML to a list

I use RestSharp in my Windows Phone 7.1 project.
I have a response in XML format here:
https://skydrive.live.com/redir.aspx?cid=0b39f4fbbb0489dd&resid=B39F4FBBB0489DD!139&parid=B39F4FBBB0489DD!103&authkey=!AOdT-FiS6Mw8v5Y
I tried to deserialize that response to a class:
public class fullWall
{
public _user user { get; set; }
public int numberOfFriend { get; set; }
public int numberOfPhoto { get; set; }
public List<timhotPhotos> timhotPhotos { get; set; }
public fullWall()
{
timhotPhotos = new List<timhotPhotos>();
}
}
All properties are ok except the timhotPhotos list, as you can see here:
timhotPhotos class:
public class timhotPhotos
{
public string id { get; set; }
public string title { get; set; }
public string description { get; set; }
public string url { get; set; }
public double width { get; set; }
public double height { get; set; }
public DateTime createdDate { get; set; }
public _user user { get; set; }
public int numOfComment { get; set; }
public int numOfRate { get; set; }
public int numOfView { get; set; }
public bool rated { get; set; }
}
Where am I wrong?
You'll have to change the default XML deserializer to the DotNetXmlDeserializer, like this:
RestClient client;
client.AddHandler("application/xml", new DotNetXmlDeserializer());
Then, add the XmlElement attribute to the List<timhotPhotos> timhotPhotos property like this:
public class fullWall
{
public _user user { get; set; }
public int numberOfFriend { get; set; }
public int numberOfPhoto { get; set; }
[System.Xml.Serialization.XmlElement()]
public List<timhotPhotos> timhotPhotos { get; set; }
public fullWall()
{
timhotPhotos = new List<timhotPhotos>();
}
}
Now it should work fine!

Resources