I am wondering if anyone can assist me, I am having a problem with power bi. What I am trying to do is push some data into Power BI. I am finding it difficult to find an approach were a user can enter there user name and password and then I will be able to push data into the Power BI account.
I am getting stuck at the first hurdle of getting an Access Token. I just keeping bad request. I have also tried getting-started-for-dotnet which for some strange reason I can also not get to work.
Error given is: The remote server returned an error: (401) Unauthorized.
Registered as Web application
public class PowerBICreds
{
public string resourceUri { get; set; }
public string clientID { get; set; }
public string grantType { get; set; }
public string username { get; set; }
public string password { get; set; }
public string scope { get; set; }
public string clientSecret { get; set; }
public string loginAddress { get; set; }
public string baseurl { get; set; }
}
public static string AccessToken(PowerBICreds Creds)
{
StringBuilder Httpbody = new StringBuilder();
Httpbody.Append("resource=" + HttpUtility.UrlEncode(Creds.resourceUri));
Httpbody.Append("&client_id=" + HttpUtility.UrlEncode(Creds.clientID));
Httpbody.Append("&grant_type=" + HttpUtility.UrlEncode(Creds.grantType));
Httpbody.Append("&username=" + HttpUtility.UrlEncode(Creds.username));
Httpbody.Append("&password=" + HttpUtility.UrlEncode(Creds.password));
Httpbody.Append("&scope=" + HttpUtility.UrlEncode(Creds.scope));
Httpbody.Append("&client_secret=" + HttpUtility.UrlEncode(Creds.clientSecret));
using (WebClient web = new WebClient())
{
web.Headers.Add("client-request-id", Guid.NewGuid().ToString());
web.Headers.Add("return-client-request-id", "true");
string jsonstring = web.UploadString(Creds.loginAddress, Httpbody.ToString());
dynamic result = JsonConvert.DeserializeObject(jsonstring);
try
{
return result.access_token;
}
catch
{
}
return null;
}
}
Update when I try the sample to show how to use the Power BI API provided by Mircosoft here https://github.com/PowerBI/getting-started-for-dotnet
Additional technical information:
Correlation ID: f1281ec2-4e09-41e6-8847-3acfd3eb7922
Timestamp: 2015-12-04 22:48:58Z
AADSTS65005: The client application has requested access to resource 'https://analysis.windows.net/powerbi/api'. This request has failed because the client has not specified this resource in its requiredResourceAccess list.
The error you got when using our sample application may mean that the app you registered with AAD doesn't request any permission for Power BI. Try using our new app registration page at http://dev.powerbi.com/apps. If you just want to push data into Power BI, you just need the dataset read/write permission.
Related
I am using Duende Identity server and I have an external authentication provider lets say google. While logging into google we get tokens from google which we can make use of calling some google API's.
I need to return the google token also to the client side(Angular/WPF/MVC etc) through Duende token endpoint.
I can see from the code that Duende token endpoint response has a Custom property, but I have no clue how or from where I can insert my values.
From Duende Source Code
internal class ResultDto
{
public string id_token { get; set; }
public string access_token { get; set; }
public int expires_in { get; set; }
public string token_type { get; set; }
public string refresh_token { get; set; }
public string scope { get; set; }
[JsonExtensionData]
public Dictionary<string, object> Custom { get; set; }
}
I would like to see some code snippets or direction on how to add values to this Custom property by existing Duende functionality.
If you need to customize token response you can ICustomTokenResponseGenerator (It is for identity server 3, if you are using version 4 and above I am not sure but it should be ITokenResponseGenerator):
class CustomTokenResponseGenerator : ICustomTokenRequestValidator
{
public Task<TokenResponse> GenerateAsync(ValidatedTokenRequest request, TokenResponse response)
{
response.Custom.Add("custom_field", "custom data");
return Task.FromResult(response);
}
}
and then add it with factory:
factory.CustomTokenResponseGenerator = new Registration<ICustomTokenResponseGenerator, CustomTokenResponseGeneratorService>();
I would like to start by saying that I am not a developer and this is my very first time writing a code to this extend of complication (at least to me). Any help/guidance would be much appreciated.
The idea of this program is to retrieve the employee user ID (or signature) from an API URL once the name has been entered.
I created a folder called WebAPI which will access the API and retrieve the needed information. (please see the code)
namespace TimeSheets_Try_11.Controllers
{
class WebAPI
{
public string Getsignature(string name)
{
var cookies = FullWebBrowserCookie.GetCookieInternal(new Uri(StaticStrings.UrlIora), false);
WebClient wc = new WebClient();
wc.Encoding = System.Text.Encoding.UTF8;
wc.Headers.Add("Cookie:" + cookies);
wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
string uri = "";
uri = StaticStrings.UrlIora + name;
var response = wc.DownloadString(uri);
Employeename status = JsonConvert.DeserializeObject<Employeename>(response);
string signature = status.Signature;
return signature;
}
}
}
I also created a class called Employeename which I defined the variables (please see code)
namespace TimeSheet_Try11_Models
{
public class Employeename
{
public string Signature { get; set; }
public string FirstName { get; set; }
public string FullName { get; set; }
public string LastName { get; set; }
}
}
Problem: There are no visible errors, however, when I start debugging and enter a name in the forms application, I get the error of "System.Net.WebException: 'The remote server returned an error: (401) Unauthorized.'" for the line "var response = wc.DownloadString(uri);" in the WebAPI folder.
so I'm pretty new to using Web.Api calls and have been reading up on them the last few days. In a nutshell I have a C# asp.net application that needs to post records to a Web.Api call that another group has setup for various applications to send records to that I need to interface with. Right now I have something that tries to work but I'm getting 'error 500: Internal server error' when I run things. I admit it could be on their end, but I wanted to make sure my end was correct as well.
So here is what I have. First I have a class I populate and send up to the wab.api call as that is what it is asking for
public class PackageData
{
public string HostName { get; set; }
public string SerialNumber { get; set; }
public int SourceID { get; set; }
public string PackageName { get; set; }
public string UserName { get; set; }
public string BatchID { get; set; }
public DateTime ReceivedTime { get; set; }
}
Here is the function I actually make the call with. Right now for testing purposes I populate a generic 'PackageData' object which I will eventually populate programatically
public string Test_Update()
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://ServerName/Updates/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
PackageData InstallPackage = new PackageData();
InstallPackage.HostName = "ComputerName";
InstallPackage.SerialNumber = "SerialNumber";
InstallPackage.PackageName = "PackageName.EXE";
InstallPackage.SourceID = 1;
InstallPackage.UserName = "User";
InstallPackage.BatchID = 1;
InstallPackage.ReceivedTime = DateTime.Now;
HttpResponseMessage response = client.PostAsJsonAsync("api/Package?UserName=UserID&Password=password", InstallPackage).Result;
response.EnsureSuccessStatusCode();
return response.Headers.Location.ToString();
}
Is there anything glaring that looks wrong to anyone?
Thanks for the help!
Using Microsoft.AspNet.Membership.OpenAuth I've very quickly been able to get an app logging people in via various external provider (facebook, twitter, google, microsoft). That's great.
My question is, can I use this framework to get the users profile information easily? I'd like to get their profile picture, email address, DOB etc if the service has them.
I know there is some extra information in AuthenticationResult.ExtraData however it isn't standard and doesn't contain what I need.
Is there something I can do from here to get the information using Microsoft.AspNet.Membership.OpenAuth (or another .net lib) or will I need to use the access token in ExtraData to access the different services manually via the separate service APIs?
Thanks
There are two main issues to overcome with the authentication workflow stuff. One, as the OP rightly pointed out concerns the contents of ExtraData and the other concerns the permissions that you need to ask Facebook for. In the end I went with the DotNetOpenAuth library rather than the Microsoft one but extended it in certain places by rolling my own classes and borrowing parts of the framework where necessary.
The first thing I did was create a FacebookClient that extended the OAuth2Client from DotNetOpenAuth and allowed me to pass in a value for scope, which got past the limitation on which data you could request from Facebook. The permission I ask for are publish_stream, manage_pages, email, user_interests. They simply get appended to the service login URL and passed across to Facebook. The useful method within my implementation of OAuth2Client is GetUserData:
protected override IDictionary<string, string> GetUserData(string accessToken)
{
var token = accessToken.EscapeUriDataStringRfc3986();
FacebookGraphData graphData;
var request = WebRequest.Create(string.Format("https://graph.facebook.com/me?access_token={0}", token));
using (var response = request.GetResponse())
{
using (var responseStream = response.GetResponseStream())
{
graphData = JsonHelper.Deserialize<FacebookGraphData>(responseStream);
}
}
var userData = new Dictionary<string, string> {{"accessToken", accessToken}};
userData.AddItemIfNotEmpty("id", graphData.Id);
userData.AddItemIfNotEmpty("name", graphData.Name);
userData.AddItemIfNotEmpty("email", graphData.Email);
userData.AddItemIfNotEmpty("firstName", graphData.FirstName);
userData.AddItemIfNotEmpty("lastName", graphData.LastName);
userData.AddItemIfNotEmpty("link", graphData.Link == null ? null : graphData.Link.AbsoluteUri);
userData.AddItemIfNotEmpty("username", graphData.Username);
userData.AddItemIfNotEmpty("gender", graphData.Gender);
userData.AddItemIfNotEmpty("locale", graphData.Locale);
FacebookFriendData friendData;
request = WebRequest.Create(string.Format("https://graph.facebook.com/me/friends?access_token={0}", token));
using (var response = request.GetResponse())
{
using (var responseStream = response.GetResponseStream())
{
friendData = JsonHelper.Deserialize<FacebookFriendData>(responseStream);
}
}
if (friendData.Friends != null)
{
userData.Add("connections", friendData.Friends.Count().ToString());
}
return userData;
}
I've basically created a few data classes that are deserialized when the response comes back from Facebook. I can also make any other Graph API calls from here that I need. Serialization classes look like this:
[DataContract]
public class FacebookFriendData
{
[DataMember(Name = "data")]
public IEnumerable<Friend> Friends { get; set; }
}
[DataContract]
public class Friend
{
[DataMember(Name = "id")]
public string Id { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
}
[DataContract]
public class FacebookGraphData
{
[DataMember(Name = "id")]
public string Id { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "email")]
public string Email { get; set; }
[DataMember(Name = "first_name")]
public string FirstName { get; set; }
[DataMember(Name = "last_name")]
public string LastName { get; set; }
[DataMember(Name = "link")]
public Uri Link { get; set; }
[DataMember(Name = "username")]
public string Username { get; set; }
[DataMember(Name = "gender")]
public string Gender { get; set; }
[DataMember(Name = "locale")]
public string Locale { get; set; }
}
As per #radm4 I still check the provider string to decide which methods to call in certain places - still working on a more elegant solution to that one...
After looking around I can't see a way to do this only with the Microsoft.AspNet.Membership.OpenAuth stuff.
My solution has been to skip the .NET oauth stuff if the user wants to use facebook. In this case I use the facebook C# SDK to authenticate and then I can access email, birthday, photo etc.
if(provider != "facebook")
{
//do normal oauth
}
else
{
FacebookClient client = new FacebookClient();
var loginUrl = client.GetLoginUrl(new
{
client_id = ConfigurationManager.AppSettings["facebookId"],
client_secret = ConfigurationManager.AppSettings["facebookClientSecret"],
redirect_uri = redirectUrl,
response_type = "code",
scope = "email,user_birthday"
});
Response.Redirect(loginUrl.AbsoluteUri);
}
When the user returns you can then use the SDK to access this extra information.
I'm going to add this type of thing for Google too. If users want to use other services to log in they can but I'll just use asp.net oauth and they won't get as customised an experience as facebook or google until I have more time to spend on each provider.
So basically the answer is ASP.net oauth is fine for logging in and very basic information but if you need more you'll need to extend or by pass it for each provider.
Can the Microsoft.Phone.Maps.Services namespace be used in a Windows Store Apps app?
If not, is there a suitable alternative available?
I was directed to this which shows some code that's just what the non-doctor ordered for getting gobs of geolocation data based on a search term such as an address.
HOWEVER
The classes used in that snippet (in the Maps_GeoCoding event and the QueryCompleted callback) are from the Microsoft.Phone.Maps.Services namespace, and I need this or similar code for a Windows store apps app (I knew that "Windows Store app" nomenclature would lead to some awkwardness).
Is anybody aware of an analogous set of functionality? Or, is it possible, though counter-intuitive sounding, that one could actually use the Microsoft.Phone.Maps.Services namespace within a Windows Store apps app?
UPDATE
This is what I did (ad[a,o]pted from Justin "Teen" Angel's code below, with appId and appCode not shown):
private async static Task<string> GetCoordinatesForAddress(string address) // AKA Geocoding (reverse geocoding is getting address for coordinates)
{
// build URL for Here.net REST service
string currentgeoLoc = "0.0,0.0";
string queryString = address; //"Ferry Building, San-Francisco";
string appID = "<appId>"; // MAKE SURE TO GET YOUR OWN from developers.here.net
object appCode = "<appCode>"; // MAKE SURE TO GET YOUR OWN from developers.here.net
var hereNetUrl = string.Format(
"http://demo.places.nlp.nokia.com/places/v1/discover/search?at={0}&q={1}&app_id={2}&app_code={3}&accept=application/json",
currentgeoLoc, queryString, appID, appCode);
// get data from HERE.net REST API
var httpClient = new HttpClient();
var hereNetResponse = await httpClient.GetStringAsync(hereNetUrl);
// deseralize JSON from Here.net
using (var tr = new StringReader(hereNetResponse))
using (var jr = new JsonTextReader(tr))
{
var rootObjectResponse = new JsonSerializer().Deserialize<JsonDOTNetHelperClasses.RootObject>(jr);
var firstplace = rootObjectResponse.results.items.First();
return string.Format("{0};{1}", firstplace.position[0], firstplace.position[1]);
}
}
The WP8 Nokia <Maps /> control and its associated services (routing, geocoding, etc) aren't currently available in the Win8 SDK. Win8 apps are expected to use Bing Maps APIs.
However, if you do want to use Nokia Maps functionality in your Win8 app, that's definitely possible. Here.net (Nokia's location portal) exposes publicly documented web APIs. You can use the "core plan" that allows up to 2,500 free queries/day from the here.net REST APIs. Those REST APIs include geocoding, reverse geocoding, pedestrian routing, driving routing and more.
You can see examples for these REST APIs # http://developer.here.net/javascript_api_explorer (click "REST API Explorer" in the top right since this view defaults to the javascript API explorer). The Geocoding APIs will be available under "Places".
For example, here's how to replicate the WP8 Maps GeoCoding sample using REST APIs on Win8:
private async void GeocodingWin8Query()
{
// build URL for Here.net REST service
string currentgeoLoc = "0.0,0.0";
string queryString = "Ferry Building, San-Francisco";
string appID = "<appId>"; // MAKE SURE TO GET YOUR OWN from developers.here.net
object appCode = "<appCode>"; // MAKE SURE TO GET YOUR OWN from developers.here.net
var hereNetUrl = string.Format(
"http://demo.places.nlp.nokia.com/places/v1/discover/search?at={0}&q={1}&app_id={2}&app_code={3}&accept=application/json",
currentgeoLoc, queryString, appID, appCode);
// get data from HERE.net REST API
var httpClient = new HttpClient();
var hereNetResponse = await httpClient.GetStringAsync(hereNetUrl);
// deseralize JSON from Here.net
using (var tr = new StringReader(hereNetResponse))
using (var jr = new JsonTextReader(tr))
{
var rootObjectResponse = new JsonSerializer().Deserialize<RootObject>(jr);
// print the details of the first geocoding result
var firstplace = rootObjectResponse.results.items.First();
await new MessageDialog("Name: " + firstplace.title + Environment.NewLine +
"Geolocation: " + firstplace.position[0] + ", " + firstplace.position[1] + Environment.NewLine +
"Address: " + HtmlUtilities.ConvertToText(firstplace.vicinity) + Environment.NewLine +
"Type: " + firstplace.type + Environment.NewLine,
"Win8 Nokia Maps Geocoding").ShowAsync();
}
}
When we run this code snippet we can see that Win8 has access to the same Geocoding data as WP8:
There's lots more this API can do, like reverse geocoding, routing, etc. As I mentioned you can explore those features at the Here.net REST APIs here (click "REST API explorer" in the top right). Also, don't forgot to sign up for an AppID and AppCode after signing in.
For the code above to work I've used JSON.Net. You'll need to install JSON.net from NuGet and copy some strongly-typed generated classes over from json2csharp. Here's how to install JSON.net:
And here are the generated C# JSON.net classes:
public class Category
{
public string id { get; set; }
public string title { get; set; }
public string href { get; set; }
public string type { get; set; }
}
public class Item
{
public List<double> position { get; set; }
public int distance { get; set; }
public string title { get; set; }
public Category category { get; set; }
public string icon { get; set; }
public string vicinity { get; set; }
public List<object> having { get; set; }
public string type { get; set; }
public string href { get; set; }
public string id { get; set; }
public double? averageRating { get; set; }
}
public class Results
{
public List<Item> items { get; set; }
}
public class Location
{
public List<double> position { get; set; }
}
public class Context
{
public Location location { get; set; }
public string type { get; set; }
}
public class Search
{
public Context context { get; set; }
}
public class RootObject
{
public Results results { get; set; }
public Search search { get; set; }
}
While it may be possible, I don't think its reliable.
Why would you want to do this when there is a Maps SDK built in (which runs on Bing Maps)
Here's a tutorial
I think you should look at