[英]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.