My local dotnet version is 6.0.400 and dotnet lambda --help shows version 5.4.5.
I have scaffolded a test lambda project with dotnet new serverless.AspNetCoreMinimalAPI -n TestCalc.
If I load this in VSCode and hit F5 it runs just fine; Giving me the classic localhost:5000/calculator responses.
If I then:
Create a new Lambda in the AWS Console
Set the Function URL Auth type to NONE
Check Configure cross-origin resource sharing (CORS)
Set the handler to TestCalc
Set the TestCalc.csproj value PublishReadyToRun to false
Publish the TestCalc project locally with dotnet publish -c Release --output=publish
Zip the contents of the \TestCalc\publish folder
Upload the publish.zip file to the Lambda
And hit the function URL, I get this error logged to CloudWatch:
System.NullReferenceException: Object reference not set to an instance of an object.
at Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction.MarshallRequest(InvokeFeatures features, APIGatewayProxyRequest apiGatewayRequest, ILambdaContext lambdaContext)
at Amazon.Lambda.AspNetCoreServer.AbstractAspNetCoreFunction`2.FunctionHandlerAsync(TREQUEST request, ILambdaContext lambdaContext)
at Amazon.Lambda.RuntimeSupport.HandlerWrapper.<>c__DisplayClass26_0`2.<<GetHandlerWrapper>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Amazon.Lambda.RuntimeSupport.LambdaBootstrap.InvokeOnceAsync(CancellationToken cancellationToken)
It appears (to me) that the function is being invoked but the AWS Lambda library is failing to receive something it expects.
How can I give it what it needs?
The generated code (plus some logging from me) is this:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Add AWS Lambda support. When application is run in Lambda Kestrel is swapped out as the web server with Amazon.Lambda.AspNetCoreServer. This
// package will act as the webserver translating request and responses between the Lambda event source and ASP.NET Core.
builder.Services.AddAWSLambdaHosting(LambdaEventSource.RestApi);
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.MapGet("/", () => "Welcome to running ASP.NET Core Minimal API on AWS Lambda");
app.Logger.LogInformation($"before app.Run()"); // appears in CloudWatch
app.Run();
app.Logger.LogInformation($"after app.Run()"); // does NOT appear in CloudWatch
After finding this github post I figured I should check the options on the LambdaEventSource and switched it to LambdaEventSource.HttpApi. This solved the problem.
Related
I have encountered a strange behavior when trying to connect to Azure App Configuration with an Azure Identity from an ASP.Net Web Application. Current environment is .Net Framework 4.8, but the behavior is the same on 4.7.2 and 4.6.1.
I am using Microsoft.Extensions.Configuration.AzureAppConfiguration 4.0.0 and Azure.Identity 1.3.0. During local development I am using a service principal (AZURE_TENANT_ID, AZURE_CLIENT_ID and AZURE_CLIENT_SECRET defined in environment) and on Azure the system assigned ManagedIdentity of the app service.
private IConfiguration GetConfiguration(string label = null)
{
TokenCredential credential = new DefaultAzureCredential();
return new Microsoft.Extensions.Configuration.ConfigurationBuilder()
.AddAzureAppConfiguration(options =>
{
options = options.Connect(
new Uri(Environment.GetEnvironmentVariable("APP_CONFIGURATION_ENDPOINT")), credential)
.ConfigureKeyVault(kv => { kv.SetCredential(credential); });
if (!string.IsNullOrEmpty(label))
{
options.Select(KeyFilter.Any, label);
}
else
{
options.Select(KeyFilter.Any, LabelFilter.Null);
}
})
.Build();
}
This code snippet works, when executed during application startup, e.g. RouteConfig. All subsequent calls are working, also refresh does work without problems.
The problems are starting when first calling App Configuration at a later time, e.g. during a request. The code hangs without an error message. In my special situation I am not able to connect to Azure App Configuration at startup time.
When using .Net Core, everything works like a charm but currently this is not an option.
Here are the logs.
When executed during startup:
Starting IIS Express ...
Successfully registered URL "http://localhost:5000/" for site "AppConfigTest3" application "/"
Registration completed for site "AppConfigTest3"
IIS Express is running.
Enter 'Q' to stop IIS Express
Loading configuration ...
Created DefaultAzureCredential: Azure.Identity.DefaultAzureCredential
Using Azure environment
Created ManagedIdentityCredential: Azure.Identity.DefaultAzureCredential
Connected via APP_CONFIGURATION_ENDPOINT: https://my-test-appconfig.azconfig.io
Before configure KeyVault credential
After configure KeyVault credential
Before executing Build()
EscalationMonitorInterval: 300
Created DefaultAzureCredential: Azure.Identity.DefaultAzureCredential
Using Azure environment
Created ManagedIdentityCredential: Azure.Identity.DefaultAzureCredential
Connected via APP_CONFIGURATION_ENDPOINT: https://my-test-appconfig.azconfig.io
Before configure KeyVault credential
After configure KeyVault credential
Before executing Build()
Azure Config loaded
Anforderung gestartet: "GET" http://localhost:5000/
If called the first time during a request, I'm getting the following log:
Starting IIS Express ...
Successfully registered URL "http://localhost:5000/" for site "AppConfigTest3" application "/"
Registration completed for site "AppConfigTest3"
IIS Express is running.
Enter 'Q' to stop IIS Express
Azure Config loaded
Anforderung gestartet: "GET" http://localhost:5000/
Response sent: http://localhost:5000/ with HTTP status 200.0
Anforderung gestartet: "GET" http://localhost:5000/Home/About
Loading configuration ...
Created DefaultAzureCredential: Azure.Identity.DefaultAzureCredential
Using Azure environment
Created ManagedIdentityCredential: Azure.Identity.DefaultAzureCredential
Connected via APP_CONFIGURATION_ENDPOINT: https://my-test-appconfig.azconfig.io
Before configure KeyVault credential
After configure KeyVault credential
Before executing Build()
Nothing happens and the request does not return.
I'm stucked at this point. Does someone has a solution for this problem? Thank you.
Regards,
Stati
This is because of a bug introduced in Azure.Core package version 1.4.1. The bug has been fixed in Azure.Core version 1.9.0. Since you are referencing Azure.Identity version 1.3.0, you have an indirect dependency on Azure.Core version 1.6.0.
Your problem can be fixed by adding an explicit dependency on Azure.Core v1.9.0 or later.
I have an ASP.Net App and I recent added login with office 365 consuming Graph Api. It works fine in my local machine and I get token and user info from the Graph Api. But when I deploy the solution in production server I m getting an error in the response from the API. Production server is a virtual windows server 2016
var graphClient = new GraphServiceClient(
new DelegateAuthenticationProvider(
async (requestMessage) =>
{
requestMessage.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", accessToken);
}));
var user = await graphClient.Me.Request()
.Select(u => new {
u.DisplayName,
u.Mail,
u.UserPrincipalName
})
.GetAsync();
This is the code to get the info from the user, after calling this method I get an exeption with the next error:
Method not found: 'System.Threading.Tasks.Task`1<!!0>Microsoft.Graph.BaseRequest.SendAsyc(System.Object, System.Threading.CancellationToken, System.Net.Http.HttpCompletionOption)'.
The most rare is that this happen only in the production server, in test server and local machine it works fine. Thanks in advance!
You are likely missing some dependencies. make sure in your bin folder of the app in production you see the Microsoft.Graph.Core.dll file, sometimes when you deploy things it doesn't update the packages for whatever reason. you should see such a file in your test server and local machines. if not there, copy it over. if it is there, then check that you have the same .net versions installed in prod as you have in other environments. also make sure that in your development environment you have the latest graph api sdk being used.
Finally the solution to solve this problem was updating the .Net framework version in the server.
I created a Blazor application to be run using Kestrel (.Net core 3.1).
Import NuGet package Microsoft.AspNetCore.Authentication.Negotiate
Add the following code in ConfigureService() in Startup.cs.
services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate();
services.AddSingleton<ValidateAuthentication>();
Add the following code in Configure() in Startup.cs. They are added between app.UseRouting(); and app.UseEndpoints(...;
app.UseAuthentication();
app.UseAuthorization();
app.UseMiddleware<ValidateAuthentication>();
Add the class
internal class ValidateAuthentication : IMiddleware
{
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
if (context.User.Identity.IsAuthenticated)
await next(context);
else
await context.ChallengeAsync();
}
}
Add the following code in the Program.cs (To make sure the remote machine can access the website)
webBuilder.UseUrls(new string[] { "https://0.0.0.0:5001", "http://0.0.0.0:5000" });
I published (as self hosted) the application to a local folder and it works fine on my PC. Running .\myApp.exe and then browsing http://localhost.5000 will redirect to https://localhost:5001 and show the page.
Then the published folder was copied to a Windows 2012 Server. However, running the application gets error:
PS C:\Website\Portal> .\MyApp.exe
crit: Microsoft.AspNetCore.Server.Kestrel[0]
Unable to start Kestrel.
System.InvalidOperationException: Unable to configure HTTPS endpoint. No server certificate was specified, and the defau
lt developer certificate could not be found or is out of date.
To generate a developer certificate run 'dotnet dev-certs https'. To trust the certificate (Windows and macOS only) run
'dotnet dev-certs https --trust'.
For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054.
at Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps(ListenOptions listenOptions, Action`1 configure
Options)
at Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps(ListenOptions listenOptions)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.BindAsync(AddressBindContext con
text)
How to specify a server certificate for the application?
This Microsoft Docs article explains how to startup an ASP.Net Core app with certificates when it ships as a Docker container. You basically set ennvironment variables, e.g.
ASPNETCORE_URLS
ASPNETCORE_HTTPS_PORT
ASPNETCORE_Kestrel__Certificates__Default__Path
ASPNETCORE_Kestrel__Certificates__Default__Password
I guess you may do the same on the host directly but keep in mind that those settings won't be isolated and may affect other apps. Also note that you would be storing a password in an environment variable. I also found this article explaining how to configure Kestrel via the launch settings json.
I came across this question by accident. Solution is not tested. Just replying since there is no better suggestion yet.
I try to run a ASP.NET Core MVC Web application on the Swisscom Appcloud. But when I start the Application I get following Error-Message in the Console:
2017-01-24 14:29:53 [CELL/0] ERR Timed out after 1m0s: health check never passed.
Its looks like the Appcloud cannot check the Health of my Application. Do I need to install a Nuget-Package or something else to get this up and running?
Thanks for your effort
By default, Cloud Foundry makes a health check by trying to connect to the port which the application is exposing.
If your application is not exposing ANY port (e.g., it's not a web service with APIs and so on), then you should add the health-check-type attribute to none, as described here.
If after that you still get errors, then I suggest you to find where your application is listening to a given port. In Cloud Foundry you must listen to $PORT, which is a environment variable. You can check an example of that here.
As gsmachado has already mentioned, you must listen to a specific port.
The .NET Core buildpack configures the app web server automatically so you don’t have to handle this yourself. But you have to prepare your app in a way that allows the buildpack to deliver this information via the command line to your app.
The buildpack will start your app with the following command:
$ dotnet run --server.urls http://0.0.0.0:${PORT}
Therefore you have to add the command line as a configuration provider and then add the UseConfiguration extension to pass the configuration to the WebHostBuilder
e.g.:
var config = new ConfigurationBuilder()
.AddCommandLine(args)
.Build();
var host = new WebHostBuilder()
.UseKestrel()
.UseConfiguration(config)
.UseStartup<Startup>()
.Build();
I'm following tutorial on http://martinabbott.azurewebsites.net/2016/06/11/fun-with-azure-functions-and-the-emotion-api/
Finally got solvet issue with blob trigger. I have verified that my jpg file can be succesfully processed with my API key in the Open API Test console. I have upload project.json file include dependancies to "Microsoft.ProjectOxford.Emotion": "1.0.251"
I'm getting now error. How to solve?
2016-11-07T06:53:44.951 C# Blob Emotion function processed: Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob
2016-11-07T06:53:45.076 Function completed (Failure, Id=c0c50024-7830-4595-b749-56f58ec79d0b)
2016-11-07T06:53:45.107 Exception while executing function: Functions.BlobTriggerEmotionFunction. Microsoft.ProjectOxford.Common: Exception of type 'Microsoft.ProjectOxford.Common.ClientException' was thrown.
Based on the tutorial you are referencing, for the line of code,
var apiKey = WebConfigurationManager.AppSettings["EMOTION_API_KEY"];
did you set the EMOTION_API_KEY in your Function app's App settings?
You may verify with the following steps:
Visit your Function app through the Functions portal.
Click Function app settings -> Configure app settings.
Verify that the EMOTION_API_KEY exists and that its value matches the one you used in the Open API Test console.