代码之家  ›  专栏  ›  技术社区  ›  garfbradaz Vivek

正确使用Azure持久函数-序列化复杂对象

  •  1
  • garfbradaz Vivek  · 技术社区  · 7 年前

    Azure持久功能

    根据示例,我创建了一个 Orchestrator客户端 ( HelloOrchestratorClient.cs ),响应 HttpTrigger . 这个客户机从原始请求中提取一些信息,然后启动一个 Orchestrator函数 ( HelloOrchestrator.cs )传递一些提取的信息:

    复杂的HelloOrchestratorClient.cs:

    [FunctionName("HttpSyncStart")]
    public static async Task<HttpResponseMessage> Run(
        [HttpTrigger(AuthorizationLevel.Anonymous, methods: "get", Route = "orchestrators/{functionName}/wait")]
        HttpRequestMessage req,
        [OrchestrationClient] DurableOrchestrationClient starter,
        string functionName,
        ILogger log)
    {       
        HttpReq originalRequest = new HttpReq() {
                DeveloperId = GetDevKey(req,apiHeaderKey),
                QueryString = req.RequestUri.Query,
                APIName = GetQueryStringValue(req,APIName),
                APIVersion = GetQueryStringValue(req,APIVersion)
    
        };
        string instanceId =   await starter.StartNewAsync(functionName, originalRequest);
    
        TimeSpan timeout = GetTimeSpan(req, Timeout) ?? TimeSpan.FromSeconds(30);
        TimeSpan retryInterval = GetTimeSpan(req, RetryInterval) ?? TimeSpan.FromSeconds(1);
    
        return  await starter.WaitForCompletionOrCreateCheckStatusResponseAsync(
            req,
            instanceId,
            timeout,
            retryInterval);
    
    }
    

    这个 HelloOrchestrator.cs公司 现在只需调用一个内部API并返回一个 JsonProduct ActivityTigger 命名 HelloOrchestrator.APICall

    复杂HelloOrchestrator.cs:

      [FunctionName("E1_JsonProduct")]
            public static async Task<List<JsonProduct>> Run(
                [OrchestrationTrigger] DurableOrchestrationContextBase context,
                ILogger log)
            {
                List<JsonProduct> output = new List<JsonProduct>();
                HttpReq r = context.GetInput<HttpReq>();
                if(r != null)
                {
                    if(r.DeveloperId == null)
                    {
                        return output;
                    }
                    output.Add(await context.CallActivityAsync<JsonProduct>("E1_CallAPI",r));
                    return output;
                }
                return output;
            } 
    
    [FunctionName("E1_CallAPI")]
    public async static Task<JsonProduct> APICall([ActivityTrigger] HttpReq req,
        ILogger log)
    {
    
        JsonProduct products  = null;
        string u = $"{baseAddress}{req.APIVersion}/{req.APIName}{req.QueryString}";  
    
        var request = new HttpRequestMessage(HttpMethod.Get, u);
        request.Headers.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json")
        );
        request.Headers.Add("x-apikey",req.DeveloperId);
         log.LogInformation($"URL calling = '{request.RequestUri.AbsoluteUri}'.");
        HttpResponseMessage response = await client.SendAsync(request);
        // return await response.Content.ReadAsStringAsync();
        if(response.IsSuccessStatusCode)
        {
            var formatter = new JsonMediaTypeFormatter
            {
                SerializerSettings = HelloProj.CosmosDB.Models.Products.Converter.Settings
            };
    
            products = await response.Content.ReadAsAsync<JsonProduct>(new [] {formatter});
        }
        return products;
    }
    

    旁注:

    我遇到的问题

    所以,当我的 List<JsonProduct> HelloOrchestrator.Run ,我收到以下信息 NullReferenceException Gist (大堆栈跟踪)我收到一个 Orchestrator客户端

    以下证明了 output 返回的在运行时确实有一个对象:

    Runtime Screen Grab of output

    会不会是因为 here )? 我问,因为当我换掉我的 Orchestrator函数 不要

    此示例显示 简单的Orchestrator函数 HelloOrchestrator.cs公司 ,返回一个简单的 TestToDo.cs Gist for model 不会出错

       [FunctionName("E1_Todo")]
        public static async Task<TestToDo> RunToDo(
        [OrchestrationTrigger] DurableOrchestrationContextBase context,
            ILogger log)
        {
            HttpReq r = context.GetInput<HttpReq>();
            TestToDo todo = new TestToDo();
            if(r != null)
            {
                todo = await context.CallActivityAsync<TestToDo>("E1_CallAPITodo",r);
            }
            return todo;
        }
    
    [FunctionName("E1_CallAPITodo")]
    public async static Task<TestToDo> APITodoCall([ActivityTrigger] HttpReq req,
        ILogger log)
    {
    
        var request = new HttpRequestMessage(HttpMethod.Get, "https://jsonplaceholder.typicode.com/todos/1");
        request.Headers.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json")
        );
         log.LogInformation($"URL calling = '{request.RequestUri.AbsoluteUri}'. for {req.QueryString}");
        HttpResponseMessage response = await client.SendAsync(request);
        return await response.Content.ReadAsAsync<TestToDo>();
    } 
    

    更多信息

    如果你需要我的完整原型项目,你可以在这里找到它们:

    当您运行它时,在Postman中使用以下命令(在f5之后):

    http://localhost:7071/api/orchestrators/E1_JsonProduct/wait?timeout=20&retryInterval=0.25&api=products&apiVersion=v1&filterByImprints=W%26N&N

    当您运行它时,在Postman中使用以下命令(在f5之后):

    http://localhost:7071/api/orchestrators/E1_Todo/wait?timeout=20&retryInterval=0.25

    1 回复  |  直到 7 年前
        1
  •  1
  •   Chris Gillum    7 年前

    看看你发布的调用堆栈 NullReferenceException 似乎是系统中的一个错误 DurableOrchestrationClient 班级。查看代码(您可以找到 here

    您提到您正在使用以下URL进行测试:

    http://localhost:7071/api/orchestrators/E1_JsonProduct/wait?timeout=20&retryInterval=0.25&api=products&apiVersion=v1&filterByImprints=W%26N&N

    &N )是问题的根源。是否可以对 & 或者完全移除它来隔离问题?

    无论哪种方式,如果您可以在此处记录问题,那就太好了: https://github.com/Azure/azure-functions-durable-extension/issues