我有一个MVC4应用程序,它试图使用C#GData API访问Google文档(https://developers.google.com/gdata/client-cs)。
当我从visual studio以调试模式在本地运行该网站时,该应用程序可以正常工作,但当我在Azure网站上发布和运行时,它总是失败,并出现InvalidCredentialsException。
我已经创建了一个最小的MVC4应用程序来重新处理这种行为。它部署到一个azure网站,除了帮助我调试这个问题之外,它什么都不做。我把失败操作的本质塞进About()控制器,只是为了得到一个repo——这不是我实际项目的设置方式。还需要注意的是,当我去年1月第一次写这个网站时,这是有效的。我不知道在过渡期间发生了什么变化,使它停止工作。我知道我可以在MVC3或MVC4中重新处理此问题。
About()控制器当前为:
public ActionResult About()
{
string username = "<omitted>";
string password = "<omitted>";
string appname = "<omitted>";
var count = 0;
var query = new SpreadsheetQuery();
var gDocsService = new DocumentsService(appname);
var gDocsRequestSettings = new RequestSettings(appname, username, password);
var gDocsRequest = new DocumentsRequest(gDocsRequestSettings);
var feed = gDocsRequest.GetSpreadsheets();
foreach (Document entry in feed.Entries)
{
count++;
}
ViewBag.Message = count.ToString();
return View();}
SpreadsheetQuery、DocumentsService、RequestSettings和DocumentsRequest都是由GData库提供的类。
预计>>无论消息显示在何处,计数都应显示在"关于"视图中。实际>>这在本地调试中按预期工作,所以我知道凭据实际上是有效的,但当我发布到azure时,我遇到了以下异常/堆栈跟踪:
[InvalidCredentialsException: Invalid credentials]
Google.GData.Client.Utilities.QueryClientLoginToken(GDataCredentials gc, String serviceName, String applicationName, Boolean fUseKeepAlive, IWebProxy proxyServer, Uri clientLoginHandler) +886
Google.GData.Client.GDataGAuthRequest.QueryAuthToken(GDataCredentials gc) +263
Google.GData.Client.GDataGAuthRequest.EnsureCredentials() +40
Google.GData.Client.GDataRequest.EnsureWebRequest() +1147
Google.GData.Client.GDataGAuthRequest.EnsureWebRequest() +26
Google.GData.Client.GDataRequest.Execute() +37
Google.GData.Client.GDataGAuthRequest.Execute(Int32 retryCounter) +484
Google.GData.Client.GDataGAuthRequest.Execute() +10
Google.GData.Client.Service.Query(Uri queryUri, DateTime ifModifiedSince, String etag, Int64& contentLength) +190
Google.GData.Client.Service.Query(FeedQuery feedQuery) +177
Google.GData.Client.Feed`1.get_AtomFeed() +35
Google.GData.Client.<get_Entries>d__0.MoveNext() +69
Mvc4ApplicationPublishTest.Controllers.HomeController.About() +287
lambda_method(Closure , ControllerBase , Object[] ) +62
System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +14
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +182
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27
System.Web.Mvc.Async.<>c__DisplayClass42.<BeginInvokeSynchronousActionMethod>b__41() +28
System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +10
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +50
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +32
System.Web.Mvc.Async.<>c__DisplayClass39.<BeginInvokeActionMethodWithFilters>b__33() +58
System.Web.Mvc.Async.<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49() +225
System.Web.Mvc.Async.<>c__DisplayClass37.<BeginInvokeActionMethodWithFilters>b__36(IAsyncResult asyncResult) +10
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +50
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +34
System.Web.Mvc.Async.<>c__DisplayClass2a.<BeginInvokeAction>b__20() +24
System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__22(IAsyncResult asyncResult) +99
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +50
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__18(IAsyncResult asyncResult) +14
System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +23
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +55
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +39
System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +23
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +55
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +29
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__3(IAsyncResult asyncResult) +25
System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +23
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +55
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +31
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9631764
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
另一个注意事项是:最近我第一次尝试从azure运行应用程序时,谷歌给我发了一封电子邮件,说由于请求的可疑性,该应用程序被阻止了。当我第一次开发这个网站时,它从来没有这样做过。我(通过他们的UI)表示该应用程序是合法的,但它可能仍然不信任azure,并以某种方式阻止了登录。。。我不知道如何证明/反驳这个理论,如果是这样的话,我也不知道如何解决它。
只是为了确保它是100%清楚的:使用相同的凭据,操作确实在本地/调试中成功,所以我知道我使用了正确的凭据,并且逻辑原则上是有效的。
如有任何关于在这里寻找/尝试的指导,我们将不胜感激!
我可能是由于双向身份验证,您是否偶然启用了它?如果是这样的话,你必须确保你使用的是应用程序特定的密码,而不是个人密码。有关如何在此处设置应用程序密码的更多信息:https://support.google.com/accounts/answer/185833?hl=en
我不知道根本原因,但我删除了azure网站(来自azure管理),创建了一个同名的新azure网站,重新发布了网站,它开始按预期工作。这看起来很激烈,但它完成了任务。