I am creating a UWP application and I want to use the Onedrive API so that users can save a copy of their files in their Onedrive account, but I don't get it, so far I have only managed to login what I want is:
upload files
download files
and synchronize if any of them is modified
Create folders
Delete Files
This code achieves the login, but I can not move beyond this, as would proceed for upload files or download them
private async void btn_Login_Click(object sender, RoutedEventArgs e)
{
if (this.oneDriveClient == null)
{
try
{
// Setting up the client here, passing in our Client Id, Return Url,
// Scopes that we want permission to, and building a Web Broker to
// go do our authentication.
this.oneDriveClient = await OneDriveClient.GetAuthenticatedMicrosoftAccountClient(
clientId,
returnUrl,
scopes,
webAuthenticationUi: new WebAuthenticationBrokerWebAuthenticationUi());
// Show in text box that we are connected.
txtBox_Response.Text = "We are now connected";
// We are either just autheticated and connected or we already connected,
// either way we need the drive button now.
btn_GetDriveId.Visibility = Visibility.Visible;
}
catch (OneDriveException exception)
{
// Eating the authentication cancelled exceptions and resetting our client.
if (!exception.IsMatch(OneDriveErrorCode.AuthenticationCancelled.ToString()))
{
if (exception.IsMatch(OneDriveErrorCode.AuthenticationFailure.ToString()))
{
txtBox_Response.Text = "Authentication failed/cancelled, disposing of the client...";
((OneDriveClient)this.oneDriveClient).Dispose();
this.oneDriveClient = null;
}
else
{
// Or we failed due to someother reason, let get that exception printed out.
txtBox_Response.Text = exception.Error.ToString();
}
}
else
{
((OneDriveClient)this.oneDriveClient).Dispose();
this.oneDriveClient = null;
}
}
}
}
I created a sample repository in github:Onedrive Sync Files Sample
I have already tried using Dropbox, Gdrive, but its implementation for UWP seems to be much more complex, so I chose OneDrive. any answer will be very helpful thanks in advance
How to Sync files with OneDrive API in C#
For using OneDrive, we suggest you implement OneDrive feature with OneDrive Service that is part of Windows Community Toolkit .
Getting Started
To use the OneDrive API, you need to have an access token that authenticates your app to a particular set of permissions for a user. In this section, you'll learn how to:
Register your application to get a client ID and a client secret.
Sign your user in to OneDrive with the specified scopes using the token flow or code flow.
Sign the user out (optional).
And this is official code sample that you could refer.
Related
I have a question about Microsoft Graph API for C# code. Is it possible to get all messages which I have in Outlook?
I found a good article, but I'm still not getting an answer to my question. The article:
Get all email message using Microsoft Graph API in c#
(UPDATED) I found a good video about how to connect to Microsoft Graph: https://www.youtube.com/watch?v=acnFrkBL1kE&ab_channel=Microsoft365Developer
I have still the same question. I can get 1000 emails for call. Is there any way to get all messages from my Outlook? They should be from all my folders.
My new code for call 1000 messages:
public async Task<(IEnumerable<Message> Messages, string NextLink)> GetUserMessagesPage(
string nextPageLink = null, int top = 1000)
{
IUserMessagesCollectionPage pagedMessages;
if(nextPageLink == null)
{
pagedMessages = await _graphServiceClient.Me.Messages.Request().Select(msg => new
{
msg.Subject,
msg.BodyPreview,
msg.ReceivedDateTime
}).OrderBy("receivedDateTime desc").Top(1000).GetAsync();
}
else
{
var messagesCollectionRequest = new UserMessagesCollectionRequest(nextPageLink, _graphServiceClient, null);
pagedMessages = await messagesCollectionRequest.GetAsync();
}
return (Messages: pagedMessages, NextLink: GetNextLink(pagedMessages));
}
(UPDATED) I have tried also this:
pagedMessages = await _graphServiceClient.Users["email#.com"].Messages.Request().Select(msg => new { msg.Subject}).Top(1000).GetAsync();
messages.AddRange(pagedMessages.CurrentPage);
while (pagedMessages.NextPageRequest != null)
{
pagedMessages = await pagedMessages.NextPageRequest.GetAsync();
messages.AddRange(pagedMessages.CurrentPage);
}
It was mentioned here: https://github.com/microsoftgraph/microsoft-graph-docs/blob/main/api-reference/beta/api/user-list-messages.md
From: Microsoft Graph REST API - Get message Documentation
There are two scenarios where an app can get a message in another
user's mail folder:
If the app has application permissions, or,
If the app has the appropriate delegated permissions from one user, and another user has shared a mail folder with that user, or,
has given delegated access to that user. See details and an
example.
Permissions
One of the following permissions is required to call this API. To
learn more, including how to choose permissions, see
Permissions.
Delegated (work or school account) - Permissions: Mail.ReadBasic, Mail.Read
Delegated (personal Microsoft account) - Permissions: Mail.ReadBasic, Mail.Read
Application - Permissions: Mail.ReadBasic.All, Mail.Read
I have a really frustrating issue, where all I want to do is get user images from O365 and simply display them on my web page, which is hosted on Azure azpp service.
As you can see from this SO and this SharePoint.StackExchange question, The images fail to load when simply trying to display the link taken from SharePoint in an <img> tag.
However, after navigating to the image in a a new tab, and refreshing my page, the iamges load fine. can anyone explain this behaviour? it makes no sense to me at all
Anyways since that just dont work for whatever reason (logged in user clearly has the right permissions, as the images do disaply after navigating to them),
I thought I would try downloading the images using graph API.
SO I downloaded the quick start project and trying to download the iamges with
public async Task<Stream> TestAsync(GraphServiceClient graphClient)
{
var users = graphClient.Users;
var jk = users["user.name#domain.com"];
return await jk.Photo.Content.Request().GetAsync();
}
But I just get
Exception of type 'Microsoft.Graph.ServiceException' was thrown.
Yet when I try to view the same image in the API graph explorer, I can download the image. Please can someone just help me to display SharePoint user images in my web page without the user having to first navigate to the image directly.. Why must it be so difficult?
Once you have a valid token, make sure your permission scopes include User.Read.All, for example:
The query:
var user = graphClient.Users["<userPrincipalName>"];
corresponds to the following endpoint
Url: /users/{userPrincipalName}
Method: GET
which requires User.Read.All scope, see permission section for a more details.
In addition, in case of access without a user token requires Administrative Consent before it can be used.
Example
var users = graphClient.Users;
var user = users[accountName];
var photo = await user.Photo.Content.Request().GetAsync() as MemoryStream;
using (var file = new FileStream("./user.jpg", FileMode.Create, FileAccess.Write))
{
if (photo != null) photo.WriteTo(file);
}
I want to create an WP8 app that allow user to upload images to their dropbox account. Just one click of the button it will authorize if haven't already then upload the image, otherwise it just uploads it.
I followed the instructions here to create the following codes for the event-handler:
private async void toDropBoxBtn_Tap(object sender,System.Windows.Input.GestureEventArgs e)
{
DropBoxConfiguration config = CloudStorage.GetCloudConfigurationEasy(nSupportedCloudConfigurations.DropBox) as DropBoxConfiguration;
DropBoxRequestToken requestToken = DropBoxStorageProviderTools.GetDropBoxRequestToken(config, "MY KEY", "MY SECRET"); // The code hangs at this line
String AuthorizationUrl = DropBoxStorageProviderTools.GetDropBoxAuthorizationUrl(config, requestToken);
ICloudStorageAccessToken accessToken = DropBoxStorageProviderTools.ExchangeDropBoxRequestTokenIntoAccessToken(config, "7nu03leznnz6x74", "ex3gge8av7kp9lq", requestToken);
}
The code just hangs at the 2nd line with no error or exception. I don't know what I've do wrong. Feel free to ask for more information. Thank you.
I'm trying to upload files from local command line client to Azure storage through web-api.
I'm using Azure Web-Site for that. Working with the client is not a problem. And I've got everything working locally fine. Here is the web-api code:
public async Task<HttpResponseMessage> PostUpload()
{
// need a local resource to store uploaded files temporarily
LocalResource localResource = null;
try
{
// Azure web-site fails here
localResource = RoleEnvironment.GetLocalResource("TempStorage");
}
catch (Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Unable to get access to local resources");
}
var provider = new MultipartFormDataStreamProvider(localResource.RootPath);
// Read the form data.
await Request.Content.ReadAsMultipartAsync(provider);
// snipped validation code
var container = // code to get container
foreach (var fileData in provider.FileData)
{
var filename = GetBlobName(fileData);
var blob = container.GetBlockBlobReference(filename);
using (var filestream = File.OpenRead(fileData.LocalFileName))
{
blob.UploadFromStream(filestream);
}
File.Delete(fileData.LocalFileName);
}
return Request.CreateResponse(HttpStatusCode.OK);
}
Everything works fine when I run locally, but as soon as I deploy web-site in Azure, I can't upload, because Azure Web-Sites don't have access to LocalResource. And I'll need to switch to Azure Web-Role. I can switch, but accessing local file system is bothering me all together.
And LocalResource is required for instance of MultipartFormDataStreamProvider(). And I have not found alternative ways to upload files to WebApi. My plan was to channel through upload directly to Azure, without storing anything on a local HDD.
Is there any other way to upload files?
p.s. I have seen usages of Shared Access Signatures where I can give client application a url with signature and let the client upload directly to Azure Blog. But I'm not sure about how secure that is going to be and not really comfortable (yet) with passing the signatures down to the client. At the moment I presume the client is going to be run in very hostile environment and nothing can be trusted coming back from the client.
UPD My final solution involved using write only Shared Access Signature issued on the server and passed down to the client. And client then uploads files directly to Azure. This way I save a lot of hassle with managing uploaded files. And here is more detailed description of my solution.
This isn't exactly the answer you are looking for, but you can use local storage with Azure Websites using MultiPartFileStreamProvider and Path.GetTempPath(). The code would look something like this
public async Task<HttpResponseMessage> PostUpload()
{
var provider = new MultipartFileStreamProvider(Path.GetTempPath());
// Read the form data.
await Request.Content.ReadAsMultipartAsync(provider);
// do the rest the same
}
I found this StackOverflow article that overrides the MultipartFormDataStreamProvider so that Files are not stored locally first, but directly written to an AWSStream. See:
Is it possible to override MultipartFormDataStreamProvider so that is doesn't save uploads to the file system?
But I have to say I also like the solution of trailmax.
One possible solution to get your code to work as is with a LocalResource would be to host this inside of a worker process that self-hosts web api via Owin.
You can find a simple walkthrough at: http://www.asp.net/web-api/overview/hosting-aspnet-web-api/host-aspnet-web-api-in-an-azure-worker-role
You just need to startup the Owin-hosted api within the OnStart() method of the RoleEntryPoint. Keep in mind you can also return Html from a web api response so you can make a worker role a very flexible base project.
Here's a quick snippet showing how to set up the Owin host from the link above:
private IDisposable _webApp = null;
public override bool OnStart() {
ServicePointManager.DefaultConnectionLimit = 5;
var endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["DefaultEndpoint"];
var baseUri = string.Format("{0}://{1}", endpoint.Protocol, endpoint.IPEndpoint);
_webApp = WebApp.Start<Startup>(new StartOptions(baseUri));
return base.OnStart();
}
public override void OnStop() {
if (_webApp != null) {
_webApp.Dispose();
}
base.OnStop();
}
...
using System.Web.Http;
using Owin;
class Startup {
public void Configuration(IAppBuilder app) {
var config = new HttpConfiguration();
config.Routes.MapHttpRoutes("Default", "{controller}/{id}",
new { id = RouteParameter.Optional });
app.UseWebApi(config);
}
}
Probably not the only one asking this, but I found nothing that works...It's like a jungle ;)
I have a C# desktop app (5-10 user) that I want to connect to my Google calendar. I want to add, move, delete, update events in the calendar. I downloaded an installed the last .Net api v.3.
From what I read, the difficult part is the authenticate/connecting procedure. I suppose that we need to use OAuth 2.0 authentication ? I want my user to authenticate once, not each time they want to make a action (add, move, delete, update).In some sample I get we have to cut and paste a token from a web page into a Console...not really user friendly. And how to authenticate only 1 times (or just put the token directly in code to not authenticate ?) ?
Now, were I can have a good working sample code in C# to make that ?
Thanks you very much for helping !!
I used something similar to the example here. What I did initially was create a simple web application using the sample logic to setup the initial auth that Google requires. I stepped through and got the Refresh Token from the state. I then saved this in an app setting that I could use later during future GetAuthorization requests. At least for what I was doing this worked well, the user never needed to authorize as long as app stayed connected.
private IAuthorizationState GetAuthorization(WebServerClient client)
{
IAuthorizationState state = new AuthorizationState(new[] { CalendarService.Scopes.Calendar.GetStringValue() });
string refreshToken = LoadRefreshToken();//this where I wrote code to load it from the app settings
if (!string.IsNullOrEmpty(refreshToken))
{
state.RefreshToken = refreshToken;
try
{
if (client.RefreshToken(state))
return state;
}
catch (ProtocolException)
{
return null;
}
}
return null;
}
I have today the same issue and found now the solution
Prepare Api Access https://console.developers.google.com/apis/dashboard
Press button "Enable Apis and services"
Search "Calendar" and choose "Google Calendar API"
Press button "Create Project"
Create Project
Press "Enable"
Press button "Create credentials"
Choose "Where will you be calling the API from?" -> Other UI
Choose "What data will you be accessing?" -> Application data
Create service account
Choose Role Project -> Editor
Choose Key type JSON
Press button "Continue"
Rename the file to "credential.json" and save it in the visual studio project
Change in Visual Studio the Copy to output Directory -> "Copy if newer"
Change share config of your google calendar (Share this Calendar)
Add the email address from the json file "client_email" in the google calendar config "Share with specific people"
Example Code
using Google.Apis.Auth.OAuth2;
using Google.Apis.Calendar.v3;
using Google.Apis.Calendar.v3.Data;
using Google.Apis.Services;
using System.IO;
namespace Test.GoogleCalendar
{
class Program
{
static void Main(string[] args)
{
GoogleCredential credential;
using (var stream = new FileStream("credential.json", FileMode.Open, FileAccess.Read))
{
credential = GoogleCredential.FromStream(stream).CreateScoped(CalendarService.Scope.Calendar);
}
// Create Google Calendar API service.
var service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Test Calendar Reader",
});
var calendars = service.CalendarList.List().Execute().Items;
foreach (CalendarListEntry calendar in calendars)
{
var events = service.Events.List(calendar.Id).Execute();
}
}
}
}
Here is a link to help download Calendar Client API library for .NET. The library makes OAuth and accessing the Calendar easier. See link for OAuth details but I'm pretty sure it's what you want - user logs in only once to authorize.
On same page there are sample applications using the Client API in VB.NET and MVC.