Unable to publish existing ASP.NET Core 1.0 Web API using VS Tools - c#

I just started working on AWS Lambda using C# and .NET Core. I'm familiar with ASP.NET Core Web API, and have done few projects in it.
I was able to publish a brand new ASP.NET Core Web API project as server-less application in AWS Lambda using API Gateway proxy and able to access my Web API methods.
Now, I have an existing ASP.NET Core Web API project, which I want to publish as server-less application to AWS Lambda using the API Gateway proxy. I followed the instructions given in the below URL to setup my existing project to publish to AWS Lambda.
https://aws.amazon.com/blogs/developer/deploy-an-existing-asp-net-core-web-api-to-aws-lambda/
I'm able to see the publish wizard, and it stats up nut fails with the following trace. Wondering if anyone here could help me understand and fix the issue.
.....
... publish: Configuring project completed successfully
... publish: publish: Published to D:\Aditya\Apps\ManzilApp\Server\src\ManzilApp.Server\bin\Release\netcoreapp1.0\publish
... publish: Published 1/1 projects successfully
Flattening platform specific dependencies
... flatten: runtimes/rhel-x64/native/libuv.so
**Unknown error executing AWS Serverless deployment: Could not find a part of the path** 'D:\Aditya\Apps\ManzilApp\Server\src\ManzilApp.Server\bin\Release\netcoreapp1.0\publish\runtimes/rhel-x64/native/libuv.so'.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)
at System.IO.File.Copy(String sourceFileName, String destFileName)
at Amazon.Lambda.Tools.LambdaPackager.<>c__DisplayClass4_0.<FlattenRuntimeFolder>b__0(String sourceRelativePath)
at Amazon.Lambda.Tools.LambdaPackager.FlattenRuntimeFolder(IToolLogger logger, String publishLocation, JsonData depsJsonTargetNode)
at Amazon.Lambda.Tools.LambdaPackager.CreateApplicationBundle(LambdaToolsDefaults defaults, IToolLogger logger, String workingDirectory, String projectLocation, String configuration, String targetFramework, String& publishLocation, String& zipArchivePath)
at Amazon.Lambda.Tools.Commands.DeployServerlessCommand.<ExecuteAsync>d__55.MoveNext()

Finally, I got the AWS Lambda deploy tool working in VS 2015 on my existing ASP.NET Core 1.0 Web API project. I had to change the sdk version in global.json file in my source folder (same folder where my .sln file resides). Not sure what is the reason (still would like to understand), but this solved the issue.
{
"projects": [ "src", "test" ],
"sdk": {
"version": "1.0.0-preview2-003131"
}
}

Related

Why is HttpRepl unable to find an OpenAPI description? The command "ls" does not show available endpoints

I am working through the Microsoft Learn tutorials to "Create a web API with ASP.Net Core".
Under the heading, "Build and test the web API", at instruction (5) I am getting a response, "Unable to find an OpenAPI description".
For step (6) when executing the "ls" command I get the response, "No directory structure has been set, so there is nothing to list. Use the 'connect' command to set a directory structure based on an OpenAPI description". I have tried the "connect" command suggested here and have tried "dir" as an alternative to "ls".
I can successfully change directories in step (7) and execute the GET request for step (8) and receive the expected reply. However, it really bothers me the "ls" command is not working here and seems like an important function of the httprepl tool.
How can I get the "ls" command to work here or tell me why does it not work?
C:\Users\xxxx\source\repos\Learn\ContosoPizza>httprepl http://localhost:5000
(Disconnected)> connect http://localhost:5000
Using a base address of http://localhost:5000/
Unable to find an OpenAPI description
For detailed tool info, see https://aka.ms/http-repl-doc
http://localhost:5000/> ls
No directory structure has been set, so there is nothing to list. Use the "connect" command to set a directory structure based on an OpenAPI description.
http://localhost:5000/>
ADDED RESULTS OF SUGGESTIONS--
C:\Users\xxxx\source\repos\Learn\ContosoPizza>dotnet --version
3.1.412
C:\Users\xxxx\source\repos\Learn\ContosoPizza>dotnet add WebAPI.csproj package Swashbuckle.AspNetCore -v 5.6.3
Could not find project or directory `WebAPI.csproj`.
httprepl GitHub repo and MS Docs page
The solution for me was to simply trust localhost's SSL certification, which you can do with this command:
dotnet dev-certs https --trust
While doing the same Tutorial, a friend of mine noticed, that trusting the dev certificate, was already covered by the Tutorial, which I had overlooked doing the Tutorial myself. This is the official help site:
Trust the ASP.NET Core HTTPS development certificate on Windows and macOS.
Maybe this will still help someone with the same problem.
In step 5 HttpRepl emits the warning Unable to find an OpenAPI description, which means that it can't find the swagger endpoint, and therefore the ls command wont work.
I assume you are using VS Code and ASP.NET Core 5.0. Here is my output from running dotnet --version:
5.0.401
If we are using Visual Studio, then remember to enable swagger when you create the project - I am using Visual Studio 2019 to create the screenshot:
Specifying your OpenAPI description
To find out which endpoint to use, open the file Startup.cs and locate the code fragment that contains the text UseSwaggerUI. You should find this block of code:
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebAPI v1"));
}
Use the endpoint you find and run the tool like this:
httprepl http://localhost:5000 --openapi /swagger/v1/swagger.json
If you do not find any references to swagger, then see None of the above worked, swagger isn't installed below, for how to install and configure swagger for your project.
Ignoring your environment
If specifying the Open API endpoint to use doesn't work, then you are not running your Web API in a development environment. So either use a development environment, or uncomment the if-statement while testing (to setup your environment for development, see Changing your environment below):
//if (env.IsDevelopment())
//{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebAPI v1"));
//}
Remember to restore the code you uncommented, if any, before you deploy to production.
Changing your environment
The profile your Web API is using, is specified in the file Properties\launchSettings.json. Open the file and search for ASPNETCORE_ENVIRONMENT. Then change the instances you find to:
"ASPNETCORE_ENVIRONMENT": "Development"
If this doesn't work, or the instances were already set to "Development", it means that you are not using any of the profiles specified in your launch settings. If no profile is used, ASPNETCORE_ENVIRONMENT defaults to "Production". When using the dotnet run command, the --launch-profile parameter lets you specify which profile to use:
dotnet run --launch-profile "name_of_profile"
As a last resort you can set the environment variable ASPNETCORE_ENVIRONMENT in the shell you are using, before you run the command dotnet run:
Bash
export ASPNETCORE_ENVIRONMENT=Development
CMD
set ASPNETCORE_ENVIRONMENT=Development
PowerShell
$env:ASPNETCORE_ENVIRONMENT='Development'
Then run the application without a profile :
dotnet run --no-launch-profile
The default ports, when running without a profile, should be 5000 or 5001. But read the output from the command, to see which ports it assigns to your Web API.
Please note, if you use VS Code to run your project, that VS Code may also have created launch settings in the .vscode\launch.json. It depends on how you have configured VS Code and what you allow it to do. I found some older articles, that claim that some extensions for VS Code, may interfere with the launch settings, but they didn't specify which ones.
None of the above worked, swagger isn't installed
I none of the above worked, it means you don't have swagger installed. Install swagger for your project and when done, try again.
Package Installation
Open your project in VS Code and run the following command from the Integrated Terminal and replace WebAPI.csproj with the name of your own project file:
dotnet add WebAPI.csproj package Swashbuckle.AspNetCore -v 5.6.3
You can of course run the command from outside VS Code, with your project folder as the current working directory.
Add and configure Swagger middleware
Add the Swagger generator to the services collection in the Startup.ConfigureServices method, as the last statement in the method:
public void ConfigureServices(IServiceCollection services)
{
[... other code here ...]
// Register the Swagger generator, defining 1 or more Swagger documents
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebAPI", Version = "v1" });
});
}
In the Startup.Configure method, enable the middleware for serving the generated JSON document and the Swagger UI, at the top of the method:
public void Configure(IApplicationBuilder app)
{
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
[... other code here for setting up routing and the like ...]
}
To learn more about setting up swagger, profiles and the environment
Get started with Swashbuckle and ASP.NET Core
Managing Production and Development Settings in ASP.NET Core
Use multiple environments in ASP.NET Core
ASP.NET Core web API documentation with Swagger / OpenAPI
I had faced same issue. I have solved it by following:
In Developer PowerShell(VS 2022), Run 'dotnet run' command.
Keep this powershell as it is.
Now open new PowerShell and run "httprepl https://localhost:{PORT}"
You should be able to run api now.
You must be connected to the web server through dotnet run.

Issue accessing GCP secrets manager using dotnet 5

I am using Google.Cloud.SecretManager.V1 in my .NET 5 aspnet core application. I am containerizing application to run as linux container on GCP Cloud run. I get following exception while creating SecretManagerServiceClient
//call SDK
SecretManagerServiceClient client = SecretManagerServiceClient.Create();
System.DllNotFoundException: Unable to load shared library 'libdl.so' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: liblibdl.so: cannot open shared object file: No such file or directory
at Grpc.Core.Internal.UnmanagedLibrary.Linux.dlopen(String filename, Int32 flags)
at Grpc.Core.Internal.UnmanagedLibrary.LoadLibraryPosix(Func`3 dlopenFunc, Func`1 dlerrorFunc, String libraryPath, String& errorMsg)
at Grpc.Core.Internal.UnmanagedLibrary.PlatformSpecificLoadLibrary(String libraryPath, String& errorMsg)
at Grpc.Core.Internal.UnmanagedLibrary..ctor(String[] libraryPathAlternatives)
at Grpc.Core.Internal.NativeExtension.LoadUnmanagedLibrary()
at Grpc.Core.Internal.NativeExtension.LoadNativeMethods()
at Grpc.Core.Internal.NativeExtension..ctor()
at Grpc.Core.Internal.NativeExtension.Get()
at Grpc.Core.Internal.NativeMethods.Get()
at Grpc.Core.GrpcEnvironment.GrpcNativeInit()
at Grpc.Core.GrpcEnvironment..ctor()
at Grpc.Core.GrpcEnvironment.AddRef()
at Grpc.Core.Channel..ctor(String target, ChannelCredentials credentials, IEnumerable`1 options)
at Google.Api.Gax.Grpc.GrpcCore.GrpcCoreAdapter.CreateChannelImpl(String endpoint, ChannelCredentials credentials, GrpcChannelOptions options)
at Google.Api.Gax.Grpc.GrpcAdapter.CreateChannel(String endpoint, ChannelCredentials credentials, GrpcChannelOptions options)
at Google.Api.Gax.Grpc.ChannelPool.GetChannel(GrpcAdapter grpcAdapter, String endpoint, GrpcChannelOptions channelOptions, ChannelCredentials credentials)
at Google.Api.Gax.Grpc.ChannelPool.GetChannel(GrpcAdapter grpcAdapter, String endpoint, GrpcChannelOptions channelOptions)
at Google.Api.Gax.Grpc.ClientBuilderBase`1.CreateCallInvoker()
at Google.Cloud.SecretManager.V1.SecretManagerServiceClientBuilder.BuildImpl()
at Google.Cloud.SecretManager.V1.SecretManagerServiceClientBuilder.Build()
at Google.Cloud.SecretManager.V1.SecretManagerServiceClient.Create()
Same code works fine if I use aspnetcore 3.1 image. NET 5 is supposed to be upgrade of .NET core 3.1 and backward compatible. So, I am curious and what could be done to make this code work on .NET 5
I posted this answer to make a solution from the comment section more visible.
As it was suggested by #John Hanley and confirmed by #SmartCoder this issue was solved by adding to the Docker file lines below:
RUN apt-get update -y
RUN apt-get install -y libc6-dev

Error: An assembly specified in the application dependencies manifest not found Package:Newtonsoft.Json when deploying .Net core 2.2

I am deploying a .Net core 2.2 console application using self contained deployment and using some 3rd party libraries like(log4net and Newtonsoft.Json). The application is working fine on the system it is developed but not working when deployed to any other system. The below error displays:
C:\Users\shubhamjain\source\repos\Collect\Collect\bin\Release\netcoreapp2.2\win-x64>Collect.exe
Error:
An assembly specified in the application dependencies manifest (Collect.deps.json) was not found:
package: 'Newtonsoft.Json', version: '12.0.2'
path: 'lib/netstandard1.3/Newtonsoft.Json.dll'
I have tried the below things:
Changing the .Net core version from 2.1 and 2.2
changing the version of Newtonsoft.Json from nuget
Updating visual studio 2019
Nothing worked but when I looked to a file ("Collect.runtimeconfig.dev.json" in path C:\Users\shubhamjain\source\repos\Collect\Collect\bin\Release\netcoreapp2.2\win-x64) and change the shubhamjain with the deployed system username, everything works fine.
Now, What I observe that Newtonsoft.Json is depends on file (.runtimeconfig.dev.json) and in order to make it work I have to change the username in this file.
Is there any way to resolve this automatically?
Collect.runtimeconfig.dev.json :
{
"runtimeOptions": {
"additionalProbingPaths": [
"C:\\Users\\shubhamjain\\.dotnet\\store\\|arch|\\|tfm|",
"C:\\Users\\shubhamjain\\.nuget\\packages",
"C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder" ]
}
}
Can you try configuring your json file with using %username% parameter. I am not sure if it is possible to run that way but you can use that parameter in the Command Prompt to get the logged in username.
You can check the link for more detail.
In this case your Collect.runtimeconfig.dev.json will be :
{
"runtimeOptions": {
"additionalProbingPaths": [
"C:\\Users\\%username%\\.dotnet\\store\\|arch|\\|tfm|",
"C:\\Users\\%username%\\.nuget\\packages",
"C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder" ]
}
}
Also you can prepare different configuration files for different environments. Maybe this Microsoft Doc could be helpful about that.

How to prevent Asp.Net Core from referencing dependencies from Runtime Store

I am developing a web application using Asp.NET Core 2.1 on Visual Studio 17.7, the problem is when I publish the web app as a Framework-Dependent and I try to run the app on production machine I get this error message:
Error:
An assembly specified in the application dependencies manifest (Example.deps.json) was not found:
package: 'Cronos', version: '0.6.3'
path: 'lib/netstandard1.0/Cronos.dll'
Cronos.dll is a dependency of Hangfire library which I am using in the web app, in the Example.deps.json file I found this:
"Cronos/0.6.3": {
"dependencies": {
"NETStandard.Library": "2.0.3"
},
"runtime": {
"lib/netstandard1.0/Cronos.dll": {
"assemblyVersion": "0.6.3.0",
"fileVersion": "0.6.3.0"
}
},
"compile": {
"lib/netstandard1.0/Cronos.dll": {}
}
},
The problem is that it's referencing the libraries in the runtime store, which will work on the developemnt machine but when I deploy to another machine the error happens.
I have tried the suggested solution in this article:
https://learn.microsoft.com/en-us/dotnet/core/deploying/runtime-store
By setting:-
<PropertyGroup>
<PublishWithAspNetCoreTargetManifest>false</PublishWithAspNetCoreTargetManifest>
</PropertyGroup>
and I have also tried solutions in this github issue with no success:
https://github.com/dotnet/coreclr/issues/13542
When deploying a .NET Core application, only use the publish output from the bin/Release/netcoreapp*/publish or …/netcoreapp*/{RID}/publish (when using -r RID option) or call dotnet publish with an -o ../target-dir option to specify a publish target location.
The build output (bin/Release/netcoreapp*) is meant for development purposes only since the runtimeconfig.dev.json file configures .NET Core to use packages directly from your NuGet package cache which avoids copying assets during the development builds.

Problems with deploy ASP.NET 5 (ASP.NET Core) app to Azure

I have an app on ASP.NET 5 (CoreCLR) and I try to publish it to the Microsoft Azure. I using free Web App (not VDS)
I am publishing app using Visual Studio 2015 Publish->Microsoft Azureand following this instructions.
But when I publish it and try to open, I see just non-stop loading of empty page. I enabling logging and view the log (stdout.log) from Azure and there was only:
'"dnx.exe"' is not recognized as an internal or external command,
operable program or batch file.
Also I tried to do Continiusly publishing with git. During push, It started restoring packages and failed with error no disk space available.
Is there any way to publish ASP.NET 5 app to the Azure Web App?
Short Answer
But when I publish it and try to open, I see just non-stop loading of empty page.
This happens when our app fails to publish the runtime (dnx.exe) with the application.
Discussion
There are several ways to publish ASP.NET Core rc1 apps to an Azure Web App. These include continuous deployment with Git and publishing with Visual Studio. Post your repository's contents for specific help.
The example is an ASP.NET Core rc1 app, deployed to an Azure Web App, via GitHub continuous deployment. These are the vital files.
app/
wwwroot/
web.config
project.json
startup.cs
.deployment <-- optional: if your app is not in the repo root
global.json <-- optional: if you need dnxcore50 support
app/wwwroot/web.config
Add the HttpPlatformHandler. Configure it to forward all requests to a DNX process. In other words, tell the Azure Web app to use DNX.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="httpPlatformHandler"
path="*" verb="*"
modules="httpPlatformHandler"
resourceType="Unspecified"/>
</handlers>
<httpPlatform
processPath="%DNX_PATH%"
arguments="%DNX_ARGS%"
stdoutLogEnabled="false"
startupTimeLimit="3600"/>
</system.webServer>
</configuration>
app/project.json
Include a dependency on the Kestrel server. Set a web command that will startup Kestrel. Use dnx451 as the target framework. See below for the additional work to target dnxCore50.
{
"dependencies": {
"Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final"
},
"commands": {
"web": "Microsoft.AspNet.Server.Kestrel"
},
"frameworks": {
"dnx451": { }
}
}
app/Startup.cs
Include the Configure method. This one adds an extremely simple response handler.
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;
namespace WebNotWar
{
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.Run(async (context) =>
{
await context.Response.WriteAsync(
"Hello from a minimal ASP.NET Core rc1 Web App.");
});
}
}
}
.deployment (optional)
If your app is not in the repositories root directory, tell the Azure Web App which directory contains the app.
[config]
project = app/
global.json (optional)
If you would like to target .NET Core, tell Azure that we want to target it. After adding this file, we can either replace (or complement) the dnx451 entry in our project.json with dnxCore50.
{
"sdk": {
"version": "1.0.0-rc1-update1",
"runtime": "coreclr",
"architecture": "x64"
}
}
Firstly, yes, you can happily run ASP.Net 5 core apps on Azure, but there are some gotchas.
I don't know why it doesn't work when you publish from Visual Studio itself (so why is he posting an answer I hear you ask...), but here are some things to have a look at;
Try running in IIS locally (rather than kestrel) - just to see if there is a problem. For example, you need a Web.config with some settings or you need the app.UseIISPlatformHandler in startup.cs.
Have a look at your global.json file. It shouldn't matter when you publish from Visual Studio but it won't hurt to set this correctly. You can do something like this:
.
{
"sdk": {
"version": "1.0.0-rc1-update1",
"runtime": "coreclr",
"architecture": "x64"
}
}
Regarding continous publishing - that is a known problem with free and shared sites and one that cost me a few hours. Basically, when you are deploying by this mechanism and you specify corecelr, the entire runtime is re-installed from Nuget and that takes up nearly 1GB (the allowance for free and shared sites). Add a few NPM packages and you are over the limit and, hey presto, you can't deploy. #shanselman discussed it recently on one of his podcasts. It's not actually the runtime binaries that take up all the space, but because we are in build mode, all the documentation XML files are installed as well, because Nuget doesn't know you are not in a development environment, and they are huge.
Right now, the simplest answer if you want to use continuous publishing on a free or shared site is to also include the full runtime in your project.json and set your global.json to use the full CLR instead of the coreclr. Just very frustrating.
I was having the same problem. This answer solved the issue.
When creating a new project with the asp.net core template the global.json file was part of my API project, but it was also referenced in the Solution Items folder. When published to an Azure API app, two global.json files were deployed:
In the /approot/global.json
In the /approot/src/MyAPI/global.json
I moved the global.json file out of the project folder to the solution root, and re-added a reference back into the Solution Items folder.
When deployed only the /approot/global.json file was then deployed, resolving the issue.

Categories