HTTP trigger azure function having problems when not running locally - c#

I have a basic HTTP trigger azure function in Visual Studio (C#):
[FunctionName("HttpTriggerCSharp")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
HttpRequest req, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
return name != null
? (ActionResult)new OkObjectResult($"Hello, {name}")
: new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}
But I'm having 2 issues with this:
(1) I only want it to receive 'Post' requests. But when I take out the "get" from the arguments the function no longer receives my requests in Azure. I get a 404 Not Found. But locally it stills receives my request and works fine.
(2) Additionally the body of the request is not received in Azure. Its empty. Once again when running locally no such problems occur.
I found several cases of people having the issue (2), but haven't found a way to solve. As to issue (1), haven't found any similar cases posted online yet.
Does anyone have any idea on why this is happening?

Related

returning multiple objects from a function [C#],[ASP.NET Core]

I have a function which is checking if the user has correct role assigned to it.
So if the user doesn't have the correct role I'm returning Forbid() so it can be redirected to login page.
But now I want to have a toster message displaying the appropriate message why it is being redirected.
So I looking for way how can I display that toast message and redirect to login page.
[FunctionName("SampleResponse")]
public static async Task<IActionResult> SampleResponse(
[HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
string name = data.name; // get name from dynamic/JSON object
if (name == null)
{
// Return a 400 bad request result to the client with additional information
return new BadRequestObjectResult("Please pass a name in the request body");
}
// Return a 200 OK to the client with additional information
return new OkObjectResult($"{name} exists");
}
your UI should check the response message, then perform the redirect.

Using Azure Function (.NET Core) to Download a file

I have created and HTTP Triggered Azure Function (v2) using .NET Core with the hopes that I can execute the function while passing in some info in the request body and then have the function return/download a file in the browser. Unfortunately I am struggling to get this working.
Below is a snippet of Code
public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequest req, ILogger log)
{
string csv;
//Do some stuff to create a csv
byte[] filebytes = Encoding.UTF8.GetBytes(csv);
req.HttpContext.Response.Headers.Add("content-disposition", "attachment;filename=Export.csv");
req.HttpContext.Response.ContentType = "application/octet-stream";
return (ActionResult)new OkObjectResult(filebytes);
}
When I do a post using Postman the request is accepted but the response is 406 "unacceptable" and the output in the log states
"Microsoft.AspNetCore.Mvc.Infrastructure.DefaultOutputFormatterSelector[1]
No output formatter was found for content type 'application/octet-stream' to write the response."
I've tried multiple content types including text/plain and text/csv, all give the same response about output formatting.
If I remove or comment out the ContentType the request processes and returns a 200 but the filebytes are returned in the response body instead of being downloaded in the browser.
You'll need a FileContentResult for this:
public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequest req, ILogger log)
{
string csv;
//Do some stuff to create a csv
byte[] filebytes = Encoding.UTF8.GetBytes(csv);
return new FileContentResult(filebytes, "application/octet-stream") {
FileDownloadName = "Export.csv"
};
}
While the comments correctly point out that the ideal solution is to kick off processing in the HTTP function asynchronously, return a 202 Accepted response, save the result to blob storage, have the client wait for processing to complete before starting the blob download and then delete the blob once it's been downloaded, current Azure Functions pricing is only $0.000016/GB-s so you may find that to be unnecessarily complicated unless you have quite high traffic.

Azure Function Return Deprecated API Header

I have an Azure Function that sits behind a proxy. If an update occurs to the objects that get returned we want to deprecate the Function after a period of time. I'm trying to create a response with the expected content from an HTTP Header by using what was provided in this solution.
Warning: 299 - "Deprecated API"
I try to append the Azure Function like so:
[FunctionName("MyAPI")]
public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function,
"post", Route = null)]
HttpRequestMessage req,
TraceWriter log)
{
object response = await someService.Get();
if (settingsService.IsDeprecated)
{
var httpresponse = req.CreateResponse(HttpStatusCode.OK, response, "application/json");
httpresponse.Content.Headers.Add("Warning", "299 - Deprecated API");
return httpresponse;
}
return req.CreateResponse(HttpStatusCode.OK, response, "application/json");
}
I get the Exception
Exception while executing function: MyAPI -> Misused header name. Make sure request headers are used with HttpRequestMessage, response headers with HttpResponseMessage, and content headers with HttpContent objects.
How do I append the "Deprecated" status warning in my API Http Response?
Change your line to
httpresponse.Headers.Add("Warning", "299 - \"Deprecated API\"");
The quotes seem to be important there to adhere to the format requirement.

Retrieving body of json Object of an http Request C#

I have the problem, that I can't retrieve the body of a POST statement of a JSON Object. Here is the function, which is called when executing the http-Request:
public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "HttpTriggerCSharp/name/{name}")]HttpRequestMessage req, string name, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
string output = JsonConvert.SerializeObject(req.Content.ToString());
// Fetching the name from the path parameter in the request URL
return req.CreateResponse(HttpStatusCode.OK, output);
}
Im executing the POST with Postman and the following URL: http://localhost:7071/api/HttpTriggerCSharp/name/test
In the Header I wrote "Content-Type: application/json" and the Body looks like this:
{
"Benutzer":"Nenad",
"Passwort":"test"
}
My result is this: "\"System.Net.Http.StreamContent\""
Thank you for your help!
Thanks for the answers guys,
i found now an other solution with the help of a friend, this is the following:
public static async System.Threading.Tasks.Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "HttpTriggerCSharp/name/{name}")]HttpRequestMessage req, string name, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
dynamic dataArray = await req.Content.ReadAsAsync<object>();
string output = dataArray.ToString();
var data = Newtonsoft.Json.JsonConvert.DeserializeObject<Benutzer>(output);
// Fetching the name from the path parameter in the request URL
return req.CreateResponse(HttpStatusCode.OK, data);
}
Content is an instance of HttpContent class (as you can see in your output). So you have to use an appropriate method to get the string.

Azure Functions C# Http Trigger does not return response

If have a simple HTTP triggered function in C# which just doesn't return the result:
public static HttpResponseMessage Run(HttpRequestMessage req, TraceWriter log)
{
string jobId = req.Headers.GetValues("scheduler-jobid").FirstOrDefault();
string executionTime = req.Headers.GetValues("scheduler-expected-execution-time").FirstOrDefault();
return req.CreateResponse(HttpStatusCode.OK,new {
JobId = jobId,
ExecutionTime = executionTime}
);
}
I checked with POSTMAN that HTTP headers are set correctly but just get a 200 OK without a response body.
In hindsight the solution is obvious:
I had to define a HTTP Response output and without changing the code above the Azure Functions runtime automatically wires in the req.CreateResponse.

Categories