简体   繁体   English

在 .NET core c# 控制台应用程序中调用 Node Http Triggered azure 函数

[英]Call a Node Http Triggered azure function inside a .NET core c# console application

I have a Node Http triggered azure function that returns an array in the response body.我有一个 Node Http 触发的 azure 函数,它在响应正文中返回一个数组。 I want to call this function inside a C# console application and access the array returned by the azure function.我想在 C# 控制台应用程序中调用此函数并访问 azure 函数返回的数组。 My azure function returns the expected response body when I hit it on postman.当我在邮递员上点击它时,我的 azure 函数返回预期的响应正文。 However this is not the case when I call this endpoint on the c# application as I'm getting a response object with status 200 but content-length is -1.但是,当我在 c# 应用程序上调用此端点时,情况并非如此,因为我正在获取状态为 200 但内容长度为 -1 的响应对象。 Please note if I do the same call for a normal express application in the c# application, I'm able to get the expected response请注意,如果我在 c# 应用程序中对普通的 express 应用程序执行相同的调用,我能够得到预期的响应

Here is my azure function这是我的 azure 函数

    const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {

    context.log('HTTP trigger function processed a request.');
    const adresses = req.body && req.body.adresses;

    if (adresses) {

        //make an asyn function call
        const locationsPromise = await adresses.map(async (address) => await getLocationCoordinates(address));
        const resolvedLocations = await Promise.all(locationsPromise);
        context.res = await {
            // status: 200, /* Defaults to 200 */
            body:{ data: resolvedLocations}
        };
    }
    else {
        context.res = await  {
            status: 400,
            body: "Please pass a adresses in the request body"
        };
    }
};

Here is my C# code I'm using for the call这是我用于调用的 C# 代码

  {
    string[] adresses = new string[] { "nairobi", "nakuru", "kericho" };
    string apiUrl = "http://localhost:7071/api/Adress-call";
    Dictionary<string, string[]> postData1 = new Dictionary<string, string[]>()
    {
        { "adresses", adresses },

    };

    var postData = JsonConvert.SerializeObject(postData1);
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(apiUrl);
    request.Method = "POST";
    request.ContentType = "application/json";
    request.ContentLength = postData.Length;
    using (Stream webStream = request.GetRequestStream())
    using (StreamWriter requestWriter = new StreamWriter(webStream, Encoding.ASCII))
    {
        requestWriter.Write(postData);
    }
    try
    {
        WebResponse response = request.GetResponse();
        using (Stream responseStream = response.GetResponseStream())
        {
            StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
            DataTable ds = new DataTable();
            var pageViewModel = JsonConvert.DeserializeObject<List<LocationModel>>(reader.ReadToEnd());

        }
    }
    catch (WebException ex)
    {
        WebResponse errorResponse = ex.Response;
        using (Stream responseStream = errorResponse.GetResponseStream())
        {
            StreamReader reader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
            String errorText = reader.ReadToEnd();
            // log errorText
        }
        throw;
    }


}

The Content-Header may be missing from the response.响应中可能缺少Content-Header If you check the HttpWebResponse.ContentLength you'll get a -1 .如果你检查HttpWebResponse.ContentLength你会得到一个-1 As the docs explain:正如文档解释的那样:

If the Content-Length header is not set in the response, ContentLength is set to the value -1.如果响应中未设置 Content-Length 标头,则 ContentLength 设置为值 -1。

HttpWebRequest and HttpWebResponse are really old classes that are largely replaced by HttpClient, especially in .NET Core. HttpWebRequest 和 HttpWebResponse 是非常老的类,它们在很大程度上被 HttpClient 取代,尤其是在 .NET Core 中。 There were no nullable value types back when these classes were created, so they can only return -1 .创建这些类时没有可空值类型,因此它们只能返回-1

All of this should be replaced with HttpClient.所有这些都应该用 HttpClient 代替。 The code isn't just simpler, the class itself is thread-safe and can be reused.代码不仅更简单,类本身也是线程安全的,可以重用。 It caches sockets underneath, which means the app doesn't have to pay the DNS resolution tax each time it tries to call the same endpoint :它将套接字缓存在下面,这意味着应用程序不必在每次尝试调用同一个端点时支付 DNS 解析税:

var data=new { adresses = new [] { "nairobi", "nakuru", "kericho" }};
var postData = JsonConvert.SerializeObject(data);
var content=new StringContent(data,Encoding.UTF8,"application/json");

var response=await client.PostAsync(content);

At this point you can inspect the status code :此时您可以检查状态代码:

if (response.StatusCode == ...) // Check status code here.
{
 ...
}

The Content-Length is a Content header. Content-Length是一个内容头。 It may be missing, in which case the ContentLength property will be null :它可能会丢失,在这种情况下ContentLength属性将为 null :

if (response.Content.Headers.ContentLength!=null)
{
    long length=response.Content.Headers.ContentLength.Value;
    //Use the Content length here
}

Or, using pattern matching :或者,使用模式匹配:

if (response.Content.Headers.ContentLength is long length)
{    
    //Use the Content length here
}

Finally, you can read the response as a string with ReadAsStringAsync and deserialize it.最后,您可以使用ReadAsStringAsync将响应作为字符串ReadAsStringAsync并反序列化。 That method will take care of decoding the response body :该方法将负责解码响应正文:

var json=await response.Content.ReadAsStringAsync();
var models=JsonConvert.DeserializeObject<List<LocationModel>>(json);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在我的 .NET 核心控制台应用程序和 map 变量中运行原始 SQL 语句和 map 变量 - Run raw SQL statement inside my .NET core console application and map the results to C# variables 如何在 c# .net core 3.1 控制台应用程序中保存设置? - how to save settings in c# .net core 3.1 console application? 如何在 Linux 上创建没有控制台的 C#.Net Core 应用程序? - How to create a C# .Net Core application without a console on Linux? C# Console Application.Net core中的分层数据结构菜单 - Hierarchical Data Structure Menu in C# Console Application .Net core 在asp.net核心剃须刀页面应用程序中ajax调用C#函数的“ URL”是什么 - What is the “url” to ajax-call a C# function in an asp.net core razor pages application .net 核心控制台应用程序中的 c# Main() function - c# Main() function in .net core console apps 使用 ExecuteInDefaultAppDomain 调用主函数 C# 控制台应用程序 - Using ExecuteInDefaultAppDomain to call the main function C# console application C# Azure Function .NET Core 3 字符串编码问题 - C# Azure Function .NET Core 3 string Encoding Issue 如何调用 http 触发 azure function 从定时器触发 azure function - How to call http triggered azure function from timer triggered azure function C#.net Core调用Oracle函数错误不是有效月份 - C# .net Core call Oracle function error not a valid month
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM