使用SDK需要做一些准备工作
一、在开发者中心注册应用
2、在页面上点击“创建应用程序”,输入应用程序名称并选择语言。然后“我接受”(怎么不是我愿意
3、在API设置页面中将“移动或桌面客户端应用”选择成“是”。如果你要在原有的应用中使用SDK,更改对应应用的API设置即可
二、项目准备
1、新建一个UWP工程,这里命名为OneDriveDemo
2、在工程中安装SDK对应的NuGet包,搜索“Microsoft.OneDriveSDK”
3、将项目工程与应用程序关联
右键项目名,选择“应用商店”->“将应用程序与应用商店关联”
在登陆应用商店之后,在选择应用程序名称页面下面填入新应用名称,或者在应用列表中选择对应应用名
以上,我们完成了SDK使用的准备工作。
要操作OneDrive中的应用,就要让用户登录,也就是身份认证。
三、身份认证
在UWP中,有三种方法可以调用用于身份认证(其实大同小异
• GetUniversalClient
var oneDriveClient = OneDriveClientExtensions.GetUniversalClient(scopes);
var accountSession = await oneDriveClient.AuthenticateAsync();
• GetClientUsingOnlineIdAuthenticator
var oneDriveClient =await OneDriveClientExtensions.GetAuthenticatedClientUsingOnlineIdAuthenticator(scopes);
var accountSession = await oneDriveClient.AuthenticateAsync();
• GetClientUsingWebAuthenticationBroker
var oneDriveClient = OneDriveClientExtensions.GetClientUsingWebAuthenticationBroker(appId,scopes);
await oneDriveClient.AuthenticateAsync();
前两种方法接受一个string 数组做为参数scopes,第三者方法多一个string 参数appId。返回一个IOneDriveClient对象
scopes数组的定义是这样:
private readonly string[] scopes = new string[] { "onedrive.readwrite", "wl.offline_access", "wl.signin" };
其中具体的选择可以查看这
https://dev.onedrive.com/auth/msa_oauth.htm
appId可以在注册应用的时候在应用设置中查看。我偏向于使用第一种方法,也不需要appId了。
调用oneDriveClient的AuthenticateAsync方法,如果没问题,第一次就会弹出下面的对话框
之后一般都不会再弹,除非身份验证过期。
四、SDK主要方法
OneDrive中的每一个项都是Item,因此操作的对象都是Item
1、通过Id获取Item
var item = await oneDriveClient
.Items[itemId]
.Request()
.GetAsync();
2、通过路径获取Item
var item = await oneDriveClient
.Drive
.Root
.ItemWithPath(itemPath)
.Request()
.GetAsync();
3、删除Item
await oneDriveClient
.Drive
.Items[itemId]
.Request()
.DeleteAsync();
4、获取Item的子项目列表
var items=await oneDriveClient
.Drive
.Items[rootItem.Id]
.Children
.Request()
.GetAsync();
var itemList= items.CurrentPage;
5、上传Item
using (stream)
{
var uploadedItem = await oneDriveClient
.Drive
.Root
.ItemWithPath(itemPath)
.Content
.Request()
.PutAsync<Item>(stream);
}
6、下载Item
var stream = await oneDriveClient
.Drive
.Items[itemId]
.Content
.Request()
.GetAsync();
五、Demo
1、XAML界面设计
<Page.Resources>
<local:ItemTypeToImageConverter x:Key="ItemType2ImageConverter" />
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0">
<Button Content="登陆" Click="btnLogin_Click" Margin="5"/>
<Button Content="上传" Click="btnUpload_Click" Margin="5"/>
<Button Content="下载" Click="btnDownload_Click" Margin="5"/>
<Button Content="返回" Click="btnBack_Click" Margin="5"/>
<TextBlock x:Name="txtMsg"/>
</StackPanel>
<GridView Grid.Row="1" x:Name="gridView" SelectionChanged="gridView_SelectionChanged">
<GridView.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Source="{Binding File,Converter={StaticResource ItemType2ImageConverter}}" Width="150" Height="150"/>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Grid>
2、XAML中的Convert类
作用:如果是文件显示文件的图片,否则显示文件夹的图片。判断方式是Item的File属性是否为null
public class ItemTypeToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value==null)
return "Assets/folder.png";
else
return "Assets/file.png";
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
3、登陆并显示所有文件/文件夹
private async void btnLogin_Click(object sender, RoutedEventArgs e)
{
try
{
oneDriveClient = OneDriveClientExtensions.GetUniversalClient(scopes);
var accountSession = await oneDriveClient.AuthenticateAsync();
if (accountSession!=null)
{
var rootItem = await oneDriveClient
.Drive
.Root
.Request()
.GetAsync();
var items=await oneDriveClient
.Drive
.Items[rootItem.Id]
.Children
.Request()
.GetAsync();
gridView.ItemsSource = items.CurrentPage;
}
}
catch (OneDriveException oe)
{
txtMsg.Text="登陆失败";
}
}
4、选择事件
判断当前选择的是否是文件夹,如果是文件夹则进入,并重新绑定数据源
private async void gridView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (gridView.SelectedItem!=null)
{
var selectedItem = gridView.SelectedItem as Item;
if (selectedItem.Folder!=null)
{
var items = await oneDriveClient
.Drive
.Items[selectedItem.Id]
.Children
.Request()
.GetAsync();
gridView.ItemsSource = items.CurrentPage;
pathStack.Push(selectedItem.ParentReference.Path);
}
}
}
这里用到了一个栈用来保存路径。Item的ParentReference属性是其父节点的数据
5、返回事件
如果存储路径的栈非空,说明存在上一级
private async void btnBack_Click(object sender, RoutedEventArgs e)
{
if (pathStack.Count >0)
{
var parentItem = await oneDriveClient
.Drive
.Root
.ItemWithPath(pathStack.Pop().Substring(12))
.Request()
.GetAsync();
var items = await oneDriveClient
.Drive
.Items[parentItem.Id]
.Children
.Request()
.GetAsync();
gridView.ItemsSource = items.CurrentPage;
}
}
6、上传事件
private async void btnUpload_Click(object sender, RoutedEventArgs e)
{
var picker = new FileOpenPicker();
picker.ViewMode = PickerViewMode.Thumbnail;
picker.FileTypeFilter.Add(".txt");
var file = await picker.PickSingleFileAsync();
if (file != null)
{
Stream stream = await file.OpenStreamForReadAsync();
var uploadedItem = await oneDriveClient
.Drive
.Root
.ItemWithPath(file.Name)
.Content
.Request()
.PutAsync<Item>(stream);
txtMsg.Text = "上传成功";
}
}
7、下载事件
毕竟是个Demo,所以只下载了跟目录下的文件
private async void btnDownload_Click(object sender, RoutedEventArgs e)
{
try
{
var picker = new FolderPicker();
picker.FileTypeFilter.Add(".txt");
var folder = await picker.PickSingleFolderAsync();
var rootItem = await oneDriveClient
.Drive
.Root
//.ItemWithPath("焕屏")
.Request()
.GetAsync();
var items = await oneDriveClient
.Drive
.Items[rootItem.Id]
.Children
.Request()
.GetAsync();
var queryItem = items.Where(item => item.File != null);//筛选文件
foreach (var item in queryItem)
{
var file = await folder.CreateFileAsync(item.Name, CreationCollisionOption.GenerateUniqueName);
var stream = await oneDriveClient
.Drive
.Items[item.Id]
.Content
.Request()
.GetAsync();
byte[] buffer = new byte[stream.Length];
await stream.ReadAsync(buffer, 0, buffer.Length); //将流的内容读到缓冲区
var fs = await file.OpenStreamForWriteAsync();
fs.Write(buffer, 0, buffer.Length);
}
txtMsg.Text = "下载成功";
}
catch (Exception ex)
{
txtMsg.Text = "下载失败";
}
}