Microsoft Graph API online meetings DateTimeOffset format - .net-core

I have a simple task which involves creating online meetings using Microsoft Graph API. I'm using the basic sample code from the site, something like this:
var onlineMeeting = new OnlineMeeting
{
StartDateTime = DateTimeOffset.Parse("2019-07-12T21:30:34.2444915+00:00"),
EndDateTime = DateTimeOffset.Parse("2019-07-12T21:30:34.2444915+00:00"),
Subject = "This is the subject"
};
var meeting = await graphClient.Users["userid here"].OnlineMeetings.Request().AddAsync(onlineMeeting);
This unfortunately gives a 400 response with a very obsure reasoning. However, I was able to narrow down the probable cause of the problem: the serialization of the DateTimeOffset properties. For some reason, my requests contain the data in the format like 19/07/12 21:30:34 -07:00", instead of the required format, which is basically the same as the argument provided for DateTimeOffset.Parse().
My question is how can I customize the serialization format in the SDK? And more importantly, why should I do this explicitly, and why can't I find any mention of this in the documentation?

Turns out I have not updated the SDK for a while now and I was using an old version. I updated to the latest version and the problem went away :)

Related

Unable to set TimeSpan based parameter on an Azure Service Bus subscription filter using Microsoft.Azure.ServiceBus library

Using the older "Windows.Azure.ServiceBus" library, I am able to setup a SqlFilter that takes as its parameters a TimeSpan, but when I try the same using the "Microsoft.Azure.ServiceBus" library it fails with the following error:
Object is not of supported type: TimeSpan. Only following types are
supported through HTTP: string,int,long,bool,double,DateTime
What I am trying to do:
I want to have 2 subscriptions on my topic (highPriority, normalPriority)
Messages have a user property called "StartDate"
If StartDate <= 1 day, then it should go to highPriority subscription, else it should go to normalPriority. [i.e (StartDate - sys.EnqueuedDateTimeUtc) <= 24 hours].
Code that works (when using the older .net-framework Windows.Azure.ServiceBus package):
SqlFilter highMessagesFilter =
new SqlFilter("(StartDate-sys.EnqueuedTimeUtc) <= #TimeSpanImmediateWindow");
highMessagesFilter.Parameters.Add("#TimeSpanImmediateWindow", TimeSpan.FromDays(1));
var subscription = SubscriptionClient.CreateFromConnectionString(connectionString,topicName, subName1);
subscription.RemoveRule(RuleDescription.DefaultRuleName);
subscription.AddRule(new RuleDescription()
{
Name = RuleDescription.DefaultRuleName,
Filter = highMessagesFilter,
Action = new SqlRuleAction("set priorityCalc = (StartDate-sys.EnqueuedTimeUtc)")
});
Where as, this code (using: Microsoft.Azure.ServiceBus) doesnt work:
var filter = new SqlFilter("(StartDate-sys.EnqueuedTimeUtc) <= #TimeSpanHoursImmediateWindow");
filter.Parameters.Add("#TimeSpanHoursImmediateWindow",TimeSpan.FromDays(1));
var ruleDescription = new RuleDescription
{
Filter = filter,
Action = new SqlRuleAction(#"
SET HighPriority = TRUE;
SET Window = StartDate - sys.EnqueuedTimeUtc
"),
Name = RuleDescription.DefaultRuleName,
};
await managementClient.UpdateRuleAsync(topicPath,subscriptionName,ruleDescription);
The above code throws the following error:
Object is not of supported type: TimeSpan. Only following types are
supported through HTTP: string,int,long,bool,double,DateTime
If instead of managementClient.UpdateRuleAsync, I try using the following code:
var subClient = new SubscriptionClient(connectionString, topicPath, subscriptionName);
await subClient.RemoveRuleAsync(RuleDescription.DefaultRuleName);
await subClient.AddRuleAsync(ruleDescription);
It fails, with the following error (ServiceBusException):
Message The service was unable to process the request; please retry
the operation. For more information on exception types and proper
exception handling, please refer to
http://go.microsoft.com/fwlink/?LinkId=761101
The microsoft link is to a list of exceptions, and FilterException, but its not!
Here is the stack trace of the 2nd exception:
at
Microsoft.Azure.ServiceBus.Amqp.AmqpSubscriptionClient.OnAddRuleAsync(RuleDescription
description) in
C:\source\azure-service-bus-dotnet\src\Microsoft.Azure.ServiceBus\Amqp\AmqpSubscriptionClient.cs:line
132 at
Microsoft.Azure.ServiceBus.SubscriptionClient.AddRuleAsync(RuleDescription
description) in
C:\source\azure-service-bus-dotnet\src\Microsoft.Azure.ServiceBus\SubscriptionClient.cs:line
499 at UserQuery.Main() in
C:\Users\XXXX\AppData\Local\Temp\LINQPad6_quhgasgl\niqvie\LINQPadQuery.cs:line
82
So my questions are:
Can I use TimeSpan parameters using .net standard library? or will I have to use the older .net framework library if I wanted to use TimeSpans.
Is there a better way to implement what I am trying to do, a way that would work with the newer .net standard library? (FYI: I thought about sending the calculation as the parameter (decimal) and then the parameter would be a double, instead of a TimeSpan). And in fact, thats what I might end up doing.
If the library is throwing an exception stating that TimeSpan is not a supported type, then it's pretty much what you have. Note that the .NET Standard client has two implementations, the ManagementClient and some operations via entity clients, such as subscription client. The latter is implemented using AMQP. ManagementClient is entirely based on HTTP. While it would be ideal to use the AMQP implementation, it's incomplete. I would recommend relying on the ManagementClient. This is likely the reason why modifying rules using a subscription client is throwing an exception.
Regarding a better way - your idea sounds right. As long as it's not a type that the new client doesn't accept. Also, you can raise an issue with the library team at https://github.com/Azure/azure-sdk-for-net/issues if you'd like to know the reason why TimeSpan is no longer supported.

Getting the error "ApiKey invalid" for hotel live prices

I'm trying to get the a list of current hotel prices but I can't get my API Key to work. I've had it for a couple days so I know it isn't too new. I even tried the example in the docs (after fixing the dates):
http://partners.api.skyscanner.net/apiservices/hotels/liveprices/v2/UK/EUR/en-GB/27539733/2016-12-04/2016-12-10/2/1?apiKey=myKey
While it worked for the demo key it wouldn't work for mine. I also tried it on the ec2 micro I'm using for testing with Python and get a response with u'{"errors":["ApiKey invalid"]}':
SKY_SCAN_URL = "http://partners.api.skyscanner.net/apiservices/hotels/liveprices/v2/"
sky_key = get_sky_scan_key()
def get_hotels(request):
entityid = request.GET['entityid']
checkindate = date_formatter(request.GET['start'])
checkoutdate = date_formatter(request.GET['end'])
rooms = request.GET['rooms']
guests = request.GET['guests']
FINAL_SKY_URL = "%s/%s/%s/%s/%s/%s/%s/%s/%s/?apiKey=%s" % (
SKY_SCAN_URL, 'US', 'USD', 'en-US', entityid, checkindate, checkoutdate, guests, rooms, sky_key)
sky_response = requests.get(FINAL_SKY_URL)
This function outputs a get request with a URL like this:
http://partners.api.skyscanner.net/apiservices/hotels/liveprices/v2//US/USD/en-US/20.7983626,-156.3319253-latlong/2016-09-07/2016-09-14/1/1/?apiKey=myKey
Any advice on what the possible issue could be would be awesome, thanks!
Edit:
To be more specific I'm looking for reasons why my API Key is invalid. I'm not familiar with skyscan and while I've added an app from the skyscanner dashboard by clicking the travel api and copied the key into my project and directly into a valid url my key is showing as bad. Are there any additional steps or things that I need to take into account?
I don't know about how you're creating the URL but it seems like it shouldn't be built that way. (most likely due to their misleading documentation)
This:
http://partners.api.skyscanner.net/apiservices/hotels/liveprices/v3/?apiKey=myKey&checkoutdate=2016-09-14&checkindate=2016-09-07&currency=USD&rooms=1&entityid=20.7983626%2C-156.3319253-latlong&local=en-US&market=US&guests=1
Should be:
http://partners.api.skyscanner.net/apiservices/hotels/liveprices/v3/US/USD/en-US/20.7983626,-156.3319253-latlong/2016-09-07/2016-09-14/1/1/?apiKey=myKey
Your code should be something like:
SKY_SCAN_URL = "http://partners.api.skyscanner.net/apiservices/hotels/liveprices/v3/"
FINAL_URL = "%s/%s/%s/%s/%s/%s/%s/%s/%s/?apiKey=%s" % (SKY_SCAN_URL, market, currency, locale, entityid, checkindate, checkoutdate, guests, rooms, apiKey)
sky_response = requests.get(FINAL_URL)
I also suggest you do some tests here.
From their help site as of 17 days ago -
https://support.business.skyscanner.net/hc/en-us/articles/209452689-Why-is-my-API-key-returning-no-results-for-hotels-
"Our Hotels API is currently being reworked, and access is not available at present. Apologies for any inconvenience, when the new API is ready for use we will update the Skyscanner for Business site, so please check back there for updates."
Unclear when this changes.
Since April 2017, skyScanner started re-working their Hotels API, thus stopping all ongoing API calls to LIVE Pricing APIs:
https://support.business.skyscanner.net/hc/en-us/articles/209452689-Why-is-my-API-key-returning-no-results-for-hotels-
Hotels and Flights Cached Pricing and Browse services still working, though I am not sure if it is enough for your business case.
It seems that Skyscanner has updated their Hotels API recently and the documentation can be found here: https://skyscanner.github.io/slate/#hotels-live-prices

ASP.net (VB code behind) JSON parsing facebook Graph API response

net but wanted to try to do this code in ASP.net instead of my normal classic ASP.
I have been trying to find code examples that would show me how to parse out the name & id in a returned JSON from a facebook API Graph call. The JSON return looks like this from Facebook:
{
"data": [
{
"name": "David xxxxxx",
"id": "05121212",
"administrator": true
},
{
"name": "Billy xxxxxxx",
"id": "0005128888"
}
],
"paging": {
"next": "https://graph.facebook.com/xxxxx/members?format=json&limit=5000&offset=5000&__after_id=xxxxx"
}
}
Any examples on how to go about parsing out just the name and id from the JSON response in ASP.net would be awesome!
Thanks,
David
Go for, http://james.newtonking.com/
string response = <your fb data>; // I am lazy :P
JObject obj = JObject.Parse(response);
JArray data = (JArray)obj["data"];
for(int i=0,int len=data.count; i < len ; i++)
{
string name = data[i]["name"].ToString();
string id = data[i]["id"].ToString();
string administrator = string.Empty;
if(data[i]["administrator"]!=null)
{
string administrator = data[i]["administrator"].ToString();
}
}
I think, this code is enough to get you going.
Always check for null as api data may or may not have that value.
Edit: I noticed that you wanted a VB code, sorry. But it may help others, so leaving it here. You can convert the code from any C# to VB convertor.
Regardless of whether or not there is a known library for .NET and Open Graph, Json is Json. The way I see it you have three options:
1) Use Newtonsoft Json. You can install this package using nuget into your ASP.NET project and from there there are lots of places on the web that talk about working with this library. http://james.newtonking.com/ is the home page of the library, there are also posts here.
2) Use .NET Json. Again, lots of info on the web here. I found a pretty good looking post here Parse JSON in C#
3) Use the C# Facebook SDK. The FacebookClient class has the ability to serialize and de-serialize Json. You can also install this library via Nuget. I admit the documentation on the C# SDK is lacking, but none the less it works well. More information about it can be found here: http://blog.prabir.me/category/Facebook-C-SDK.aspx
I hope this helps you down the right path.
-Eric
There are no known supported libraries for .net for the new graph api. https://github.com/facebook-csharp-sdk has a few samples for using .net though.

Grails 2.0 - Upgrading Controller Testing and losing renderArgs and redirectArgs

Problem:
I upgraded from Grails 1.3.7 to Grails 2.0.
I had to then refactor my controller tests to use annotations: #TestFor(controller) and Mock(domain) which took care of a lot of problems.
However, in 1.3.7 controller.renderArgs and controller.redirectArgs were available. This seems to no longer be the case in 2.0 and I am having a difficult time figuring out how to get the data these very convenient variables provided.
It appears that this data will not be provided based off of this Grails Jira posting. The last comment in this post by James Lang, which has no response, is my exact question:
In Grails 2.0 controller unit testing, how can you get to the renderArgs such as action, id, params, etc?
The Jira comments only supply inputs to getting to the response.redirectUrl
Any ideas?
Thanks for the update and the link to the post by Graeme.
Our solution to the problem was to metaclass the controller to get to these variables.
I created corresponding member variables and then added the following code to the setup of the unit test:
controller.metaClass.redirect = { Map map ->
redirectAction = map.action
redirectID = map.id
redirectUrl = map.url
}
controller.metaClass.render = {Map map ->
renderView = map.view
renderModel = map.model
}
At the moment it appears you can't. I saw this forum post where Graeme replied and mentioned it would take a feature request.

Flex slow first Http request

When i use loader.load(request); for the first time, my flex freeze for 10 secondes before posting the data (i can see the web server result in real time).
However if redo a similar POST with other data but same request.url, it's instantaneous.
// Multi form encoded data
variables = new URLVariables();
variables.user = "aaa";
variables.boardjpg = new URLFileVariable(data.boardBytes, "foo.jpg");
request = new URLRequestBuilder(variables).build();
request.url = "http://localhost:8000/upload/";
loader.load(request);
How can i see what is taking so long ?
Thanks !
Ok, this is an old question, anyway I find it searching for other things so quick adding this
URLFileVariables nor URLRequestBuilder are core classes in AS3, so I guess you're using some custom library to build your request. I don't know which library you use, but it seems that the purpose is to serialize some binary data to build a POST. Serializing usually takes some times the first time (lookup initialization and the like) and goes faster next, a well known example is Remoting in his different flavours

Resources