Unable to configure 'IApplicationBuilder UseOwin' - c#

As stated in official document, I am trying to implement UseOwin in the Startup.cs.I am trying to use/port IAppBuilder (Microsoft.Owin.Builder.AppBuilder) inside IApplicationBuilder (Microsoft.AspNetCore.Builder.IApplicationBuilder). I had legacy code written using IAppBuilder running fine on .Net Framework 4.5.
I have seen couple of examples about using IAppBuilder in IAplicationBuilder e.g. example 1 example 2. These attempts were about .netcore 1.1 and not .net core 2.0. May be this is the reason i am unable to port.
Please share your thoughts whether i am trying to achieve something not possible at the moment in .net core 2.0 or there is some error in my code.
Note:
I am using dotnetcore 2.0 with Visual Studio 2017
Error
I am getting following error.
return owinAppBuilder.Build,
Task>>(); TypeLoadException: Could not load type
'System.Security.Cryptography.DpapiDataProtector' from assembly
'System.Security, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a'.
My attempt
app.UseOwin(setup => setup(next =>
{
var owinAppBuilder = new AppBuilder();
var aspNetCoreLifetime =
(IApplicationLifetime)app.ApplicationServices.GetService(typeof(IApplicationLifetime));
new AppProperties(owinAppBuilder.Properties)
{
OnAppDisposing = aspNetCoreLifetime?.ApplicationStopping ?? CancellationToken.None,
DefaultApp = next,
AppName = "test"
};
// Only required if CORS is used, configure it as you wish
var corsPolicy = new System.Web.Cors.CorsPolicy
{
AllowAnyHeader = true,
AllowAnyMethod = true,
AllowAnyOrigin = true,
SupportsCredentials = true
};
//corsPolicy.GetType()
// .GetProperty(nameof(corsPolicy.ExposedHeaders))
// .SetValue(corsPolicy, tusdotnet.Helpers.CorsHelper.GetExposedHeaders());
owinAppBuilder.UseCors(new Microsoft.Owin.Cors.CorsOptions
{
PolicyProvider = new CorsPolicyProvider
{
PolicyResolver = context => Task.FromResult(corsPolicy)
}
});
PublicClientId = "self";
OAuthAuthorizationServerOptions OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new Microsoft.Owin.PathString("/Login"),
Provider = new MyServiceProvider(PublicClientId),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(60),
AllowInsecureHttp = true,
RefreshTokenProvider = new MyRefreshTokenProvider(),
};
owinAppBuilder.UseOAuthBearerTokens(OAuthOptions);
//owinAppBuilder.UseTus(context => new DefaultTusConfiguration
//{
// // Excluded for brevity, use the same configuration as you would normally do
//});
return owinAppBuilder.Build<Func<IDictionary<string, object>, Task>>();
}));

Microsoft.Owin and related packages do not have targets for .NET Core, no for .NET Standard. All they have is dlls targeting full .NET. You can reference such libraries from your project targeting .NET Core, but they are not guaranteed to work, as you see yourself, because API (set of classes\methods\signatures) of full .NET and .NET Core are different. Visual Studio even will show a warning when you are doing that, for example:
Package 'Microsoft.Owin 3.1.0' was restored using
'.NETFramework,Version=v4.6.1' instead of the project target framework
'.NETCoreApp,Version=v2.0'. This package may not be fully compatible
with your project.
There is Microsoft.AspNetCore.Owin package and you can use OWIN middleware in .NET Core app as your first link describes, but almost all it provides is UseOwin extension method. There is no AppBuilder type there and so on, and there are no Microsoft.AspNetCore.Owin.Cors packages or similar. So you have to either implement all that yourself (no reason to, because you can use the same functionality provided by asp.net core framework) or wait for OWIN packages that target .NET Standard\Core and do that (didn't check, maybe they even exist already).
So, your code uses packages which are indeed not compatible with your target framework, as exception you have at runtime shows. So another answer (for some reason downvoted) is technically correct.
If you still want to use those packages reliably - you need to target full .NET Framework and not .NET Core. To do that, open your .csproj file and change
<TargetFramework>netcoreapp2.0</TargetFramework>
To some .NET framework version that supports .NET Standard 2.0, for example:
<TargetFramework>net47</TargetFramework>
Then go to nuget package manager and, if you have microsoft.aspnetcore.all package (or other packages targeting .NET Core) - uninstall it, you don't need it anyway. Then install Microsoft.AspNetCore package and all other asp.net core packages you need (if not installed already). Rebuild, run and it will work just fine.
That works because all (most?) AspNetCore packages target .NET Standard, not .NET Core, and you can use them in projects targeting full .NET Framework.
Note that by doing that you have asp.net Core project, but not on .NET Core, with all consequences that come from that (cannot run with dotnet run, on linux need to run with mono, and so on).

The Microsoft.Owin components will not work on dotnet core 2.0, they only work on .NET 4.5+

Related

Does SevenZipSharp work with .NETCore on Windows?

I have a .NETCore app which I am trying to add 7 zip functionality to.
Compiling gives this warning:
warning NU1701: Package 'SevenZipSharp 0.64.0' was restored using '.NETFramework,Version=v4.6.1, .NETFramework,Version=v4.6.2, .NETFramework,Version=v4.7, .NETFramework,Version=v4.7.1, .NETFramework,Version=v4.7.2, .NETFramework,Version=v4.8' instead of the project target framework 'net5.0'. This package may not be fully compatible with your project.
So I presume the project is .NETCore v5.0. Can I run SevenZipSharp in this project?
Running the app gives an error at the call to CompressFiles: SevenZip.SevenZipLibraryException: 'Can not load 7-zip library or internal COM error! Message: failed to load library.'
public void ZipQOB(string sevenZipDllPath, string zippedQobPath, string unzippedQobFiles)//List<string> sourceFiles)
{
// throw exception if paths passed in are null, does 7zipsharp throw exceptions in this case?
try
{
if (System.IO.File.Exists(sevenZipDllPath) && System.IO.Directory.Exists(zippedQobPath))// && System.IO.Directory.Exists(unzippedQOBFiles))
{
string path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "7z.dll");
//SevenZipCompressor.SetLibraryPath(sevenZipDllPath);
SevenZipCompressor.SetLibraryPath(path);
SevenZipCompressor sevenZipCompressor = new()
{
CompressionLevel = SevenZip.CompressionLevel.Ultra,
CompressionMethod = CompressionMethod.Lzma
};
string[] files = System.IO.Directory.GetFiles(unzippedQobFiles);
sevenZipCompressor.CompressFiles(zippedQobPath + #"\zip.QOB", files);
//System.IO.Path.ChangeExtension(zippedQobPath, ".QOB");
}
This question How do I use 7zip in a .NET Core app running on Linux? mentions a CLI wrapper ported from .NET Framework to .NET Core, but I can't find any details - is this something I would have to write and how?
I have already tried things suggested elsewhere, I altered the project build setting to:
Platform Target = AnyCPU,
ticked Prefer 32-bit
Should I just look at a different option as this page seems lists some stating .netcore compatible: https://github.com/topics/7zip?l=c%23
Many thanks for any help :)

C# dotnet Core project referencing Entity Framework Standard DLL

I'm trying to reference dlls in my dotnet core project that are using Entity framework standard, not core.
The problem that i'm running into with dotnet core is that the connection strings that are defined in the appsettings.json are not being read by the referenced dlls, so I get the error:
Message=No connection string named 'Entities' could be found in the application config file.
In the dotnet core app I'm able to get the connection string using EF core with:
"ConnectionStrings": {
"Entities": "my connection info", // this works
},
services.AddDbContext...
This all works. The problem that I run into now is that a lot of our legacy code is .net standard, and i'd prefer to just continue to use them as libraries for now.
Where it fails in the referenced libraries is when
using (var context = new Entities()) // here
Do I need to modify the entity framework layer in the referenced libraries so that they can accept a connection string as a parameter? That would require a lot of updating very old code.

Running web job gives ArgumentNullException on start

I'm developing an Azure webjob using .NET Framework but when I'll run this localy, I've this exception after the startup.
Microsoft.Azure.WebJobs.Host.Listeners.FunctionListenerException: The listener for function [Name of function] was unable to start.
Inner exception:
ArgumentNullException: Value cannot be null.
Parameter name: connectionString
This is the code inside the Program class of the web job.
static void Main()
{
HostBuilder builder = new HostBuilder();
builder.ConfigureWebJobs(b =>
{
b.AddAzureStorageCoreServices();
b.AddTimers();
});
using (IHost host = builder.Build())
{
host.Run(); // <-- error happens on this line
}
}
Inside the App.config I've added next two connection strings:
<add name="AzureWebJobsDashboard" connectionString="DefaultEndpointsProtocol=https;AccountName=[Name];AccountKey=[Key]" />
<add name="AzureWebJobsStorage" connectionString="DefaultEndpointsProtocol=https;AccountName=[Name];AccountKey=[Key]" />
With [Name] and [Key] as the account name en key from a live environment.
Also when I change the connection strings to UseDevelopmentStorage=true, I'm getting the same exception.
How could I solve this?
Update:
If you're using Azure WebJobs SDK of version 3.x with .NET Framework, there is an issue: Version 3.x is incompatible with .NET Framework and PackageReference.
So there're several ways as workaround:
Directly use the Azure WebJobs template from Visual studio, it's based on .net framework.
You can add an appsettings.json file (Note: right click the file → select Properties → then set "Copy to Output Directory" to "Copy if newer") to the .NET Framework project, it will work(based on 1, it will throw errors, but it can work). The JSON file looks like below:
{
"AzureWebJobsStorage": "{storage connection string}"
}
The best solution is to use .NET Core with WebJobs SDK of version 3.x.
Original answer:
If you're using WebJob SDK version 3.x, I suggest you should create a .NET Core console project instead of .NET Framework console project, then you should follow this official doc.
First, create a .NET Core console app. And install all the necessary packages mentioned in the official doc.
Your program.cs:
static void Main()
{
HostBuilder builder = new HostBuilder();
builder.ConfigureWebJobs(b =>
{
b.AddAzureStorageCoreServices();
b.AddAzureStorage();
b.AddTimers();
});
using (IHost host = builder.Build())
{
host.Run();
}
}
Then create a function, please refer to this section.
Then add an appsettings.json file (Note: right click the file → select Properties → then set "Copy to Output Directory" to "Copy if newer"), add the AzureWebJobsStorage inside it:
{
"AzureWebJobsStorage": "{storage connection string}"
}
Please let me know if you still have more issues about that.

.Net Core 3.0 invoking .Net Framework 4.8 program via Reflection

I have a .net Core 3.0 application attempting to invoke .Net Framework 4.8 via reflection. Our goal is to read encrypted AppSettings.config (xml) with ConfigurationManager, which is not possible in .Net Core. Unencrypted yes, but encrypted (CipherData), no.
My reflection code that accesses a static class & method goes like this:
Assembly assembly = Assembly.LoadFrom(exeFullName);
MethodInfo method = assembly.GetType(nameSpacenClass).GetMethod(methodName);
if (method != null)
{
object rtnVal = method.Invoke(null, new object[] { jsonParms });
return rtnVal;
}
else
return null;
The method.Invoke errorred out with this exception message:
FileNotFoundException: Could not load file or assembly 'System.Configuration.ConfigurationManager, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot find the file specified.
So I wrote a proxy program in .Net Framework 4.8, and use the same code to access the code that reads encrypted config via reflection, and it works fine.
Then, I coded .net Core 3.0 to access that proxy via reflection, and it fails. The proxy .Net Framework 4.8 has no references whatsoever. It is barebone. Yet core still requires ConfigurationManager even though the proxy does not. The Config program has only one reference - to System.Configuration.
Core 3.0 => Encrypted App.config => Failed
Core 3.0 => ConfigProgram 4.8 => App.Config => Failed
ConfigProgram 4.8 => App.config => Works
Proxy 4.8 => ConfigProgram 4.8 => App.Config => Works
Core 3.0 => Proxy 4.8 => ConfigProgram 4.8 => App.Config => Failed
I guess the referenced System.Configuration is not required for Reflection invoke by 4.8 but is required even though trough a barebone stepping stone, by .Net Core 3.0. Could someone help me please?
When you load an assembly built for .NET Framework via reflection on .NET Core, it does not load any parts of .NET Framework - just your assembly ("user cod"). And some parts may or may not work. In your case it fails because the requested classes / assemblies of the code compiled for .NET Framework is not part of .NET Core.
This is the reason why only the cases where you start a .NET Framework application to begin with - thus booting up the .NET Framework Runtime - work for you.

How to upgrade Sustainsys.Saml2 from version 0.23.0 to version 2.0.0

I want to upgrade Sustainsys.Saml2 Nuget package from version 0.23.0 to version 2.0.0.
I have an error in next line of code: spOptions.SystemIdentityModelIdentityConfiguration.AudienceRestriction.AudienceMode = AudienceUriMode.Never;.
The SPOptions class doesn't have a IdentityConfiguration property anymore.
var spOptions = new SPOptions();
spOptions.SystemIdentityModelIdentityConfiguration.AudienceRestriction.AudienceMode = AudienceUriMode.Never;
I want to know how to receive the same behaviour after updating to version 2.0.
It's currently not supported in 2.2 to ignore the audience restriction. I you need that, and still run on the .NET Framework you might as well use 1.0.0.

Categories

Resources