Handle RequestCookieCollection class in .net6 - .net-6.0

RequestCookieCollection class is not supported in .net 6. I want to make below code compatible in .net6 as i have migrated my application from .netcore2.1 to .net6
Dictionary<string, string> cookies = new Dictionary<string, string>();
foreach (var existingCookie in context.Request.Cookies)
cookies.Add(existingCookie.Key, existingCookie.Value);
var collection = new RequestCookieCollection(cookies);
context.Request.Cookies = collection;

Related

How to do bulk update using elasticsearchOperations in Spring data elasticsearch?

We were doing bullk insert by using bulkIndex as follow:
List<IndexQuery> indexQueries = new ArrayList<>();
for (FooDocument fooDocument : fooDocuments) {
IndexQuery query = new IndexQueryBuilder()
.withId(String.valueOf(fooDocument.getId()))
.withObject(fooDocument)
.build();
indexQueries.add(query);
}
elasticsearchOperations.bulkIndex(indexQueries, IndexCoordinates.of("foo_index_3"));
We also want to use for bulk updates something like:
elasticsearchOperations.bulkUpdate(updateQueries, IndexCoordinates.of("foo_index_3"));
But bulkUpdate requires list of UpdateQuery.I am trying to create it by doing something like:
List<IndexQuery> updateQueries = new ArrayList<>();
for (FooDocument fooDocument : fooDocuments) {
UpdateQuery updateQuery = new UpdateQueryBuilder()//which Builder class and method is required?
.withId(String.valueOf(fooDocument.getId()))
.withObject(fooDocument)
.build();
updateQueries.add(query);
}
But unlike IndexQueryBuilder there is no UpdateQueryBuilder() available, what is the correct way to build the UpdateQuery and which Builder class should we use? I am wondering whether UpdateQueryBuilder class has been deprecated.
P.S: we are using 4.0.2.RELEASE version of spring-data-elasticsearch
You create an UpdateQuery with a builder like this:
UpdateQuerybuilder builder = UpdateQuery.builder(id)
.with(...)
.build();
Here the builder is a nested class and not a separate one.

ElasticSearch Connection settings

I just created ElasticSearch class and find some codes for elasticsearch connection settings but i know i am using NEST 7.0 and these codes i found are lower version than 7.0 so, how i can change to current version because i am getting some errors. Thanks in advance.
private static readonly ConnectionSettings connSettings = new ConnectionSettings(new Uri("http://localhost:9200/"))
.DefaultIndex("change_history")
.DefaultMappingFor(m => m
.Add(typeof(ChangeLog), "change_history"));
private static readonly ElasticClient elasticClient = new ElasticClient(connSettings);
especially the defaultmapping part :)
The configuration options documentation has an example. Adapted for your example
private static readonly ConnectionSettings connSettings =
new ConnectionSettings(new Uri("http://localhost:9200/"))
.DefaultIndex("change_history")
.DefaultMappingFor<ChangeLog>(m => m
.IndexName("change_history")
);
private static readonly ElasticClient elasticClient = new ElasticClient(connSettings);

Deserializing DynamoDBResults with gson fails

I have a specific use case where I store the results from my one table in DynamoDB to be stored in a serialized manner in another DynamoDB.
Now when I use gson to deserialize the data being retrieved,
I get this error:
java.lang.RuntimeException: Unable to invoke no-args constructor for class java.nio.ByteBuffer. Register an InstanceCreator with Gson for this type may fix this problem.
at com.google.gson.internal.ConstructorConstructor$12.construct(ConstructorConstructor.java:210)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:186)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:103)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:196)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:187)
at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:145)
at com.google.gson.Gson.fromJson(Gson.java:810)
at com.google.gson.Gson.fromJson(Gson.java:775)
My method looks like this:
public void store(MyCustomObject obj) {
String primaryKey = obj.getKey();
List<Map<String, AttributeValue>> results = AmazonDynamoDB.query(...).getItems();
Gson gson = new Gson();
List<String>records = results .stream()
.map(mappedResult-> gson.toJson(mappedResult))
.collect(Collectors.toList());
Map<String, AttributeValue> attributeMap = transformToAttributeMap(records);
PutItemRequest putItemRequest = new PutItemRequest().withItem(attributeMap);
AmazonDynamoDB.putItem(...);
}
The method to retrieve the records looks something like this:
public void retrieve(String id) {
QueryRequest...
Map<String, AttributeValue> records = DynamoDB.query(...).getItems();
List<String> serializedRecords = new ArrayList<>();
List<AttributeValue> values = records.get("key");
for( AttributeValue attributeValue: values) {
serializedRecords.add(attributeValue.getS());
}
Gson gson = new Gson();
Type recordType = new TypeToken<Map<String, AttributeValue>>() { }.getType();
List<Map<String, AttributeValue>> actualRecords = serializedRecords.stream()
.map(record-> gson.fromJson(record, recordType))
.collect(Collectors.toList());
}
What am I doing wrong?
The problem is AttributeValue class has a field java.nio.ByteBuffer with name b. Gson tries to deserialize the data into it, but there is no default constructor for ByteBuffer class. Therefore gson cannot deserialize b field.
An alternative solution is with the new DynamoDB usage of AWS SDK. Following example should work:
AmazonDynamoDBClient client = new AmazonDynamoDBClient(
new ProfileCredentialsProvider());
Item item = new DynamoDB(client).getTable("user").getItem("Id", "user1");
String json = item.toJSON();
Item deserialized = Item.fromJSON(json);
You should modify the credentials provider according to your setup.
Not exactly the best workaround/answer, but I was able to do this:
Item item = new Item().withJSON("document", jsonStr);
Map<String,AttributeValue> attributes = InternalUtils.toAttributeValues(item);
return attributes.get("document").getM();

Web API Nunit Tests not injecting dependencies

When trying to unit test my web api project I am getting the error
{[Message, An error has occurred.]}
ExceptionMessage, An error occurred when trying to create a controller of type 'ExampleController'. Make sure that the controller has a parameterless public constructor.
{[ExceptionType, System.InvalidOperationException]}
{[StackTrace, at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()]}
{[InnerException, System.Web.Http.HttpError]}
Unit Test:
[TestFixtureSetUp]
public void TestsSetup()
{
_server = HttpRequestHelper.SetupHttpServerDefault();
}
[Test]
public void CanGetAllAddresses()
{
var client = new HttpClient(_server);
var request = HttpRequestHelper.CreateRequest("memory/address", HttpMethod.Get, ConfigurationManager.AppSettings["KeyUser"], string.Empty, ConfigurationManager.AppSettings["SecretUser"]);
using (HttpResponseMessage response = client.SendAsync(request).Result)
{
Assert.NotNull(response.Content);
}
}
I am registering my controllers within an nunit TestFixtureSetUp function that involves this logic:
public static HttpServer SetupHttpServerDefault()
{
var config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "memory/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
var container = new Container();
container.Register<IAddressService, AddressService>();
var services = GlobalConfiguration.Configuration.Services;
var controllerTypes = services.GetHttpControllerTypeResolver().
GetControllerTypes(services.GetAssembliesResolver());
foreach (var controllerType in controllerTypes)
{
var registration = Lifestyle.Transient.
CreateRegistration(controllerType, container);
container.AddRegistration(controllerType, registration);
registration.SuppressDiagnosticWarning
(DiagnosticType.DisposableTransientComponent, "");
}
container.Verify();
GlobalConfiguration.Configuration.DependencyResolver = new
SimpleInjectorWebApiDependencyResolver(container);
return new HttpServer(config);
}
My address controller starts out like this:
public class AddressController : BaseController
{
private readonly IAddressService _addressService;
public AddressController(IAddressService addressService)
{
_addressService = addressService;
}
}
When removing the controller parameters I am able to debug into the controller which tells me I am not injecting the dependencies into the controller correctly. I've looked over this post here that seems similar but I am unfamiliar with how I would explicitly declare my controllers. I tried using a similar method to my services but I did not work.
The solution for my particular problem was actually to register the dependency resolver on both the in memory HttpServer that I am creating in the tests and on the GlobalConfiguration as well. Above in the question you'll see the creation of the config variable and then this is the code that fixed my issues:
config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver =
new SimpleInjectorWebApiDependencyResolver(container);
Without the config.DependencyResolver I wasn't able to connect to my projects controllers via:
using (HttpResponseMessage response = client.SendAsync(request).Result)
And without GlobalConfiguration.Configuration.DependencyResolver I wasn't able to contact services locally in my test project. Hope this helps someone else!

Asp.net Identity, Generate WebApi token OAuthGrantResourceOwnerCredentialsContext - no access to UserManager using Unity

I am trying to setup a project structure so that I have a WebApi, WebUI and Domain layer. I have moved all the Asp.Net.Identity objects into the Domain layer and have also setup the ApplicationContext here too (inheriting from IdentityContext).
(I have used this tutorial and package as a base which is excellent. http://tech.trailmax.info/2014/09/aspnet-identity-and-ioc-container-registration/)
In the WebAPI layer I am able to use the Account controller correctly to login and register. However, I cannot generate an access token.
The OAuthGrantResourceOwnerCredentialsContext method internally uses
var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
This works fine but doesnt give me the same context as my Account Controller as I am using Unity constructor injection in this to use my ApplicationUserManager from the domain.
I have tried injecting the OAuth class but I never seem to get the instance back.
Any advice?
Edit, this is what I have in Startup class in a default WebApi project.
// Configure the application for OAuth based flow
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true
};
So the ApplicationOAuthProvider seems to be used when getting an access token.
--
More info.
UnityConfig.cs
container.RegisterType<ApplicationDbContext>(); //this is referencing my domain layer
Startup.Auth.cs
app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<ApplicationUserManager>());
// Configure the application for OAuth based flow
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true
};
ApplicationOAuthProvider.cs
Have injected constructor as below
public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
{
private readonly string _publicClientId;
private ApplicationUserManager userManager;
public ApplicationOAuthProvider(ApplicationUserManager userManager)
{
this.userManager = userManager;
}
public ApplicationOAuthProvider(string publicClientId)
{
//this.userManager = userManager;
if (publicClientId == null)
{
throw new ArgumentNullException("publicClientId");
}
_publicClientId = publicClientId;
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
//var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>(); //PROBLEM LINE!!!
ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);
}
}
The problem line is shown above. This method gets called when requesting a token, and the userManager is always null.
Edit to show UnityWebApiActivator.cs
public static class UnityWebApiActivator
{
/// <summary>Integrates Unity when the application starts.</summary>
public static void Start()
{
// Use UnityHierarchicalDependencyResolver if you want to use a new child container for each IHttpController resolution.
// var resolver = new UnityHierarchicalDependencyResolver(UnityConfig.GetConfiguredContainer());
var resolver = new UnityDependencyResolver(UnityConfig.GetConfiguredContainer());
GlobalConfiguration.Configuration.DependencyResolver = resolver;
}
/// <summary>Disposes the Unity container when the application is shut down.</summary>
public static void Shutdown()
{
var container = UnityConfig.GetConfiguredContainer();
container.Dispose();
}
}
I have just create pure WebApi project with Identity, checked over the classes and not sure I understand your question correctly.
The standard VS2013 template contains this in Startup.Auth.cs:
public partial class Startup
{
public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
public static string PublicClientId { get; private set; }
// For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder app)
{
// blah - other stuff
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
Provider = new ApplicationOAuthProvider(PublicClientId),
// another blah
};
app.UseOAuthBearerTokens(OAuthOptions);
//blah-blah-blah
}
}
I have checked and ApplicationOAuthProvider is not used anywhere else. So no need to inject it.
Inside of this class, as you say, it calls for context.OwinContext.GetUserManager<ApplicationUserManager>() to get user manager. If you get an incorrect instance of ApplicationDbContext there, then you inject incorrect instance of ApplicationUserManager into Owin context. Do you still have a line with this:
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
Go replace it with this:
app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<ApplicationUserManager>());
This should do the job - would be the best solution.
Alternatively in ApplicationOAuthProvider replace line where you get the ApplicationUserManager from OWIN context with this:
var userManager = DependencyResolver.Current.GetService<ApplicationUserManager>()
This should resolve your user manager from Unity, giving you correct DbContext.

Resources