Following the ASP.NET MVC example here, I've implemented the Google Admin SDK in my web application so that I can get a list of organizational units and/or users associated with an organizational unit using the Directory service.
Everything works great locally (the auth callback works because I leverage ngrok to hit my local box), but when I deploy to a cloud service in MS Azure, the application won't start, and I see the following error in the event log:
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'
I'm using ASP.NET MVC version 5.2.3 in my .NET 4.5 web application, and the setting below in my web.config. It's not clear to me exactly where this explicit reference is coming from for version 4.0.0.0, but I've redeployed my app with and without the references to the Google API libraries, and the error definitely occurs when I'm referencing the Google API libraries.
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
The first few times I got the error, I assumed it was because I was using a FileDataStore object in my AppFlowMetadata class, and local file storage might not be available in an Azure cloud service. So finding this SO post, I created my own database store that implements the IDataStore interface, and that works great locally as well, but deploying to Azure results in the same error as listed above.
Does anyone know why the Azure deployment fails and why/where System.Web.MVC Version=4.0.0.0 is being referenced?
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; }
}
}