Location of IWebProxy implementation for .NET Core - .net-core

What is the available implementation of the System.Net.IWebProxy (from System.Net.Primitives, DNX Core)? By application requirement, the only framework can be used in dnxcore50, so what is the right NuGet package that contains proxy implementations?
What is the correct way to resolve such questions? Related functionality seems to be split among dozen of packages.

Despite the name, IWebProxy implementation does not actually need to implement any proxying, it just provides information about the proxy. So, you can create your own implementation:
public class MyProxy : IWebProxy
{
public Uri GetProxy(Uri destination)
{
return new Uri("http://localhost:8888");
}
public bool IsBypassed(Uri host)
{
return false;
}
public ICredentials Credentials { get; set; }
}

There is a WebProxy class in the System.Net namespace (source here) that you can use.

Make sure your project.json file has these two lines under "dependencies"
"frameworks": {
"dotnet5.4": {
"dependencies": {
"Microsoft.Net.Http": "2.2.29",
"System.Net.Primitives": "4.0.11-beta-23516"
}
}
}

Related

How can I get the baseurl of my site in ASP.NET Core?

Say my website is hosted in the mywebsite folder of www.example.com and I visit https://www.example.com/mywebsite/home/about.
How do I get the base url part in an MVC controller? The part that I am looking for is https://www.example.com/mywebsite
The example listed here doesn't work as we don't have access to Request.Url in ASP.NET Core
You should still be able to piece together what you need. You have access to the request object if your controller inherits from Controller.
If you are using VS2017, fire up a new ASPNet Core MVC app and replace the homecontroller with:
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult About()
{
ViewData["Message"] = $"{this.Request.Scheme}://{this.Request.Host}{this.Request.PathBase}";
return View();
}
public IActionResult Contact()
{
ViewData["Message"] = "Your contact page.";
return View();
}
public IActionResult Error()
{
return View();
}
}
I just put in some of the stuff that might interest you in the "About" method, but you should explore the rest of the request class so you know what else is available.
As #Tseng pointed out, you might have a problem when running Kestrel behind IIS or Azure App Service, but if you use the IISIntegration package or AzureAppServices package (by installing the Nuget package and adding it in Program.cs to your WebHostBuilder), it should forward those headers to you. It works great for me in Azure, because I sometimes have to make decisions based on which hostname they hit. The IIS/Azure packages also forward the original remote IP address, which I log.
If you need this anywhere in your app than you should create a class and add it as a service.
Define your static class and your extension method for adding it to the service pipeline like this.
public class MyHttpContext
{
private static IHttpContextAccessor m_httpContextAccessor;
public static HttpContext Current => m_httpContextAccessor.HttpContext;
public static string AppBaseUrl => $"{Current.Request.Scheme}://{Current.Request.Host}{Current.Request.PathBase}";
internal static void Configure(IHttpContextAccessor contextAccessor)
{
m_httpContextAccessor = contextAccessor;
}
}
public static class HttpContextExtensions
{
public static void AddHttpContextAccessor(this IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
public static IApplicationBuilder UseHttpContext(this IApplicationBuilder app)
{
MyHttpContext.Configure(app.ApplicationServices.GetRequiredService<IHttpContextAccessor>());
return app;
}
}
It might be a little redundant to expose the HttpContext in this case but I find it very helpful.
You would than add it to the pipeline in your Configfure method which is located in Startup.cs
app.UseHttpContext()
From there it is simple to use it anywhere in your code.
var appBaseUrl = MyHttpContext.AppBaseUrl;
All of these existing answers depend on an HttpContext object, which is only available during an incoming request. However, I needed to get the URLs in a background service where HttpContext was not available.
This information is also available in the Microsoft.AspNetCore.Hosting.Server.IServer service, as long as the actual host service provides this information. If you're using the default Kestrel server, I've found that it is indeed provided. I have not tested this when hosting IIS in-process or with other hosting models.
You need to get an instance of IServer and then look for the .Features entry of type IServerAddressesFeature.
Here's an extension method to get the URL(s) directly from an IServiceProvider:
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features;
public static ICollection<string> GetApplicationUrls(this IServiceProvider services)
{
var server = services.GetService<IServer>();
var addresses = server?.Features.Get<IServerAddressesFeature>();
return addresses?.Addresses ?? Array.Empty<string>();
}
You could however accomplish the same thing by injecting IServer if DI services are available.
using Microsoft.AspNetCore.Http;
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
public AccountController(IHttpContextAccessor httpContextAccessor)
{
var request = httpContextAccessor.HttpContext.Request;
var domain = $"{request.Scheme}://{request.Host}";
//domain => https://varunsoft.in
}
NPNelson answer works if with .Value.ToString()
var baseUrl = $"{this.Request.Scheme}://{this.Request.Host.Value.ToString()}{this.Request.PathBase.Value.ToString()}";
var baseUrl = Request.GetTypedHeaders().Referer.ToString();
This way you can capture the base url information.
This is how I could get it in Asp .Net Core 3.1 version.
You can access the resource from the link below.
Reference
string.Format("{0}://{1}{2}", Request.Url.Scheme, Request.Url.Authority, Url.Content("~"));
you can check for more information here:
How can I get my webapp's base URL in ASP.NET MVC?

ConfigurationManager.AppSettings.Get(key).ConvertTo error in asp.net core

Below is my code. I try to convert below code from asp.net to asp.net core. But in asp.net core in last line ConvertTo is showing error because Get(key) does not have definition of ConvertTo. Don't know what is the problem.
I am unable to find any solution how can i write below code in asp.net core?
public static T Get<T>(string key)
{
if (!Exists(key))
{
throw new ArgumentException(String.Format("No such key in the AppSettings: '{0}'", key));
}
return ConfigurationManager.AppSettings.Get(key).ConvertTo<T>(new CultureInfo("en-US"));
}
Thanks in advance.
I suggest you carefully reading the documentation first. In .NET Core the way how we work with configuration is changed significantly ( different source using, mapping to POCO objects , etc).
In your case you may simply use ConfigurationBinder’s GetValue<T> extension method instead of implementing own method for value conversion:
IConfiguration.GetValue - extracts the value with the specified key
and converts it to type T.
Configuration in .net Core is now built on top of POCO's or IOptions for the most part. You don't get individual keys but instead you build up settings classes. Previously you had to either build a CustomConfiguration class or you would prefix AppSettings to "group them". Not anymore! If you take the approach of using IOptions it works something like the following.
You have your appSettings.json look like the following :
{
"myConfiguration": {
"myProperty": true
}
}
You then make up a POCO that matches your configuration. Something like this :
public class MyConfiguration
{
public bool MyProperty { get; set; }
}
Then in your startup.cs you need to load your configuration into an options object. It will end up looking pretty similar to the following.
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MyConfiguration>(Configuration.GetSection("myConfiguration"));
}
}
Then the DI is all set up to inject an IOptions objects. You would then inject it into a controller like so :
public class ValuesController : Controller
{
private readonly MyConfiguration _myConfiguration;
public ValuesController(IOptions<MyConfiguration> myConfiguration)
{
_myConfiguration = myConfiguration.Value;
}
}
There is other ways to do this that don't use the IOptions object and you only inject in the POCO to your controllers. Some people (including me) prefer this method. You can read more here : http://dotnetcoretutorials.com/2016/12/26/custom-configuration-sections-asp-net-core/
And of course the documentation link for the official docs are here : https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration

How to inject different instance(s) for different context in ASP.NET MVC using StructureMap?

We are using classes inheriting from Registry to configure our StructureMap container in our ASP.NET MVC 4 application startup.
Some excerpt from one of the registry-classes:
For<ISomeInterface>().HybridHttpOrThreadLocalScoped().Use<SomeImplementation>();
We would like use different instances of our interfaces depending on the context. (For example switching from database "online" mode to "maintenance" mode where everything is saved on filesystem; therefore using other interfaces (i.e. repositories) all over the place in our application)
For example by default it should use SomeImplementation but when passing some kind of querystring in the url (to name a simple "context" scenario) it should use SomeOtherImplementation.
How can this be achieved for multiple interfaces/types?
Should we use named instances for this? Like:
For<ISomeInterface>().HybridHttpOrThreadLocalScoped().Use<SomeOtherImplementation>().Named("other");
I read about StructureMap Profiles but i'm not sure if this is the right way to go.
Should we use profiles for this? Like i.e.:
Profile("other", profileExpression =>
{
For<ISomeInterface>().HybridHttpOrThreadLocalScoped().Use<SomeOtherImplementation>();
});
How can we switch different configurations on the fly?
ObjectFactory.Container.SetDefaultsToProfile("other");
This way? (At what stage in mvc "life-cycle" this can happen at the earliest?)
Can this be a temporary switch for just the current request or current users session?
Thanks in advance!
From my experience, runtime configuration like this is best achieved using an abstract factory that is responsible for creating your dependency during runtime.
This dependency can then be registered with StructureMap like so:
Your registry:
public class StorageRegistry : Registry
{
public StorageRegistry()
{
...
this.For<IDataStoreInstance>().Use(ctx => ctx.GetInstance<DataStoreAbstractFactory>().ConfigureStorage());
...
}
}
Now your DataStoreAbstractFactory is responsible for creating and configure the necessary storage instance based on your configuration. As DataStoreAbstractFactory is now registered with StructureMap you're able to inject the necessary dependencies into it for determining which storage method to use.
Implementation example:
public class DataStoreAbstractFactory
{
public DataStoreAbstractFactory()
{
// Dependencies to figure out data storage method can be injected here.
}
public IDataStoreInstance ConfigureStorage()
{
// This method can be used to return type of storage based on your configuration (ie: online or maintenance)
}
}
public interface IDataStoreInstance
{
void Save();
}
public class DatabaseStorage : IDataStoreInstance
{
public void Save()
{
// Implementation details of persisting data in a database
}
}
public class FileStorage : IDataStoreInstance
{
public void Save()
{
// Implementation details of persisting data in a file system
}
}
Usage:
Your controller/services or whatever are now completely unaware of what storage method they're using when accessing and persisting data.
public class UpdateController : Controller
{
public IDataStoreInstance StorageInstance { get; set; }
public UpdateController(IDataStoreInstance storageInstance)
{
StorageInstance = storageInstance;
}
[HttpPost]
public ActionResult Index()
{
...
this.StorageInstance.Save();
...
}
...
}

Can I use my Ninject .NET project within Orchard CMS?

I am creating a website using Orchard CMS and I have an external .NET project written with Ninject for dependency injection which I would like to use together with a module within Orchard CMS. I know that Orchard uses Autofac for dependency injection and this is causing me problems since I never worked with DI before.
I have created an Autofac module, UserModule, which registers the a source, UserRegistrationSource, like this:
UserModule.cs
public class UserModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterSource(new UserRegistrationSource());
}
}
UserRegistrationSource.cs
public class UserRegistrationSource : IRegistrationSource
{
public bool IsAdapterForIndividualComponents
{
get { return false; }
}
public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
{
var serviceWithType = service as IServiceWithType;
if (serviceWithType == null)
yield break;
var serviceType = serviceWithType.ServiceType;
if (!serviceType.IsInterface || !typeof(IUserServices).IsAssignableFrom(serviceType) || serviceType != typeof(IUserServices))
yield break;
var registrationBuilder = // something...
yield return registrationBuilder.CreateRegistration();
}
}
UserServices.cs
public interface IUserServices : IDependency
{
void Add(string email, string password);
}
public class UserServices : IUserServices
{
private readonly EFMembershipManager _manager;
public UserServices(EFMembershipManager manager)
{
_manager = manager;
}
public void Add(string email, string password)
{
_manager.createUser(email, password);
}
}
EFMembershipManager.cs constructor
public EFMembershipManager(ServerRepository db,
ServerRepositoryMembershipProvider membershipProvider,
string testUsername,
string serverUsername)
{
...
}
EFMembershipManager is a class from the external project which uses Ninject for DI's and uses ServerRepository and ServerRepositoryMembershipProvider whom also are injected using Ninject.
And now I'm stuck...
Should UserRegistrationSource take the Ninject container (kernel) as a constructor argument and try to find the IUserServices service and then mediate the resolves to the Ninject kernel and return an empty Enumerable so that Autofac doesn't try to resolve anything related to IUserServices or is this the wrong approach?
Autofac supports registration sources (and more on registration sources here). A registration source is a service that the container will consult when trying to resolve a type. The source can respond, either with a means to build the type, or an empty list which indicates that the source is not able to provide the requested type.
In your case, a registration source could be implemented that will try to resolve the requested type from your Ninject container.
I'm not too familiar with Orchard but I'm guessing that it uses configuration files to configure Autofac. My suggestion is that you create a simple Autofac module that registers your registration source implementation, and that you configure Orchard to load the module from config.

Flex + BlazeDS + Multi module maven project

I've got a multi module Maven project (about 10 modules) where 2 of the modules are a flex project and its corresponding server project, communicating via BlazeDS.
The server module is dependent on another module containing common things, shared over the whole project. When using objects from the common module, the objects aren't serialized and sent via AMF to the SWF. Everything in the server-module is serialized and is working fine, but the objects from the common module (which has valid values on the server side) is not sent to the client.
I'm using Flexmojos to build this. What do I have to do to make the classes in the common project available for serialization, and being able to use them as RemoteClass-objects in my swf-project?
The basic structure is similar to this (I've tried so simplify it quite a bit):
swf-module (Flex):
Class MyObject.as:
package swf.model {
[RemoteClass(alias="server.model.MyObject")]
public class MyObject {
public var name:String;
public var common:MyCommonObject;
}
}
Class MyCommonObject.as:
package swf.model {
[RemoteClass(alias="common.model.MyCommonObject")]
public class MyCommonObject {
public var commonNumber:Number; }
}
server-module (Java):
Class MyObject.java:
package server.model;
import common.model.MyCommonObject;
public class MyObject {
private String name;
private MyCommonObject common;
public MyObject() {}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public MyCommonObject getCommon() {
return common;
}
public void setCommon(MyCommonObject common) {
this.common= common;
}
}
common-module (Java)
Class MyCommonObject.java:
package common.model;
public class MyCommonObject{
private Double commonNumber;
public MyCommonObject() {}
public Double getCommonNumber() {
return commonNumber;
}
public void setCommonNumber(Double commonNumber) {
this.commonNumber= commonNumber;
}
}
Java server side DTOs and ActionScript client DTOs are independent. I mean the following. When your BlazeDS services return AMF-serialized DTOs their binary structure is described by AMF format. And AMF transfer data contains full classpath which you describe on a client side using RemoteClass metadata. In this way client Flex project and Java server project haven't dependencies on each other in process of building. But you can build them together to produce the same WAR which contains both client and server part.
I have actually had to do this, you can go here, get the source for BlazeDS, add it to your project and debug to your heart's content.
I Think your common-module JAR is not in classpath of Flex module/WAR/BlazeDS,
try to put common module JAR in Flex modules war
means PUT {common module}.jar in {BlazeDS}\WEB-INF\lib\ on deployment
if its not there.
Hopes it works

Resources