我正在尝试使用适用于Windows Phone 8.1 app的Gmail API。这是我从https://developers.google.com/gmail/api/quickstart/quickstart-cs获得的代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Compilation;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.Routing;
using System.Web.SessionState;
using Newtonsoft.Json;
// TODO(class) Reorder, this gets messy with alt+shift+F10
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Util;
using Google.Apis.Gmail;
using Google.Apis.Gmail.v1;
using Google.Apis.Gmail.v1.Data;
using Google.Apis.Oauth2;
using Google.Apis.Oauth2.v2;
using Google.Apis.Oauth2.v2.Data;
using Google.Apis.Plus.v1;
using Google.Apis.Auth.OAuth2.Responses;
using Google.Apis.Auth.OAuth2.Flows;
using System.Threading;
namespace GmailQuickstart
{
/// <summary>
/// This is a minimal implementation of GMail demonstrating:
/// - Using the Google+ Sign-In button to get an OAuth 2.0 refresh token.
/// - Exchanging the refresh token for an access token.
/// - Making GMail API requests with the access token, including
/// getting a list GMail threads.
/// - Disconnecting the app from the user's Google account and revoking
/// tokens.
/// </summary>
/// @author class@google.com (Gus Class)
public class Signin : IHttpHandler, IRequiresSessionState, IRouteHandler
{
// These come from the APIs console:
// https://code.google.com/apis/console
public static ClientSecrets secrets = new ClientSecrets()
{
ClientId = "YOUR_CLIENT_ID",
ClientSecret = "YOUR_CLIENT_SECRET"
};
// Configuration that you probably don't need to change.
static public string APP_NAME = "GMail .NET Quickstart";
// Stores token response info such as the access token and refresh token.
private TokenResponse token;
// Used to peform API calls against Google APIs.
private PlusService ps = null;
private GmailService gs = null;
/// <summary>Processes the request based on the path.</summary>
/// <param name="context">Contains the request and response.</param>
public void ProcessRequest(HttpContext context)
{
// Redirect base path to signin.
if (context.Request.Path.EndsWith("/"))
{
context.Response.RedirectPermanent("signin.ashx");
}
// This is reached when the root document is passed. Return HTML
// using index.html as a template.
if (context.Request.Path.EndsWith("/signin.ashx"))
{
String state = (String)context.Session["state"];
// Store a random string in the session for verifying
// the responses in our OAuth2 flow.
if (state == null)
{
Random random = new Random((int)DateTime.Now.Ticks);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 13; i++)
{
builder.Append(Convert.ToChar(
Convert.ToInt32(Math.Floor(
26 * random.NextDouble() + 65))));
}
state = builder.ToString();
context.Session["state"] = state;
}
// Render the templated HTML.
String templatedHTML = File.ReadAllText(
context.Server.MapPath("index.html"));
templatedHTML = Regex.Replace(templatedHTML,
"[{]{2}\\s*APPLICATION_NAME\\s*[}]{2}", APP_NAME);
templatedHTML = Regex.Replace(templatedHTML,
"[{]{2}\\s*CLIENT_ID\\s*[}]{2}", secrets.ClientId);
templatedHTML = Regex.Replace(templatedHTML,
"[{]{2}\\s*STATE\\s*[}]{2}", state);
context.Response.ContentType = "text/html";
context.Response.Write(templatedHTML);
return;
}
if (context.Session["authState"] == null)
{
// The connect action exchanges a code from the sign-in button,
// verifies it, and creates OAuth2 credentials.
if (context.Request.Path.Contains("/connect"))
{
// Get the code from the request POST body.
StreamReader sr = new StreamReader(
context.Request.InputStream);
string code = sr.ReadToEnd();
string state = context.Request["state"];
// Test that the request state matches the session state.
if (!state.Equals(context.Session["state"]))
{
context.Response.StatusCode = 401;
return;
}
// Use the code exchange flow to get an access and refresh token.
IAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = secrets,
Scopes = new string[] { PlusService.Scope.PlusLogin, GmailService.Scope.GmailReadonly}
});
token = flow.ExchangeCodeForTokenAsync("", code, "postmessage",
CancellationToken.None).Result;
// Create an authorization state from the returned token.
context.Session["authState"] = token;
// Get tokeninfo for the access token if you want to verify.
Oauth2Service service = new Oauth2Service(
new Google.Apis.Services.BaseClientService.Initializer());
Oauth2Service.TokeninfoRequest request = service.Tokeninfo();
request.AccessToken = token.AccessToken;
Tokeninfo info = request.Execute();
string gplus_id = info.UserId;
}
else
{
// No cached state and we are not connecting.
context.Response.StatusCode = 400;
return;
}
}
else if (context.Request.Path.Contains("/connect"))
{
// The user is already connected and credentials are cached.
context.Response.ContentType = "application/json";
context.Response.StatusCode = 200;
context.Response.Write(JsonConvert.SerializeObject("Current user is already connected."));
return;
}
else
{
// Register the authenticator and construct the Plus service
// for performing API calls on behalf of the user.
token = (TokenResponse)context.Session["authState"];
IAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = secrets,
Scopes = new string[] { PlusService.Scope.PlusLogin, GmailService.Scope.GmailReadonly }
});
UserCredential credential = new UserCredential(flow, "me", token);
bool success = credential.RefreshTokenAsync(CancellationToken.None).Result;
token = credential.Token;
ps = new PlusService(
new Google.Apis.Services.BaseClientService.Initializer()
{
ApplicationName = ".NET Quickstart",
HttpClientInitializer = credential
});
gs = new GmailService(
new Google.Apis.Services.BaseClientService.Initializer()
{
ApplicationName = ".NET Quickstart",
HttpClientInitializer = credential
});
}
// Perform an authenticated API request to retrieve the list of
// people that the user has made visible to the app.
if (context.Request.Path.Contains("/mail"))
{
// List the GMail threads for the current user.
IList<Google.Apis.Gmail.v1.Data.Thread> threadFeed =
gs.Users.Threads.List("me").Execute().Threads;
string jsonContent =
Newtonsoft.Json.JsonConvert.SerializeObject(threadFeed);
context.Response.ContentType = "application/json";
context.Response.Write(jsonContent);
return;
}
// Disconnect the user from the application by revoking the tokens
// and removing all locally stored data associated with the user.
if (context.Request.Path.Contains("/disconnect"))
{
// Perform a get request to the token endpoint to revoke the
// refresh token.
token = (TokenResponse)context.Session["authState"];
string tokenToRevoke = (token.RefreshToken != null) ?
token.RefreshToken : token.AccessToken;
WebRequest request = WebRequest.Create(
"https://accounts.google.com/o/oauth2/revoke?token=" +
token);
WebResponse response = request.GetResponse();
// Remove the cached credentials.
context.Session["authState"] = null;
// You could reset the state in the session but you must also
// reset the state on the client.
// context.Session["state"] = null;
context.Response.Write(
response.GetResponseStream().ToString().ToCharArray());
return;
}
}
/// <summary>
/// Implements IRouteHandler interface for mapping routes to this
/// IHttpHandler.
/// </summary>
/// <param name="requestContext">Information about the request.
/// </param>
/// <returns></returns>
public IHttpHandler GetHttpHandler(RequestContext
requestContext)
{
var page = BuildManager.CreateInstanceFromVirtualPath
("~/signin.ashx", typeof(IHttpHandler)) as IHttpHandler;
return page;
}
public bool IsReusable { get { return false; } }
}
}
所以我不断收到此错误System.web,System.Web.Compilation命名空间不可用。所以我该怎么做才能解决这个问题?
答案 0 :(得分:1)
错误是正确的。 System.Web不适用于Windows Phone应用程序(Silverlight或Runtime)。如果Gmail API依赖于它,那么它可能是针对完整的.Net Framework设计的,而不是针对Windows Phone设计的。相反,您需要直接连接到Gmail网络API。看起来谷歌在https://developers.google.com/gmail/api/v1/reference/
上有文档有关WP8 Silverlight应用程序中可用的.Net类,请参阅.NET API for Windows Phone。