Migrate .NET Azure function app from the in-process model to the isolated worker model

Aml Abbas 45 Reputation points
2024-05-07T09:21:52.72+00:00

Hello,

After migrating my Azure function app from in-process model to isolated worker model

I got this issue

Unable to cast object of type 'System.String' to type 'Microsoft.Azure.WebJobs.Extensions.DurableTask.IDurableOrchestrationContext'.

My httpTrigger

[Function("ResponseHandler_HttpStart")]

public async Task<HttpResponseData> HttpStart(

  [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req,

  [DurableClient] DurableTaskClient starter)

{

            byte[] requestBodyBytes;

              using (var ms = new MemoryStream())

              {

                  await req.Body.CopyToAsync(ms);

                  requestBodyBytes = ms.ToArray();

              }

              string formData = Encoding.UTF8.GetString(requestBodyBytes);

              var formDataDict = ParseFormData(formData);

              WebhookResponse webhookResponse = new WebhookResponse();

              foreach (var keyValuePair in formDataDict)

              {

                  var key = keyValuePair.Key;

                  var value = keyValuePair.Value;

                  switch (key)

                  {

                      case "document_id":

                          webhookResponse.document_id = value;

                          break;

                      case "document_json":

                          webhookResponse.document_json = JsonConvert.DeserializeObject<DocumentJson>(System.Web.HttpUtility.UrlDecode(value));

                          break;

                      case "document_signed_and_sealed":

                          webhookResponse.document_signed_and_sealed = Convert.ToBoolean(value);

                          break;

                      default:

                          break;

                  }

              }

              string content = JsonConvert.SerializeObject(webhookResponse);

              logger.LogInformation($"webhookResponse is = {content}.");

              string instanceId = await starter.ScheduleNewOrchestrationInstanceAsync("O-ResponseHandler", content);

              logger.LogInformation($"Started orchestration with ID = '{instanceId}'.");

              return starter.CreateCheckStatusResponse(req, instanceId);

          }

}

My Orchestration

[Function("O-ResponseHandler")]

public async Task RunOrchestrator(

 [OrchestrationTrigger] TaskOrchestrationContext context)

{

     var webhookResponseString = context.GetInput<string>();

     var webhookResponse = JsonConvert.DeserializeObject<WebhookResponse>(webhookResponseString);

     string status = webhookResponse.document_json.status;

     if (status == "closed" || status == "rejected")

     {

         DocumentDB documentDB = await context.CallActivityAsync<DocumentDB>($"A-{nameof(GetDocumentFromDB)}", webhookResponse.document_id);

     }

 }

}

Azure Functions
Azure Functions
An Azure service that provides an event-driven serverless compute platform.
5,909 questions
{count} votes

2 answers

Sort by: Most helpful
  1. LeelaRajeshSayana-MSFT 17,766 Reputation points Moderator
    2024-05-08T22:27:22.5+00:00

    Hi @Aml Abbas Thank you for sharing additional information on this. I have looked deeper into this issue and you are correct that you would not need an explicit Task<string> returned from the orchestrator function. The method call ScheduleNewOrchestrationInstanceAsync on the DurableTaskClient returns a Task<String> which has the value for the Instance ID.

    Even though the function signatures look same in the cases where the migration is successful vs unsuccessful, I see that in the initial function, you are using WebhookResponse object and JSON serialization. I would like to note that the isolated worker model uses System.Text.Json by default whereas the in-process model uses Newtonsoft.Json

    You can modify this behavior by reassigning the Serializer property on the WorkerOptions configuration. The following example shows this using ConfigureFunctionsWebApplication

    var host = new HostBuilder()
        .ConfigureFunctionsWebApplication((IFunctionsWorkerApplicationBuilder builder) =>
        {
            builder.Services.Configure<WorkerOptions>(workerOptions =>
            {
                var settings = NewtonsoftJsonObjectSerializer.CreateJsonSerializerSettings();
                settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                settings.NullValueHandling = NullValueHandling.Ignore;
    
                workerOptions.Serializer = new NewtonsoftJsonObjectSerializer(settings);
            });
        })
        .Build();
    
    
    

    Please refer the article section - Customizing JSON serialization for more details.

    Here is another article for your reference to get more information on behavior changes when Migrating from Newtonsoft.Json to System.Text.Json

    If you still encounter the issue after trying the above steps, please share the error stack from the Azure function logs to help us better understand the origination of the issue.


    If the response helped, please do click Accept Answer and Yes for the answer provided. Doing so would help other community members with similar issue identify the solution. I highly appreciate your contribution to the community.


  2. Aml Abbas 45 Reputation points
    2024-05-10T13:43:11.57+00:00

    LeelaRajeshSayana-MSFT Here is a pic of my .scproj

    User's image

    User's image

    my host.json

    User's image

    before I had this hubname and as setting in azure function app but I delete it now

    I had this error

    microsoft.azure.webjobs.extensions.durabletask: task hub name '%taskhubname%' should contain only alphanumeric characters, start with a letter, and have length between 3 and 45. microsoft.windowsazure.storage: invalid container name. check msdn for more information about valid container naming

    User's image

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.