IwebHostEnvironment interface - asp.net-core

i have used IwebHostEnvironment in my code but i have a question ..
IWebHostEnvironment is an interface used to provide info about hosting & can get data about path from it
why i take an instance from it and inject it like i was inject a _db without register it in
ConfigureServices method like i register Db context?!
public class ProductController : Controller
{
private readonly App_DbContext _db;
private readonly IWebHostEnvironment _webHostEnvironment;
public ProductController(App_DbContext db,IWebHostEnvironment webHostEnvironment)
{
_db = db;
_webHostEnvironment = webHostEnvironment;
}
public IActionResult Index()
{
IEnumerable<Product> products= _db.Product;
return View(products);
}
this is configure services Method
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<App_DbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddControllersWithViews();
}

Agree with #Nkosi, you can refer to this section, IWebHostEnvironment is one of the framework-registered services.

Related

LinkGenerator.GetUriByAction not following the custom route

That's the controller:
[ApiController]
[Route("api/[controller]")
public class MarketController : ControllerBase
{
[HttpGet("{id}/picture")
public async Task<IActionResult> GetPictureAsync(Guid id)
{
...
}
}
I'm using LinkGenerator to create a Absolute URI from GetPictureAsync. And set the Startup class to start HttpContextAccessor as DI.
// Startup.cs
...
public void ConfigureServices(IServiceCollection services)
{
...
services.AddHttpContextAccessor();
...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapDefaultControllerRoute();
});
}
And in my custom class I use that way:
public class CustomClass
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly LinkGenerator _linkGenerator;
public CustomClass(IHttpContextAccessor httpContextAccessor,
LinkGenerator linkGenerator)
{
_httpContextAccessor = httpContextAccessor;
_linkGenerator = linkGenerator;
}
public void SomeMethod()
{
var uri = _linkGenerator.GetUriByAction(_httpContextAccessor.HttpContext, "GetPicture", "Markets", new { id = id });
}
}
The problem is because LinkGenerator is not following the custom route sample that I set in GetPicture method.
The LinkGenerator generates the following value:
https://localhost:5051/Markets/GetPicture/00748d23-afa7-4efb-b67b-77f68fdc44d5
But it should generate:
https://localhost:5051/api/Markets/00748d23-afa7-4efb-b67b-77f68fdc44d5/picture
The reason is you use wrong controller name in SomeMethod. Follow the steps you provided, I reproduced your issue.
You should use Market, not Markets.
Because your controller name is MarketController.
After test it,it works for me.

How to access session in class library .Net Core 5

is there a way to access HttpContext.session in a class library? (im using .Net Core 5)
I have the configuration all set up and also using microsoft.AspNetCore.Http but im still unable to access the session variables.
If there is no way to do that whats the best way to perform actions that require the current User's ID/Identification?
As #King King answered, you could inject the IHttpContextAccessor into the class.
Step 1 Add Session service
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddSession();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseAuthorization();
app.UseSession();
app.UseEndpoints(endpoints =>
...
}
Step 2 Access Session in custom class
public class SessionTest
{
private readonly IHttpContextAccessor _httpContextAccessor;
private ISession _session => _httpContextAccessor.HttpContext.Session;
public SessionTest(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public void setSession()
{
_session.SetString("Test", "Hello World!");
}
public void getSession()
{
var message = _session.GetString("Test");
...
}
}
Step 3 access session via custom class
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly ISession _session;
public HomeController(IHttpContextAccessor httpContextAccessor,ILogger<HomeController> logger)
{
_logger = logger;
_httpContextAccessor = httpContextAccessor;
_session = _httpContextAccessor.HttpContext.Session;
}
public IActionResult Index()
{
SessionTest session = new SessionTest(_httpContextAccessor);
session.setSession();
session.getSession();
return View();
}
}

.NET Core Identity and Simple Injector. Crosswire not working

I am using simple injector (4.8.1) on a project that uses asp.net core identity. I tried to crosswise UserManager but I got an error saying
No service for type 'Microsoft.AspNetCore.Identity.UserManager`1[Tenancy.Core.Domain.AppUser]' has been registered."
the SimpleInjectorConfig class is:
public static class SimpleInjectorConfig
{
private static Container _container;
public static void ConfigureServices(IServiceCollection services, IConfiguration config,
IWebHostEnvironment env)
{
_container = new Container();
_container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
_container.ConfigureCore(config, env);
_container.RegisterInitializer<BaseApiController>(controller =>
{
controller.Mediator = _container.GetInstance<IMediator>();
});
services.AddSingleton(_container);
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddControllers();
services.AddLogging();
// Sets up the basic configuration that for integrating Simple Injector with
// ASP.NET Core by setting the DefaultScopedLifestyle, and setting up auto
// cross wiring.
services.AddSimpleInjector(_container, options =>
{
// AddAspNetCore() wraps web requests in a Simple Injector scope and
// allows request-scoped framework services to be resolved.
options
.AddAspNetCore()
.AddControllerActivation();
options.AddLogging();
options.CrossWire<UserManager<AppUser>>();
});
}
public static void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseSimpleInjector(_container);
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
IdentityModelEventSource.ShowPII = true;
}
//app.UseHttpsRedirection();
_container.Verify();
}
}
and I called it in my Startup.cs file
public class Startup
{
public IConfiguration _configuration { get; }
public IWebHostEnvironment _env { get; }
public Startup(IConfiguration configuration, IWebHostEnvironment env)
{
_configuration = configuration;
_env = env;
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
SimpleInjectorConfig.ConfigureServices(services, _configuration, _env);
CorsConfig.ConfigureServices(services);
DatabaseConfig.ConfigureServices(services, _configuration);
MvcConfig.ConfigureServices(services);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
SimpleInjectorConfig.Configure(app, env);
CorsConfig.Configure(app, _configuration);
MvcConfig.Configure(app);
}
}
The configurations have their own class and called in the Startup called in the Startup class just to keep it clean, SimpleInjectorConfig is the config class for simple injector.

Get value of Web root

On an ASP.NET Core Startup file I have the following:
public void ConfigureServices(IServiceCollection services) {
services.AddMvc();
services.AddPOLocalization(x => x.ResourcesPath = "wwwroot/assets");
}
How can get the value defined for web root instead of hard code it (wwwroot)?
There is an IHostingEnvironment.WebRootPath property:
Gets or sets the absolute path to the directory that contains the web-servable application content files.
You can get instance from DI container:
private IHostingEnvironment _env;
public Startup(IConfiguration configuration, IHostingEnvironment env)
{
// use env.WebRootPath here or variable in private field for future using
// (like in ConfigureServices method)
_env = env;
...
}
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddPOLocalization(x =>
x.ResourcesPath = System.IO.Path.Combine(_env.WebRootPath, "assets"));
}

Accessing the IHostingEnvironment in ConfigureServices method

I need to check in ConfigureServices method whether the current hosting environment name is 'Development'.
So using IHostingEnvironment.IsDevelopment() method may be ok for me, but unlike in Configure method, I do not have IHostingEnvironment env.
just create a property in the Startup class to persist the IHostingEnvironment. Set the property in the Startup constructor where you already have access, then you can access the property from ConfigureServices
Copied here from question marked as duplicate of this one and deleted. Credit to a-ctor.
If you want to access IHostingEnvironment in ConfigureServices you will have to inject it via the constructor and store it for later access in ConfigureServices:
public class Startup
{
public Startup(IConfiguration configuration, IHostingEnvironment environment)
{
Configuration = configuration;
Environment = environment;
}
public IConfiguration Configuration { get; }
public IHostingEnvironment Environment { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
System.Console.WriteLine($"app: {Environment.ApplicationName}");
}
// rest omitted
}
IHostingEnvironment is deprecated in Core 3.1
private readonly IWebHostEnvironment _env;
public Startup(IConfiguration configuration, IWebHostEnvironment env)
{
_env = env;
Configuration = configuration;
}
should do the trick...
Then reference anywhere with _env.IsDevelopment() etc...
If you aren't using a Startup class and are calling .Configure() directly, you can access the IHostingEnvironment or IWebHostEnvironment using GetService:
ASP.NET Core 2.2:
.Configure(app => {
var hostingEnvironment = app.ApplicationServices.GetService<IHostingEnvironment>();
if (hostingEnvironment?.IsDevelopment() == true)
{
app.UseDeveloperExceptionPage();
}
// .. Other stuff
});
ASP.NET Core 3.x:
.Configure(app => {
var hostingEnvironment = app.ApplicationServices.GetService<IWebHostEnvironment>();
if (hostingEnvironment?.IsDevelopment() == true)
{
app.UseDeveloperExceptionPage();
}
// .. Other stuff
});
If you don't have a Startup class (you may be creating a service) you can get the environment from the hostContext in ConfigureServices like so:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
IConfiguration config = hostContext.Configuration;
Configuration = config;
var env = hostContext.HostingEnvironment;
EnvironmentName = env?.EnvironmentName;
...
There are some examples here but none of them seem accurate to the newest release of dotnet, so here we go.
First, in your Startup.cs you should have a reference in your initial constructor like this:
public Startup(IConfiguration configuration, IWebHostEnvironment env)
{
this.Configuration = configuration;
this.Environment = env;
}
We can take the Env and tack it onto ServiceCollection like so:
services.AddSingleton(sp => this.Environment);
Then we can access it in any extension method or other place like so:
var hostEnvironment = services.BuildServiceProvider().GetRequiredService<IHostEnvironment>();
if (hostEnvironment.IsDevelopment())
{
//do something if in dev
}