繁体   English   中英

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

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

我有一个 Node Http 触发的 azure 函数,它在响应正文中返回一个数组。 我想在 C# 控制台应用程序中调用此函数并访问 azure 函数返回的数组。 当我在邮递员上点击它时,我的 azure 函数返回预期的响应正文。 但是,当我在 c# 应用程序上调用此端点时,情况并非如此,因为我正在获取状态为 200 但内容长度为 -1 的响应对象。 请注意,如果我在 c# 应用程序中对普通的 express 应用程序执行相同的调用,我能够得到预期的响应

这是我的 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"
        };
    }
};

这是我用于调用的 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;
    }


}

响应中可能缺少Content-Header 如果你检查HttpWebResponse.ContentLength你会得到一个-1 正如文档解释的那样:

如果响应中未设置 Content-Length 标头,则 ContentLength 设置为值 -1。

HttpWebRequest 和 HttpWebResponse 是非常老的类,它们在很大程度上被 HttpClient 取代,尤其是在 .NET Core 中。 创建这些类时没有可空值类型,因此它们只能返回-1

所有这些都应该用 HttpClient 代替。 代码不仅更简单,类本身也是线程安全的,可以重用。 它将套接字缓存在下面,这意味着应用程序不必在每次尝试调用同一个端点时支付 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);

此时您可以检查状态代码:

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

Content-Length是一个内容头。 它可能会丢失,在这种情况下ContentLength属性将为 null :

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

或者,使用模式匹配:

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

最后,您可以使用ReadAsStringAsync将响应作为字符串ReadAsStringAsync并反序列化。 该方法将负责解码响应正文:

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

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM