Cosmos DB provider in Entity Framework Core throwing 400 BadRequest

azure-cosmosdb azure-cosmosdb-sqlapi c# entity-framework-core

Question

I've integrated Cosmos DB in my ASP.NET Core API project, using the latest EF Core package that ships with a Cosmos DB provider.

I'm able to successfully use this provider when running locally in my local ASF cluster, connecting to a local Cosmos DB emulator instance. However, when trying to either run in local ASF or Azure-hosted ASF, I'm unable to connect to the Azure Cosmos DB instance. For some reason I keep getting a 400 BadRequest when initializing the seed for the database/collection.

It's the following line that is generating an error:

var created = await context.Database.EnsureCreatedAsync();

Exception:

BadRequest at Microsoft.EntityFrameworkCore.Cosmos.Storage.Internal.CosmosClient.CreateDocumentCollectionIfNotExistsOnceAsync(DbContext _, String collectionId, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementationAsync[TState,TResult](Func4 operation, Func4 verifySucceeded, TState state, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementationAsync[TState,TResult](Func4 operation, Func4 verifySucceeded, TState state, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Cosmos.Storage.Internal.CosmosDatabaseCreator.EnsureCreatedAsync(CancellationToken cancellationToken) at Infrastructure.SystemDataContextSeed.SeedAsync(SystemDataContext context) in Infrastructure\SystemDataContextSeed.cs:line 21 at xtensions.IWebHostExtensions.Seed(IWebHost webhost) in Extensions\IWebHostExtensions.cs:line 23 at Api.<>c__DisplayClass1_0.b__1(String url, AspNetCoreCommunicationListener listener) in AccountApi.cs:line 47 at Microsoft.ServiceFabric.Services.Communication.AspNetCore.AspNetCoreCommunicationListener.OpenAsync(CancellationToken cancellationToken) at Microsoft.ServiceFabric.Services.Runtime.StatelessServiceInstanceAdapter.OpenCommunicationListenersAsync(CancellationToken cancellationToken)

What I've tried:

  • Analysing log analytics, shows no logging for these requests
  • Removing the EnsureCreated and just directly insert data
  • Create the collection manually (SystemDataContext)
  • Create the database manually (AccountService)
  • Removing networking firewall (Allow all networks) in azure

The endpoint details used are in the form of:

"Cosmos": {
    "EndPoint": "https://xxxx-sqlapi.documents.azure.com:443",
    "AuthKey": "xxx==",
    "DatabaseName": "AccountService"
  },

Extension method to hook up the Cosmos DB provider:

public static IServiceCollection AddCosmosSettings(this IServiceCollection services, IConfiguration configuration)
        {
            services.AddEntityFrameworkCosmos()
                   .AddDbContext<SystemDataContext>(options =>
                   {
                       options.UseCosmos(configuration["Cosmos:EndPoint"], configuration["Cosmos:AuthKey"], configuration["Cosmos:DatabaseName"]); ;
                   },
                       ServiceLifetime.Scoped  //Showing explicitly that the DbContext is shared across the HTTP request scope (graph of objects started in the HTTP request)
                   );

            return services;
        }

Any ideas are greatly appreciated!

1
1
12/8/2018 2:32:16 PM

Accepted Answer

For reference, the Cosmos DB provider in EF Core 2.2 is a preview, and is not suitable for use against an Azure-hosted Cosmos DB. This is because in some places, headers are missing that are apparently not an issue for the emulator, but cause a 400 when exeuting against Azure.

The issue I was looking at the longest, was the fact that I got a 400 when it was trying to create the document collection. After digging in the EF Core sourcecode, I saw that it did not sent any partition keys. There is actually no implementation of partition keys at all in the current Cosmos DB implementation. And because I created a database in Azure with shared throughput across collections, you are required to provide a partition key on collection level apparently.

2
12/24/2018 9:36:02 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow