C# Google Drive Api-带有实体框架的自定义IDataStore
我实现了我的自定义C# Google Drive Api-带有实体框架的自定义IDataStore,c#,asp.net-mvc,oauth-2.0,google-api,google-oauth,C#,Asp.net Mvc,Oauth 2.0,Google Api,Google Oauth,我实现了我的自定义IDataStore,这样我就可以将最终用户令牌存储在我的数据库上,而不是默认实现,默认实现保存在%AppData%内的文件系统上 public class GoogleIDataStore : IDataStore { ... public Task<T> GetAsync<T>(string key) { TaskCompletionSource<T> tcs = new TaskCompleti
IDataStore
,这样我就可以将最终用户令牌存储在我的数据库上,而不是默认实现,默认实现保存在%AppData%内的文件系统上
public class GoogleIDataStore : IDataStore
{
...
public Task<T> GetAsync<T>(string key)
{
TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();
var user = repository.GetUser(key.Replace("oauth_", ""));
var credentials = repository.GetCredentials(user.UserId);
if (key.StartsWith("oauth") || credentials == null)
{
tcs.SetResult(default(T));
}
else
{
var JsonData = Newtonsoft.Json.JsonConvert.SerializeObject(Map(credentials));
tcs.SetResult(NewtonsoftJsonSerializer.Instance.Deserialize<T>(JsonData));
}
return tcs.Task;
}
}
公共类GoogleIDataStore:IDataStore
{
...
公共任务GetAsync(字符串键)
{
TaskCompletionSource tcs=新的TaskCompletionSource();
var user=repository.GetUser(key.Replace(“oauth_uu”);
var-credentials=repository.GetCredentials(user.UserId);
if(key.StartsWith(“oauth”)| | credentials==null)
{
设置结果(默认值(T));
}
其他的
{
var JsonData=Newtonsoft.Json.JsonConvert.SerializeObject(映射(凭证));
SetResult(NewtonsoftJsonSerializer.Instance.Deserialize(JsonData));
}
返回tcs.Task;
}
}
控制器
public async Task<ActionResult> AuthorizeDrive(CancellationToken cancellationToken)
{
var result = await new AuthorizationCodeMvcApp(this, new GoogleAppFlowMetadata()).
AuthorizeAsync(cancellationToken);
if (result.Credential == null)
return new RedirectResult(result.RedirectUri);
var driveService = new DriveService(new BaseClientService.Initializer
{
HttpClientInitializer = result.Credential,
ApplicationName = "My app"
});
//Example how to access drive files
var listReq = driveService.Files.List();
listReq.Fields = "items/title,items/id,items/createdDate,items/downloadUrl,items/exportLinks";
var list = listReq.Execute();
return RedirectToAction("Index", "Home");
}
公共异步任务
谢谢你的帮助我不太清楚为什么你的不起作用,但这是我使用的代码的副本。完整的类可以在这里找到
//
///返回给定键的存储值,如果匹配的文件(
///在这个世界上根本不存在。
///
///要检索的类型
///要从数据存储中检索的密钥
///存储的对象
公共任务GetAsync(字符串键)
{
//Key是使用AuthorizeAsync发送的用户字符串
if(string.IsNullOrEmpty(key))
{
抛出新ArgumentException(“键必须有值”);
}
TaskCompletionSource tcs=新的TaskCompletionSource();
//注意:创建打开连接的方法。
SqlConnection myConnection=newsqlconnection(“用户id=“+LoginName+”;”+
@“password=“+password+”;server=“+ServerName+”;”+
“受信任的连接=是;”+
“database=“+DatabaseName+”;”+
“连接超时=30”);
myConnection.Open();
//尝试在数据库中查找该行。
使用(SqlCommand=newsqlcommand(“从GoogleUser中选择RefreshToken,其中UserName=@UserName;”,myConnection))
{
command.Parameters.AddWithValue(“@username”,key);
字符串refreshttoken=null;
SqlDataReader myReader=command.ExecuteReader();
while(myReader.Read())
{
RefreshToken=myReader[“RefreshToken”].ToString();
}
if(refreshttoken==null)
{
//我们没有记录,所以我们向用户请求它。
设置结果(默认值(T));
}
其他的
{
尝试
{
//我们有它,我们用它。
SetResult(NewtonsoftJsonSerializer.Instance.Deserialize(RefreshToken));
}
捕获(例外情况除外)
{
tcs.SetException(ex);
}
}
}
返回tcs.Task;
}
API在您的IDataStore
中存储(至少)两个值。以下是从空IDataStore的角度来看授权过程的样子(请注意哪些行设置了值,哪些行获得了值):
获取IDataStore值:MyKey”http://localhost..."
正在设置IDataStore值:MyKey=>{“访问令牌”:。。。
获取IDataStore值:oauth_MyKey Hi.Mine也在工作..但是在“StoreAsync”之后的初始重定向(用于用户授权访问其google驱动器)调用GetAsync
,键的值为oauth_xxxx@xx.xxx.这就是我得到的错误。我不确定你的项目是否像我的一样是MVC…问题可能与此有关。我将用控制器代码编辑我的问题。
/// <summary>
/// Returns the stored value for the given key or <c>null</c> if the matching file (<see cref="GenerateStoredKey"/>
/// in <see cref="FolderPath"/> doesn't exist.
/// </summary>
/// <typeparam name="T">The type to retrieve</typeparam>
/// <param name="key">The key to retrieve from the data store</param>
/// <returns>The stored object</returns>
public Task<T> GetAsync<T>(string key)
{
//Key is the user string sent with AuthorizeAsync
if (string.IsNullOrEmpty(key))
{
throw new ArgumentException("Key MUST have a value");
}
TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();
// Note: create a method for opening the connection.
SqlConnection myConnection = new SqlConnection("user id=" + LoginName + ";" +
@"password=" + PassWord + ";server=" + ServerName + ";" +
"Trusted_Connection=yes;" +
"database=" + DatabaseName + "; " +
"connection timeout=30");
myConnection.Open();
// Try and find the Row in the DB.
using (SqlCommand command = new SqlCommand("select RefreshToken from GoogleUser where UserName = @username;", myConnection))
{
command.Parameters.AddWithValue("@username", key);
string RefreshToken = null;
SqlDataReader myReader = command.ExecuteReader();
while (myReader.Read())
{
RefreshToken = myReader["RefreshToken"].ToString();
}
if (RefreshToken == null)
{
// we don't have a record so we request it of the user.
tcs.SetResult(default(T));
}
else
{
try
{
// we have it we use that.
tcs.SetResult(NewtonsoftJsonSerializer.Instance.Deserialize<T>(RefreshToken));
}
catch (Exception ex)
{
tcs.SetException(ex);
}
}
}
return tcs.Task;
}