如何将 Google Admin SDK 部署到 Azure 云服务

How to deploy Google Admin SDK to Azure cloud service

按照 ASP.NET MVC 示例 here,我在我的 Web 应用程序中实施了 Google Admin SDK,以便我可以获得组织单位列表 and/or 与使用目录服务的组织单位关联的用户。

一切都在本地运行良好(身份验证回调有效,因为我利用 ngrok 访问我的本地框),但是当我部署到 MS Azure 中的云服务时,应用程序无法启动,我在事件日志中看到以下错误:

Role entrypoint could not be created: System.TypeLoadException: Unable to load the role entry point due to the following exceptions: -- System.IO.FileLoadException: Could not load file or assembly 'System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040) File name: 'System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'

我在我的 .NET 4.5 Web 应用程序中使用 ASP.NET MVC 版本 5.2.3,在我的 web.config 中使用以下设置。对于 4.0.0.0 版本,我不清楚这个显式引用的确切来源,但我已经重新部署了我的应用程序,有和没有对 Google API 库的引用,以及错误 当我引用 Google API 库时肯定会发生。

<dependentAssembly>
    <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
    <bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>

前几次我收到错误,我认为这是因为我在我的 AppFlowMetadata class 中使用了一个 FileDataStore 对象,而本地文件存储可能在 Azure 云服务中不可用。因此找到 this SO post,我创建了自己的数据库存储,它实现了 IDataStore 接口,并且在本地也很好用,但是部署到 Azure 会导致与上面列出的相同的错误。

有谁知道为什么 Azure 部署失败并且 why/where System.Web.MVC Version=4.0.0.0 被引用?

public class AppFlowMetadata : FlowMetadata
    {
        public AppFlowMetadata()
        {
        }

    private static readonly IAuthorizationCodeFlow flow =
    new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
    {
        ClientSecrets = new ClientSecrets
        {
            ClientId = "CLIENT-ID",
            ClientSecret = "CLIENT-SECRET"
        },
        Scopes = new[] { DirectoryService.Scope.AdminDirectoryOrgunit, DirectoryService.Scope.AdminDirectoryUser },
        DataStore = new GoogleDBDataStore()
    });

    public override string GetUserId(Controller controller)
    {
        var user = controller.Session["user"] as USER;

        if (user != null)
        {
            return user.UserID.ToString();
        }
        else
        {
            return null;
        }
    }

    public override IAuthorizationCodeFlow Flow
    {
        get { return flow; }
    }
}

Does anyone know why the Azure deployment fails and why/where System.Web.MVC Version=4.0.0.0 is being referenced?

您可能会从这里得到答案blog。它阐述了根本原因和解决方案。以下是博客的片段。

解法:

1) Open the .dll.config located in your project bin folder.

2) Check if there is the BindingRedirect entry that you need. If not, follow one of the two options below:

  • Copy the web.config or app.config content (considering one of these two configuration files has the information that you need) and paste it into the .dll.config file.

  • Manually create an Assembly Binding entry:

3) Add the .dll.config file to your Solution (same level as the web.config or app.config) and set the Copy to Output Directory property to “Copy Always”.

根本原因:

Usually, when a new assembly is added to your project, Visual Studio will automatically create a bindingRedirect entry in your web.config (Web Role) or app.config (Worker Role) just to avoid the wrong assembly version issue.

However, in Azure Cloud Services, the assembly bindings from web.config and app.config does not have effect, due to the fact that WaIISHost (Web Role) and WaWorkerHost (Worker Role) are not able to read these two configuration files, instead, they read the .dll.config file, and this is the file where the assembly binding configuration need to be