I am attempting to get access to the underlying JSON object (request body) within a service call in service stack. The reason I wish to do this is to create a PATCH version of an existing service, which will only attempt to update fields that were in the JSON. Seems simple enough:
public object Patch(AddUpdateContactRequest request)
{
var json = this.Request.GetRawBody();
var keysToUpdate = JsonSerializer.DeserializeFromString<Dictionary<string, string>>(json);
return Put(request);
}
However, I get an exception from service stack when GetRawBody() is called (when service stack is calling in to .NET core):
Message: "Could not load type
'Microsoft.AspNetCore.Http.Internal.BufferingHelper' from assembly
'Microsoft.AspNetCore.Http, Version=3.0.0.0, Culture=neutral,
PublicKeyToken=adb9793829ddae60'."
Source: "ServiceStack"
StackTrace: " at ServiceStack.Host.NetCore.NetCoreRequest.GetRawBody() in
C:\BuildAgent\work\3481147c480f4a2f\src\ServiceStack\Host\NetCore\NetCoreRequest.cs:line
211"
TargetSite: {System.String GetRawBody()}
TypeName: "Microsoft.AspNetCore.Http.Internal.BufferingHelper"
It seems to be referencing version 3.0 of Microsoft.AspNetCore.Http, but this version does not have the namespace Microsoft.AspNetCore.Http.Internal.BufferingHelper. It looks like a version mismatch issue, but I cannot seem to make it work. I cannot see any dll version conflicts locally, I am implicitly referencing the latest version of .NET core and have the latest SDK/hosting package installed.
If this is .NET Core 3.0 this is due to a breaking change in .NET Core 3.0 which has been resolved in the latest v5.7.1 packages on MyGet.
Related
I am trying to connect to a gRPC service in a .NetFramework 4.5 windows application. I am currently using metapackage nuget Grpc which I know is only in maintenance mode now...
I need to access the service which is not at a host:port location, but has a subpath, subdirectory. My service is located here "https://example.com/mySubpath"
Is there a way to specify a subdirectory, subpath for gRPC calls in .NetFramework?
For .NetFramework4.5, if I specify the full path (which contains the "mySubpath" part) it doesn't work
var channel = new Channel("example.com/mySubpath", ChannelCredentials.SecureSsl);
I saw that I could also add a List<ChannelOption> parameter to the Channel constructor, but don't know if there is one option which I could use for that.
I am currently trying to upgrade to .NetFramework 4.6.1 to see if I can use Grpc.Net.Client which I understood it has some support over .NetFramework 4.6.1 if a WinHttpHandler is used. (https://learn.microsoft.com/en-us/aspnet/core/grpc/netstandard?view=aspnetcore-6.0)
I have found a solution here https://github.com/grpc/grpc-dotnet/issues/880 for .NetCore and I am trying to see if I can use that to the .NetFramework 4.6. I used the SubdirectoryHandler class as it is defined in the link to change the RequestUri and assigned a WinHttpHandler
var handler = new SubdirectoryHandler(new WinHttpHandler(), subpath);
var httpClient = new HttpClient(handler);
GrpcChannel channel = GrpcChannel.ForAddress(address, new GrpcChannelOptions { HttpClient = httpClient });
but I am getting an exception related to assembly System.Buffers, Version=4.0.2.0.
StatusCode="Unavailable",
Detail="Error starting gRPC call. HttpRequestException: Error while copying content to a stream. FileLoadException: Could not load file or assembly 'System.Buffers, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)",
I think this is because Grpc.Net.Client references version=4.0.2.0, while the System.Net.Http.WinHttpHandler references version 4.0.3.0.
Any idea what I need to change to be able to use the subdirectory,subpath for .NetFramework 4.6.1 or for .NetFramework4.5?
After update ef core to version 5, from 3.1. I get error:
System.Reflection.ReflectionTypeLoadException: 'Unable to load one or more of the requested types.
Could not load type 'Microsoft.EntityFrameworkCore.Query.IParameterValues' from assembly 'Microsoft.EntityFrameworkCore, Version=5.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.'
This error show up during using Automatic DI. Did Entity removed this extensions?
Thank you
this API no longer exists;
here it is in 3.1, but when you try for 5.0, it says:
The requested page is not available for Entity Framework Core 5.0. You have been redirected to the newest product version this page is available for.
So; the API is removed - that's allowed in a major, so: stop trying to configure/use it, I guess?
Trying to upgrade ASP.NET Boilerplate project from .NET Core 1.x to .NET Core 2.0
Solution builds successfully, but throws exception in Startup.ConfigureServices method at
services.AddAbpIdentity<Tenant, User, Role, SecurityStampValidator>(
options => {})
.AddUserManager<UserManager>()
.AddRoleManager<RoleManager>()
.AddSignInManager<SignInManager>()
.AddClaimsPrincipalFactory<UserClaimsPrincipalFactory>()
.AddDefaultTokenProviders();
Exception details
System.TypeLoadException: 'Could not load type 'Microsoft.AspNetCore.Authentication.SharedAuthenticationOptions' from assembly 'Microsoft.AspNetCore.Authentication, Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.'
You should wait ABP v3.0. We have released ABP v3.0.0-beta2. If you want, you can use beta version.
You also need to change your solution for:
https://learn.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/
https://learn.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x
Fortunately, I upgraded solution template. So, you can see all changes I done:
https://github.com/aspnetboilerplate/module-zero-core-template/pull/106/files
I'm working on a .net Core project, using the .net Core framework, I wanted to use DropNet package with .net Core so I added a reference to net452 framework inside my project.json:
"frameworks": {
"netcoreapp1.0": {
"imports": [
"dotnet5.6",
"portable-net45+win8",
"net452"
]
}
},
Now when I try to create a DropNet client object in my controller class I've got an error:
Error CS0012 The type 'IWebProxy' is defined in an assembly that is not referenced.
You must add a reference to assembly 'System, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089'. Test3..NETCoreApp,Version=v1.0
Ok in order to fix that error I've installed microsoft.netcore.portable.compatibility package, and the error is gone, the thing is that when I do that and execute the project and try to get access to the View that I'm returning from the controller action where I'm using DropNet I get a FileNotFoundException :
FileNotFoundException: Could not load file or assembly 'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. The system cannot find the file specified.
I'm having that problem only with that view, this is my Action Method:
public IActionResult Test()
{
DropNetClient client = new DropNetClient("gsfgsgsfg438", "6ysgsgs234cf", userToken: "w5gdfgsdfg3434d4", userSecret: "239usfgsghsf3434wyqo");
return View();
}
The problem is that DropNetClient line, if a comment that line, the view is showed, but if that line is active in there, the FileNotFoundException is thrown...
Please, don't abuse the import statement. It is there to override nuget validation when restoring packages, to install libraries which are compatible (PCL which target .NET 4.5 and Windows 8/8.1+) but do not yet have the netstandard1.6 target.
Don't EVER use it to force import net452 libraries into a .NET Core application. It won't work!!! .NET 4.5.2 libraries aren't compatible with .NET Core!!!
You only have two options:
Don't use any libraries which do not support netstandard, netcoreapp or portable-net45+win8!!!
If you need some libraries that only run with net452 and there is no replacement, then target net452 instead of netcoreapp1.0
We're having a weird problem when using Castle.Windsor to instantiate an SqlConnection using a typed factory:
The registration looks like this:
container.Register(Component.For<IDbConnectionFactory>().AsFactory().LifestyleTransient());
container.Register(Component.For<IDbConnection>().ImplementedBy<SqlConnection>()
.LifestyleTransient()
.DependsOn(Dependency.OnValue<string>
(ConfigurationManager.ConnectionStrings["DbConnectionString"].ConnectionString)));
And the IDbConnectionFactory:
public interface IDbConnectionFactory
{
IDbConnection Create();
void Release();
}
Now, when I try to access a new connection using this code:
using (var connection = _connectionFactory.Create())
{
}
I get an exception:
An unhandled exception of type
'Castle.MicroKernel.ComponentActivator.ComponentActivatorException' occurred
in Castle.Windsor.dll
Additional information: Error setting property SqlConnection.AccessToken in component
System.Data.SqlClient.SqlConnection. See inner exception for more information.
If you don't want Windsor to set this property you can do it by either decorating it
with DoNotWireAttribute or via registration API.
Alternatively consider making the setter non-public.
The problem with this Exception is that the type SqlConnection in System.Data for .NET 4.5.1 does not contain the property AccessToken whereas the one in .NET 4.6 does. In other words, if I try to manually do
var connection = new SqlConnection("connectionstring");
connection.AccessToken = "";
I get a build-error if the project is configured for .NET 4.5.1, but a runtime error on setting the AccessToken if it's configured for .NET 4.6.
Any idea why Castle.Windsor attempts to create a v4.6 SqlConnection instead of a .NET 4.5.1?
Workaround/Hack
I can get around the problem by telling Castle to ignore the property, but this seems like a hack. Doing this requires me to add it to the PropertiesIgnore in the registration:
container.Register(Component.For<IDbConnection>().ImplementedBy<SqlConnection>()
.PropertiesIgnore(info => info.Name.Equals("AccessToken"))
.LifestyleTransient()
.DependsOn(Dependency.OnValue<string>
(ConfigurationManager.ConnectionStrings["DbConnectionString"].ConnectionString)));
All .NET versions since 4.5 are in place updates
as you can see here.
This means that once you have installed .NET 4.6 you will always get the .NET 4.6 version of SqlConnection regardless of how you instantiate it.
When building your application in Visual Studio you build against a specific version of the .NET framework typically located in a folder under:
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework
This means that when building msbuild can check that you are not using something which isn't available in the framework version you are targeting.
However when you run your 64 bit application it will use the assemblies typically located in C:\Windows\Microsoft.NET\Framework64\v4.0.30319
This is the same folder for all versions from .NET 4.0 through .NET 4.6, this is what in place upgrade means.
So when you execute your application on your developement environment that has .NET 4.6 installed, you will always get the .NET 4.6 version (at least unless you do something special to load other versions of the assemblies).
Castle Windsor will try to set properties with public setter and it will use reflection to find the properties which means that it will find the .NET 4.6 properties on a .NET 4.6 machine, even if you are building against 4.5.1.
The reason it fails when it tries to set the AccessToken is most likely because your connection string is not compatible with setting AccessToken.
If you check the source code of the AccessToken setter you will see that it will throw an exception if you try to set it for a incompatible connection string, even if you only try to set the AccessToken to the empty string.
As you don't need to inject any dependencies into the SqlConnection object you may as well create it simply using the new operator and then you avoid the problem caused by Windsors attempts to inject the properties of the connection.
Using this registration should work:
container.Register(Component.For<IDbConnection>().ImplementedBy<SqlConnection>()
.LifestyleTransient()
.UsingFactoryMethod(() => new SqlConnection
(ConfigurationManager.ConnectionStrings["DbConnectionString"].ConnectionString)));