'WebHost' is inaccessible due to its protection level - c#

I am trying to follow Microsoft's Ocelot API Gateway tutorial (https://learn.microsoft.com/en-us/dotnet/architecture/microservices/multi-container-microservice-net-applications/implement-api-gateways-with-ocelot).
First I intialized a new empty ASP.NET Core web app:
dotnet new web
Then I installed the Ocelot dependencies (https://www.nuget.org/packages/Ocelot/):
dotnet add package Ocelot --version 17.0.0
Then I took the code from the tutorial:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
using System.IO;
namespace MyApp
{
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args)
{
var builder = WebHost.CreateDefaultBuilder(args);
builder.ConfigureServices(s => s.AddSingleton(builder))
.ConfigureAppConfiguration(
ic => ic.AddJsonFile(Path.Combine("configuration",
"configuration.json")))
.UseStartup<Startup>();
var host = builder.Build();
return host;
}
}
}
But then it complains that the WebHost class, called in BuildWebHost method, "is inaccessible due to its protection level". According to Microsoft (https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.webhost), WebHost "provides convenience methods for creating instances of IWebHost and IWebHostBuilder with pre-configured defaults.", and looks like so:
public static class WebHost
...
Why does it complain that WebHost is inaccessible, when the class is in fact public? What am I missing here?

From the documentation, WebHost is in the namespace Microsoft.AspNetCore. But in your code, It hasn't the using to this namespace.
In Visual Studio, you can try Go to definition on WebHost to discover where the type come.
As sujested by #leiflundgren, as your code has the using Microsoft.AspNetCore.Hosting, then the compiler thinks you want use Microsoft.AspNetCore.Hosting.WebHost.
https://github.com/dotnet/aspnetcore/blob/main/src/Hosting/Hosting/src/Internal/WebHost.cs
namespace Microsoft.AspNetCore.Hosting;
internal sealed partial class WebHost : IWebHost, IAsyncDisposable
{
....
}
But this class has the scope internal, then it isn't exposed and can be used by your code. Hence the following error :
WebHost is inaccessible due to its protection level.

Related

asp.net core: IApplicationLifetime.ApplicationStopping isn't triggered

I saw a few articles about IApplicationLifetime and the way I can trigger execution when application starts and stops but I probably miss something because it is just not triggered.
Here is my workaround:
I opened a project template Container Application for kubernetes, asp.net core 2.2
Program.cs looks as it was created:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace Kubernetes1
{
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
}
Startup.cs looks as following:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
namespace Kubernetes1
{
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime appLifetime)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//var appLifetime = app.ApplicationServices.GetRequiredService<IApplicationLifetime>();
appLifetime.ApplicationStopping.Register(() => Console.WriteLine("ApplicationStopping called"));
appLifetime.ApplicationStopped.Register(() => Console.WriteLine("ApplicationStopped called"));
app.Run(async (context) =>
{
Console.WriteLine("AAA");
});
}
}
}
All I wanted to do here is running the app in cmd, then stop it and see 2 lines printed in console:
ApplicationStopping called
ApplicationStopped called
I didn't manage to make it happen.
Any ideas?
in a different cmd window I type: Get-Process -Name *dotnet* | Stop-Process
Stop-Process will kill the process, skipping any graceful shutdown behavior an application might have.
When the IApplicationLifetime talks about the application stopping, then it refers to the application being gracefully shut down. There are a few ways to trigger this, depending on how the application is starting:
When the application is running in the console: CTRL + C. For example when running through dotnet run or running the compiled executable directly.
When the application is running in IIS: Stopping the website or the application pool.
When the application is running as a Windows Service: Stopping the service.

Add a Startup.cs file in MVC5 project without authentication

How can I bind the startup.cs file adding manually to the project?
I created it from Add > New Item > OWIN Startup class but is ignored by the app.
The Startup class
using System;
using System.Threading.Tasks;
using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(WebApplication1.Startup))]
namespace WebTest
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=316888
}
}
}
Thanks
Update
I can do it thanks to this
OwinStartup not firing
[assembly: OwinStartup(typeof(**WebApplication1**.Startup))]
In the OwinStartup attribute you specify a class WebApplication1.Startup but the class shown says WebTest.Startup

Cannot convert lambda expression to type 'ServiceLifetime' because it is not a delegate type on Asp.net core 2.2

Why do I get this error:
Cannot convert lambda expression to type 'ServiceLifetime' because it is not a delegate type [TokenAuthWebApiCore.Server]
on this line of code:
public virtual void SetUpDataBase(IServiceCollection services)
{
// Add framework services.
services.AddDbContext<SecurityContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("SecurityConnection"), sqlOptions => sqlOptions.MigrationsAssembly("TokenAuthWebApiCore.Server")));
}
This is how I use it:
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton(Configuration);
services.AddMvc();
SetUpDataBase(services);
// services.AddDbContext<SecurityContext>(options =>
// options.UseSqlServer(Configuration.GetConnectionString("SecurityConnection"), sqlOptions => sqlOptions.MigrationsAssembly("TokenAuthWebApiCore.Server")));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
public virtual void SetUpDataBase(IServiceCollection services)
{
// Add framework services.
services.AddDbContext<SecurityContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("SecurityConnection"), sqlOptions => sqlOptions.MigrationsAssembly("TokenAuthWebApiCore.Server")));
}
This are all my using statements
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.IdentityModel.Tokens;
using System.Text;
I am thinking probably this is because the tutorial I am following a tutorial for a different version of .net core and I am using .net core version 2.2. Can you please show me how to fix this? Thank you.
I had the same error in my project. The problem was that my context class was not derived from DbContext.
public class SecurityContext : DbContext
{
}
SecurityContext is not a DbContext. If you have a DbContext called SecurityContext in your project, remove using System.Security; from your usings in your Startups.csclass or rename the DbContext to something like SecurityDbContext.
The generic type you are using when calling AddDbContext is from the System.Security namespace, but it should be your Database context.
I´ve had the same issue. I use an interface, which is implemented by my DbContext. This solved the problem for me:
services.AddDbContext<IMyDbContext, MyDbContext>(options => options.UseLazyLoadingProxies()
.UseNpgsql("MyConnectionString", opt => opt.UseNodaTime()));
Not about version compatibility error.You need to implement DbContext in your project. When you make context class, you need to inherit context class from DbContext class.
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services
.AddEntityFrameworkSqlServer()
.AddDbContext<EmployeeContext>(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("EmployeeContext"));
});
I received this when I accidentally installed EntityFramework instead of Microsoft.EntityFrameworkCore in my data project.
I just had the same problem, when migrating a project to EF core. What happened is that the DB context was still defined for EF. To fix it, I changed the DbContext to include EF core, and added the DbContextOptions constructor.
Full explenation over at the aspnetcore site.
I had EntityFramework & EntityFrameworkCore installed, removed EntityFramework & it was sorted

The name WebHost does not exists in current context

I'm migrating from ASP.NET Core 1.x to v2.0 with the help of following post on docs.microsoft:
https://learn.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/
I'm almost done with all the changes mentioned in that post. But there is one error that is causing troubles.
Here is my Program.cs file:
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
namespace MeridiaCoreAPI
{
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureAppConfiguration((hostContext, config) =>
{
// delete all default configuration providers
config.Sources.Clear();
config.AddJsonFile("myconfig.json", optional: true);
})
.Build();
}
}
And here is the error message:
Suppression State
Error CS0103 The name 'WebHost' does not exist in the current context
Any solution, workaround or hint would be highly appreciated. Thanks.
WebHost class resides Microsoft.AspNetCore assembly that comes with Microsoft.AspNetCore.All NuGet package. So to fix you problem install this NuGet package and add following using directive to your source file:
using Microsoft.AspNetCore;
As CodeFuller's answer indicated the WebHost class is available in the assembly Microsoft.AspNetCore If you don't need everything, you can just get the package Microsoft.AspNetCore.

Calling an external webservice method from Azure function returns 401 but the same code works in a console app

I have added a web reference (WSDL) to a class library and then referenced that dll in a timer-triggered c# Azure function (read more about azure functions). The class library has a class EmployeeService which calls a method from the web service (sort of a webservice wrapper). When I call the class lib method (GetEmployees) from a console application, it authenticates to the web service and returns result but when I run the azure function for the same code and creds it returns 401. Not sure what I am doing wrong here :
#r "MyConsult.Service.dll"
#r "Newtonsoft.Json.dll"
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using Newtonsoft.Json;
using System.Net;
using MyConsult.Service.Service;
public static void Run(TimerInfo myTimer, TraceWriter log)
{
log.Info($"C# Timer trigger function executed at: {DateTime.Now}");
try
{
EmployeeService _empService = new EmployeeService();
var emps = _empService.GetEmployees();
int count = emps.Where(x => !string.IsNullOrEmpty(x.Email)).Select(x => x.Email).Distinct().Count();
log.Info($"employee count : {count}");
}
catch (Exception ex)
{
log.Info($"Exception Message: {ex.Message}");
log.Info($"Exception Stack Trace: { ex.StackTrace}");
}
}
Your console application is likely authenticating based on service configuration settings in your app.config. For your function, you'll need to programmatically apply those settings when constructing the client/proxy.

Categories