After years writing .NET Framework 4.x web apps I'm finally trying to get to grips with writing new apps in .NET 6. Obviously one of the new features I'm keen to make use of is the native dependency injection.
I'm trying to work out how to create a typed HttpClient instance specific to an external web service which I will be calling throughout my application by injecting it as a dependency into my MVC application's controllers. Just about every article and tutorial I've read describes how to use AddHttpClient() in Program.cs and IHttpClientFactory in controller constructors to achieve this.
However, Microsoft's HttpClient guidelines state
In .NET Core and .NET 5+: Use a static or singleton HttpClient instance... This solves both the port exhaustion and DNS changes problems without adding the overhead of IHttpClientFactory
and
If your app requires cookies, consider disabling automatic cookie handling or avoiding IHttpClientFactory. Pooling the HttpMessageHandler instances results in sharing of CookieContainer objects. Unanticipated CookieContainer object sharing often results in incorrect code.
My MVC web app is using cookies, so it sounds like I want to avoid IHttpClientFactory. Is that right? If so, I'd expect to see it mentioned more in the various articles I've read. And, if it is right, what would be the correct way to create typed HTTP Client without using IHttpClientFactory?
Related
I've inherited a .Net Framework application that wasn't really designed but thrown together as a portal application for clients, but then each client has their own database to store their data for security and data sovereignty reasons. The homepage loads basic data from a shared DB, but when the users naviagate to one of the pages, the site needs to connect to their specific database.
The app is written in C# with Angular and loosely follows MVC with the main context being passed around through DI, and I've just upgraded this to .Net 5. As there can be thousands of client databases that can't be registered as service connections in the startup, I'm trying to work out the best way to handle the DBContext for these client-specific databases. It seems to follow multi-tenancy principles in general, but the following are the concerns
Avoiding code repetition or adding lots of '= new DBContext' - use of DI would be preferable if possible with a TenantFactory or Database Interceptor
Ensuring that the connection is for the correct DB if the user has
multiple tabs for different clients open
Ensuring that the DB connection is disposed of when the client page is closed or the user
returns home to view another client
I realise that I can create a new DB Context per request, passing in the name of the DB each time, but is there a pattern or example that is better suited to this use case? Something like a DbCommandInterceptor at the DB level might work, but again if there are some examples of how to do this I can find them.
For your tenant context, make sure you use one of the AddDbContext overloads with a scoped optionsLifetime. Then you can provide a different connection string per instance, derived from any other scoped service.
services.AddDbContext<T>((sp, o) => {
var context = sp.GetService<IHttpContextAccessor>().Context;
o.UseSqlServer(... get the connection string here. From context.User? ...)
});
The simplest, most secure, and best way to do this is just what you said. Create a new DbContext per request, specifying the database name through some method of multi-tenancy isolation.
DbContext is designed to only live short term. Trying to make it live longer than a request will create memory and security issues. NEVER make a DbContext static (or singleton) in a multi-user application such as a web site.
The best practice is to inject a DbContext with a per request lifecycle. This will ensure the DbContext is destroyed after the request is completed, and all memory will be cleaned up.
We have a completely OWIN project and StructureMap is used for its IoC/DI. This Entity Framework ASP.NET Web API project runs on Helios that means no Http exists at all.
Now the question is what is proper lifecycle for DbContext?
HttpContextScoped?
This is not possible at all because an exception is throwned saying that You cannot use the HttpContextLifecycle outside of a web request.
HybridHttpOrThreadLocalScoped?
DbContext is alive for several requests so managing unit of work is very hard.
Transient?
This works but I'm not sure if it is a really correct choise.
I am implementing an enterprise web application in ASP.NET MVC 5. In many situations I am writing AJAX gets and posts and communicate with the server app. Currently I am writing controller actions to serve those requests, typically returning with JSON result. The action methods parameter binding also seems work seamlessly when I passing JSON at client side.
I do not want to go far with a not appropriate practice, so the question arises, what could be the advantage to add Web API support to my project, and refactor my current ajax - controller practice?
There are few advantages according using WebAPI over MVC + Ajax:
Internal serialization
WebAPI has an internal serialization, which makes returning specific data much more easier, without your own extension method or making your controller dependent on the serialization framework library.
Action result helpers
You can use plenty of action result helpers like Ok(), NotFound(), InternalServerError(), which all return IHttpActionResult, what makes your code easier to read and maintain and clearly state your intention.
Action result abstraction
Using IHttpActionResult you can easy abstract result, which is helpful when unit testing your controllers.
Available to self-host
Using OWIN you can easily self-host your WebAPI project, what makes your application much easier to maintain and IIS-independent.
Native attribute routing
WebAPI has implemented attribute routing which makes all routing configuration much more easier(and helps when using feature-based architecture).
DI configuration improvements
Both WebAPI and MVC have their own composition roots and different DI implementation. Microsoft has introduced some improvements in WebAPI to make it easier to use and maintain.
I'd say that using MVC + Ajax was viable only when WebAPI didn't exist because there was the only option.
If your project clients needs data in multiple formats (json,xml,csv) or have chance to change in future Wep Api needs minimal configuration comparing to mvc. Wep Api returns data to client according to content negotiation (if client needs xml returns xml,if json return json according to request header ) but in mvc you need more code to satisfy that.You have to explicitly specify data format when writing action methods.(JsonResult,ActionResult,XmlResult)
Wep Api gives you more meaningful idea about what you are doing when you look at the code later.Comparing method signatures;
public List<Student> Get() has more meaning than public JsonResult Index().
Light weight & Easy to use.
Less data transfer between client and server.
Using webapi we can develop cross domain application.
Less configuration needed as compared to WCF.
It’s simple, scalable and robust because it supports all the MVC features such as routing, controllers, model binders, IOC container, action results, filter, or dependency injection as it is built on top of Asp.Net MVC.
Empower the developers by handing over control over the way HTTP protocol messages are sent and responded to.
Unit testing is easy as it support test driven development.
It provides ample flexibility in web API creation due to content negotiation and drives support for the ASP.NET routing.
Unlike WCF REST services, there is no need to define tedious configuration settings for different devices.
The architecture of web APIs is very light, which makes them a perfect alternative for the developers when they want to build applications for devices with limited bandwidth.
Web APIs are used to create non-SOAP-based HTTP Services, so if there is a requirement for web services, but not SOAP, then ASP.Net Web API is great to look for.
Supports different message format like json, plain text and xml.
Asp.Net Web API supports convention-based CRUD Actions since it works with HTTP verbs GET, POST, PUT and DELETE.
I am searching about the different ways one can manage an nhibernate session in a web api project. The simplest solution I found binds the session to HttpContext when the request begins. Other, more complex, solutions use dependency injection.
My question is there any reason for not choosing the easiest way of binding the session to HttpContext on BeginRequest?
My question is there any reason for not choosing the easiest way of
binding the session to HttpContext on BeginRequest?
The reason is that Web API is designed to work with OWIN. This means that it could be hosted outside ASP.NET where notions like HttpContext and BeginRequest simply won't exist. So using them you are tying your application to an ASP.NET host forever which is exactly what the designers of the Web API tried to avoid by porting it to the OWIN middleware.
So you can use the HttpRequestMessage.Properties dictionary instead to store your NHibernate session and achieve per-request lifetime.
We have a Silverlight intranet application using old web services, and I've been tasked with adding support for SSL. To do this I was planning to ditch the old web services and replace them with a new WCF service.
I also needed to get rid of the old web references and build the proxy dynamically as well (because the endpoint will vary), and found this useful article which outlines how to build dynamic proxies http://sonyarouje.com/2010/10/01/proxy-less-silverlight-wcf-communication.
I now have that working (although I now need to work out how to call a method that has parameters) but I've just discovered that (a) Silverlight only supports BasicHttpBinding (i.e. not ws), and (b) BasicHttpBinding does not support session state.
Our application currently uses session to keep track of and queue up requests through our singleton data access layer. The only thing I can think of doing at the moment is to write my own implementation of session - but I was wondering if there's a better solution that I'm missing, hence this post.
So basically, is there a 'best practice' approach that supports Silverlight, WCF, session state and SSL, or am I right to go ahead and replace session with my own equivalent?
I think you've mixed WCF session with ASP.NET Sessions. WCF Session and ASP.NET sessions are completely different.
In your case, to enable ASP.NET state in WCF service, you'd just require to enable ASP.NET Compatibility Mode on service,
Please find a very good blog on the same by wenlong,
http://blogs.msdn.com/b/wenlong/archive/2006/01/23/516041.aspx
HTH,
Amit