Azure / azure-webjobs-sdk

Azure WebJobs SDK
MIT License
737 stars 358 forks source link

Tables binding fails when reading JObject entity written by Azure.Data.Tables from Cosmos Tables #2813

Open pakrym opened 2 years ago

pakrym commented 2 years ago

Tables binding fails when reading JObject entity written by Azure.Data.Tables from Cosmos Tables

Microsoft.Azure.WebJobs.Host.FunctionInvocationException : Exception while executing function: GetEntityProgramT1`1.Call
  ----> System.InvalidOperationException : Exception binding parameter 'entity'
  ----> System.ArgumentException : Can not add property PartitionKey to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 343
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.TryExecuteAsync(IFunctionInstance functionInstance, CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 105
   at Microsoft.Azure.WebJobs.Host.Executors.ExceptionDispatchInfoDelayedException.Throw() in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\ExceptionDispatchInfoDelayedException.cs:line 28
   at Microsoft.Azure.WebJobs.JobHost.CallAsyncCore(IFunctionDefinition function, Object functionKey, IDictionary`2 arguments, CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\JobHost.cs:line 241
   at Microsoft.Azure.WebJobs.JobHost.CallAsync(MethodInfo method, IDictionary`2 arguments, CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\JobHost.cs:line 204
   at Microsoft.Azure.WebJobs.Extensions.Tables.Tests.TablesLiveTestBase.CallAsync[T](String methodName, Object arguments, Action`1 configure) in D:\github\azure\net\sdk\tables\Microsoft.Azure.WebJobs.Extensions.Tables\tests\TablesLiveTestBase.cs:line 106
   at Microsoft.Azure.WebJobs.Extensions.Tables.Tests.CompatibilityTests.ExtensionT1.Read[T](CompatibilityTests test) in D:\github\azure\net\sdk\tables\Microsoft.Azure.WebJobs.Extensions.Tables\tests\CompatibilityTests.cs:line 413
   at Microsoft.Azure.WebJobs.Extensions.Tables.Tests.CompatibilityTests.CanSaveAndLoadJObject(ITablesClient writer, ITablesClient reader) in D:\github\azure\net\sdk\tables\Microsoft.Azure.WebJobs.Extensions.Tables\tests\CompatibilityTests.cs:line 131
   at NUnit.Framework.Internal.TaskAwaitAdapter.GenericAdapter`1.BlockUntilCompleted()
   at NUnit.Framework.Internal.MessagePumpStrategy.NoMessagePumpStrategy.WaitForCompletion(AwaitAdapter awaiter)
   at NUnit.Framework.Internal.AsyncToSyncAdapter.Await(Func`1 invoke)
   at NUnit.Framework.Internal.Commands.TestMethodCommand.RunTestMethod(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.TestMethodCommand.Execute(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.<>c__DisplayClass1_0.<Execute>b__0()
   at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.RunTestMethodInThreadAbortSafeZone(TestExecutionContext context, Action action)
--InvalidOperationException
   at Microsoft.Azure.WebJobs.Host.Executors.DelayedException.Throw() in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\DelayedException.cs:line 27
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ParameterHelper.PrepareParametersAsync() in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 905
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithWatchersAsync(IFunctionInstanceEx instance, ParameterHelper parameterHelper, ILogger logger, CancellationTokenSource functionCancellationTokenSource) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 483
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 296
--ArgumentException
   at Newtonsoft.Json.Linq.JObject.ValidateToken(JToken o, JToken existing)
   at Newtonsoft.Json.Linq.JContainer.InsertItem(Int32 index, JToken item, Boolean skipParentCheck)
   at Newtonsoft.Json.Linq.JObject.InsertItem(Int32 index, JToken item, Boolean skipParentCheck)
   at Microsoft.Azure.WebJobs.Host.Tables.Config.TablesExtensionConfigProvider.ConvertEntityToJObject(DynamicTableEntity tableEntity) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Extensions.Storage\Tables\Config\TablesExtensionConfigProvider.cs:line 113
   at Microsoft.Azure.WebJobs.Host.Tables.Config.TablesExtensionConfigProvider.JObjectBuilder.Microsoft.Azure.WebJobs.IAsyncConverter<Microsoft.Azure.WebJobs.TableAttribute,Newtonsoft.Json.Linq.JObject>.ConvertAsync(TableAttribute attribute, CancellationToken cancellation) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Extensions.Storage\Tables\Config\TablesExtensionConfigProvider.cs:line 234
   at Microsoft.Azure.WebJobs.Host.Bindings.PatternMatcher.AsyncInvoker`2.<>c__DisplayClass0_0.<<Execute>b__0>d.MoveNext() in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Bindings\PatternMatcher.cs:line 383
--- End of stack trace from previous location ---
   at Microsoft.Azure.WebJobs.Host.Bindings.BindToInputBindingProvider`2.ExactBinding.BuildAsync(TAttribute attrResolved, ValueBindingContext context) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Bindings\BindingProviders\BindToInputBindingProvider.cs:line 213
   at Microsoft.Azure.WebJobs.Host.Bindings.BindingBase`1.BindAsync(BindingContext context) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Bindings\BindingBase.cs:line 50
   at Microsoft.Azure.WebJobs.Host.Bindings.FunctionBinding.BindAsync(ValueBindingContext context, IDictionary`2 parameters) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Bindings\FunctionBinding.cs:line 99

Repro steps

  1. Use Cosmos Tables

  2. Publish an entity using Azure.Data.Tables:

var table = new TableServiceClient(connectionString).GetTableClient("testtable");
table.CreateIfNotExists();
table.AddEntity(new TableEntity("Pk", "Rk"));
  1. Try to consume the entity using a function with JObject parameter:
        private class GetEntityProgram
        {
            public void Call([Table("testtable", "Pk", "Rk")] JObject entity)
            {
            }
        }

Expected behavior

Works.

Actual behavior

Throws an exception.

Related information

pakrym commented 2 years ago

cc @christothes