Azure function get path of http trigger - azure

I have a http trigger function app which redirects myAPI.com to a version based on the header:
public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
var version = req.Headers["x-version"];
if(version.ToString() == "2"){
return new RedirectResult("https://v2.myAPI.com", false);
}
else{
return new RedirectResult("https://v1.myAPI.com", false);
}
}
This works. However if I have a path e.g myAPI.com/customPath it returns 404 for myAPI.com/customPath. I want to redirect to https://v1.myAPI.com/customPath. Thought this would be simple; however I am unable to get the original url from within the function app.
When I try req.Path.Value it gives me /api/HttpTrigger1. How can I get the path or full url of my original post address (myAPI.com/customPath)?

You could use Microsoft.AspNetCore.Http.Extensions.UriHelper.GetEncodedUrl(req) to get the full path. It returns the combined components of the request URL in a fully escaped form suitable for use in HTTP headers and other HTTP operations.

Related

not able to pass value to controller from routes

in Codeigneter 4 i have created a method in my controller and then added his route URL in routes.php. its working when I am not trying to receive a parameter but when I want to receive a parameter it gives the error 404 page not found.
My Controller Method
public function ViewProduct($param=1)
{
echo $param;
}
my Routes.php File
$routes->get('product/(:any)', 'Public/Publiccontroller::ViewProduct/$1'); Not Working
but when I add like this its work fine
$routes->get('product', 'Public/Publiccontroller::ViewProduct/'); Working
look t example
query url httpss://exmple.com/home/ViewProduct?age=35
public function ViewProduct($id=1)
{
$age=$_GET['age'];
}
param url httpss://exmple.com/home/ViewProduct/45454
this one receive in function
public function ViewProduct($id=1)
{
echo $id;
}
https://codeigniter.com/user_guide/incoming/routing.html?highlight=route

Azure 404 not found when adding new function app to logic app

I have a simple Azure Logic app that is trigger by a new email and then passes the Body to my Function App to remove HTML.
I am getting a 404 not found error and I'm a bit stuck as to what is actually not being found.
I can click on the url and it tells me that my function app is up and running and I've selected the Function App from a list in the Logic App editor.
Are there any log files or something that can provide a bit more information as to what cannot be found?
I think the issue might be that my Function app hasn't published correctly. In VS I am getting a missing trigger attribute but I'm not sure what to add.
Code:
public static class Function1
{
[FunctionName("RemoveHTMLfunction")]
public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
log.LogInformation("HttpWebhook triggered");
string emailBodyContent = await new StreamReader(req.Body).ReadToEndAsync();
String updatedBody = WebUtility.HtmlDecode(RemoveHtmlMarkup(emailBodyContent));
return (ActionResult)new OkObjectResult(new { updatedBody });
}
If you just want to get the body without HTML of the email, you can use Body Preview:
According to the running results, the body obtained by Body has HTML, but Body Preview does not.

How to open web brower by using AWS post lambda

I have written the piece of code below:
static async postSearchResult(httpContext: HttpContext, injector: Injector) {
const log = injector.get(Log);
const service = injector.get(Service);
try {
let result = await service.redirectToUI(JSON.parse(httpContext.getRequestBody()));
httpContext.ok(result, 200, {'Content-Type': 'application/json'});
} catch (e) {
httpContext.fail(e, 500);
}
}
protected redirectToUI(response: any) {
// If any post api call happened then it should open web browser and pass some field as query parameter
window.open("https://www.google.com?abc=response.abc");
return response ? response : "failed";
}
Here I am getting the following error :
Execution failed ReferenceError: Window is not defined
What am I doing wrong?
What you are trying to accomplish doesn't make much of a sense. Lambda is a back-end service. To open new browser window, you need to use front-end JavaScript, not back-end Node (on the back-end, you have no access to the front-end window object).
If you want to open a new browser window as a reaction to some back-end response, then you can send some indicator in the HTTP response (i.e shouldOpenNewWindow: true as a part of the response object), parse that response on the front-end and it the indicator is present, then you can issue window.open command. But it has to be done on front-end.

Servicestack Display 404 page CatchAllHandlers

Im using servicestack Core with kestrel. I made a CatchAllHandlers delegate with the following code.
var requestType = typeof(NotFoundPage);
var restPath = new RestPath(requestType, pathInfo);
return new RestHandler { RestPath = restPath, RequestName = restPath.RequestType.GetOperationName(), ResponseContentType = contentType };
But the problem is that my ServicestackApi now is no longer reachable, url: /json/reply/GetApiCall goes to the 404 not found page.
Is there a way to solve this? can i check if its an api call or can i go later in the pipeline to handle the request?
update
I found that if i remove CatchAllHandler and just add the next middleware this middleware is called:
app.Use((context, next) =>
{
context.Response.Body.Write("yaayaya");
return Task.CompletedTask;
});
But this is not what i want, i want to stay inside the servicestack request.
update 2
Looking at the source-code i find HttpHandlerFactory has a property NotFoundHttpHandler Which is filled from the AppHost.
CustomErrorHttpHandlers.Add(HttpStatusCode.NotFound, new PageNotFoundHandler());
The only downside is that i can't provide any request specific information to this Urlhandler, such as the url itself:
public class PageNotFoundHandler : RestHandler
{
public PageNotFoundHandler()
{
var restPath = new RestPath(typeof(Error404), "/Url/For?");
}
}
Trying to make this work but i'm getting stuck on that my RestHandler has different amount of components than the url since this PageNotFoundHandler is made before the RestHandler.
But Basically what im looking for is to Handle a different service/InputDto
I've tried RequestConverters but this code is not reached when CatchAllHandlers doesn't return an Handler. so im stuck in this space in the middle. Anyway i could make all the left over routes, route to a single Dto?
.NET Core's new pipeline programming model expects you to call the next middleware if it wasn't already handled by any of the previously registered middleware which is how .NET Core lets you combine multiple different middlewares into the same App.
Handling Not Found Requests with the last Middleware
The last middleware that's registered will be able to handle any unhandled requests so for instance if you wanted to return a static image for unhandled requests you could register middleware after ServiceStack, e.g:
app.UseServiceStack(new AppHost());
app.Use(new StaticFileHandler("wwwroot/img/404.png"));
Or if you wanted to return a custom 404 page instead:
app.Use(new RazorHandler("/404"));
Which will render the /wwwroot/404.cshtml Razor View with ServiceStack's MVC Razor Views.
This would be the preferred way to handle Not Found requests in .NET Core in which you will be able to register additional middleware after ServiceStack to handle non-ServiceStack requests.
Calling a ServiceStack Service for unhandled requests
If you wanted to call a ServiceStack Service for any unhandled requests you can use a Fallback Route which matches on any request, e.g:
[FallbackRoute("/{Path*}")]
public class Error404
{
public string Path { get; set; }
}
public class UnhandledRequestService : Service
{
public object Any(Error404 request) => ...;
}

CORS on Web API and MVC 5 Controller: Upload images with fetch and FormData

I have an application that has the front and back ends running on different .NET projects.
The front end is an Aurelia web application running on ASP.NET 5. This Aurelia app (from now on The FrontEnd) gets all it's data from a Web API 2/MVC 5 application (henceforth, The BackEnd).
Since The FrontEnd and the BackEnd are different applications I have CORS setup, both for the Web API and in the Start.Auth.cs for the token bearer request.
The FronEnd is running on http://localhost:49850.
Now, for some code (this is all in the BackEnd)
Start.Auth.cs
The whole of the application resides behind a log-in form, so inside the Start.Auth.cs file, other than setting up the token-based authentication on the static Startup(), method I have a bit of middleware that adds the Access-Control-Allow-Origin header to the request on the one case where there is no token available yet: when we are requesting one.
public void ConfigureAuth(IAppBuilder app)
{
app.Use(async (context, next) =>
{
if (context.Request.Path.Value.Equals("/token"))
context.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "http://localhost:49850" });
await next();
});
app.UseCors(CorsOptions.AllowAll);
app.UseOAuthAuthorizationServer(OAuthOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
}
WebApiConfig.cs
Here I just added the EnableCorsAttribute so that it is enable globally.
var enableCors = new EnableCorsAttribute("http://localhost:49850", "*", "*");
config.EnableCors(enableCors);
Uploading files
Everything works fine; I can perform GET and POST requests to the Web API without a problem, the problem comes when trying to upload images.
To upload to files I have an action method in an ASP.NET MVC controller called FileControler.
FileController.cs
[HttpPost]
public ActionResult UploadImage(string id, string name = "")
{
var files = (from string fileName in Request.File
select Request.Files[fileName]
into file
where file != null
select DoSomethingWithTheFile(file, id)).ToList();
// ...
return Json(arrayWithFileUrls);
}
Calling the MVC controller
This is already part of The FrontEnd.
To call this method I use Aurelia's Fetch Client:
upload(url, data, files) {
let formData = new FormData();
for (let key of Object.keys(data)) {
formData.append(key, data[key]);
}
for (let i = 0; i < files.length; i++) {
formData.append(`files[${i}]`, files[i]);
}
return this.http.fetch(url, {
method: "POST",
body: formData,
headers: {
cmsDatabase: sessionStorage["cmsDatabase"]
}
}).then(response => {
return response.json();
}).catch(error => {
console.log(error);
});
}
And here's a call to the upload method above:
// files comes from an <input type="file" />
upload("http://localhost:64441/file/uploadImage", { id: id }, files)
.then((uploadedPhotos) => {
// do something with those file urls...
});
The Problem
All this works if I remove all CORS setup from WebApiConfig.cs, and in Startup.Auth.cs I substitute the call to the middleware for app.UseCors(CorsOptions.AllowAll);, so I know my code is ok, but as soon as I use the CORS setup described above, everything works except the call to http://localhost:64441/file/uploadImage, returning even a 404:
Fetch API cannot load http://localhost:64441/file/uploadForSku.
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin'
header is present on the requested resource.
Origin 'http://localhost:49850' is therefore not allowed access.
The response had HTTP status code 404. If an opaque response serves your needs,
set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
The "funny" thing is that if I try calling that url with, for intance, REST Console I don't get a 404.
I've tried adding the [HttpOptions] attribute to the action method; I've tried creating ActionFilterAttributes as described here and here, and even setting uip CORS from within the web.config, but to no avail.
I know the problem is that FileController is a regular MVC Controller instead of a Web API controlle, but shouldn't it still be possible to get CORS working?
have you tried this
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
in ApplicationOAuthProvider.cs file

Resources