Null ref exception UseWhen UseHttpsRedirection? - c#

I can't get it. I'm trying to use UseHttpsRedirection conditionaly but keep getting null ref exception on builder.UseHttpsRedirection() line. What am I missing??
I use core 6.0.4
static void Main(string[] args)
{
var wab = WebApplication.CreateBuilder(args);
var wa = wab.Build();
wa.UseWhen(context => !context.Request.Path.StartsWithSegments("/exercises"),
builder =>
{
builder.UseHsts();
builder.UseHttpsRedirection();
});
wa.Run();
}

Related

Akka.Net in-memory persistence calls `Recover` after app restart

I'am trying to test persistence actor, but behavior is wierd.
My tested actor:
public class PredictionManager : ReceivePersistentActor
{
public override string PersistenceId => _persistanceId;
public PredictionManager(string persistenceId)
{
_persistanceId = persistenceId;
Command<AddPredictionRequest>(OnPrediction);
Recover<SnapshotOffer>(x => OnRecover((PredictionManagerState)x.Snapshot), x => x.Snapshot is PredictionManagerState);
}
private void OnPrediction(AddPredictionRequest request)
{
/* some code */
_state.Add(request);
SaveSnapshot(_state);
}
private void OnRecover(PredictionManagerState state)
{
foreach(var request in state.RequestMap)
{
OnPrediction(request.Value);
}
}
}
My state save all messages and deletes them after manager actor recieve some message. When I try to debug my test, Recover function called first and after this called OnPrediction. My question is - how it's possible? If data stores in momory, why it have SnapshotOffer? Also I have tried to generate new percistenceId from Guid.NewGuid() but it doesn't work.
public void AddPrediction_PassToChild_CreateNewManager_PassToChild()
{
var sender = CreateTestProbe(Sys);
var persistanceId = "AddPrediction_PassToChild_CreateNewManager_PassToChild";
var props = Props.Create(() => new PredictionManager(Mock.Of<IEventBus>(), persistanceId));
var predictionManager = ActorOf(props);
var message = new PredictionManager.AddPredictionRequest(Props.Create(() => new ChildTestActor(sender.Ref)),
new StartPrediction<IPredictionParameter>("a", 1, "a", new Param() ));
//Act
predictionManager.Tell(message, sender);
sender.ExpectMsg<string>(x => x == "ok", TimeSpan.FromSeconds(15));
Sys.Stop(predictionManager);
predictionManager = Sys.ActorOf(props);
sender.ExpectMsg<string>(x => x == "ok", TimeSpan.FromSeconds(15));
Sys.Stop(predictionManager);
}
I found out that default storage for snapshots is LocalStorage not MemoryStorage. So it stores snapshots in files, and this is why it has SnapshotOffer after app restart. But I still can't get why Guid.NewGuid() as persistanceId is not working.

System.Threading.Tasks.Task`1[<myType>] being returned

This may seem like a duplicate of Why Async function returning System.Threading.Tasks.Task`1[System.String]? but I am doing the things suggested in the Answers there but to no avail.
I'm running a Console app:
static void Main(string[] args)
{
...
var details = CallRestMethodAsync(url, filterObj);
Console.Write(details);
Console.ReadKey();
}
public static async Task<NotificationEvents> CallRestMethodAsync(string url, FilterPager filterPager = null)
{
...
var result = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<NotificationEvents>(result, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
}
When I put a break-point on the last line of CallRestMethodAsync and examine result, I find it DOES contain the object expected. And JsonConvert does not throw an error.
But the output I get is:
System.Threading.Tasks.Task`1[NotificationsHandler.NotificationEvents]
Update (4/30/2019, 11:09 CT):
After accepting #Martin Brown's answer, I realized that I was (stupidly) expecting to see a stringified instance of my type output on the Console. Of course that wouldn't work. What I needed to do inside Main was :
var details = (CallRestMethodAsync(url, filterObj)).Result; // to force the Task to resolve to my type
foreach (var result in details.Results) // Results being a (array) property
Console.Write(details.Results[0].EventDate); // EventDate being a prop that the Console could actually output
Your CallRestMethodAsync method returns a Task<NotificationEvents> rather than the NotificationEvents expected. You can set your Main method to await the result of CallRestMethodAsync like this:
static async Task Main(string[] args)
{
...
var details = await CallRestMethodAsync(url, filterObj);
Console.Write(details);
Console.ReadKey();
}
If you are using an older version of .net you may not be able to create an async main method. In that case you will need to get the Result of the task like this:
static void Main(string[] args)
{
...
var details = CallRestMethodAsync(url, filterObj);
Console.Write(details.Result);
Console.ReadKey();
}

How to write a test that tests that AutoMapper is called with the correct operation options

I have this piece of code and want to test that opts.Items["foo"] is set correctly.
public Result DoStuff(MyInput myObj)
{
var mapped = _mapper.Map<Result>(myObj,
opts =>
{
opts.Items["foo"] = "bar";
});
return mapped;
}
And my test looks like this
public void MapperShouldBeCalledWithCorrectOperationItems()
{
// Arrange
var optObj = Substitute.For<IMappingOperationOptions>();
Action<IMappingOperationOptions> argumentUsed = null;
_mapper.Received().Map<Result>(result, Arg.Do<Action<IMappingOperationOptions>>(arg => argumentUsed = arg));
// Act
_uut.DoStuff(new MyInput());
argumentUsed.Invoke(optObj);
// Assert
optObj.Items["foo"].Should().Be("bar");
}
Now this doesn't work and I'm not even sure I'm on the right path :(
I don't think I can inspect the lambda so I instead have to check that IMappingOperationOptions have Items["foo"] set.
Any suggestions?
I figured it out!
public void MapperShouldBeCalledWithCorrectOperationItems()
{
// Arrange
var optObj = Substitute.For<IMappingOperationOptions>();
Action<IMappingOperationOptions> argumentUsed = null;
_mapper
.Map<Result>(Arg.Any<Result>,
Arg.Do<Action<IMappingOperationOptions>>(arg => argumentUsed = arg));
// Act
_uut.DoStuff(new MyInput());
argumentUsed.Invoke(optObj);
// Assert
optObj.Items["foo"].Should().Be("bar");
}

How to change the dependency at runtime using simple injector

I am new to simple injector. I have data access layer that has dependency on Force Client. I have register the ForceClient dependency. I want to replace the default value of ForceClient once user login into the application.
Please let me know, how i can change the default values at run time.
Ioc.ServiceContainer.Register(() => new ForceClient(
"test",
"test",
"test"));
Here is the complete detail about the requirement. I have DAL in our Xamarin project that retrieve data from sales force using Developerforce.Force apis. I am writing unit test cases using MOQ to test the DAL.
DAL Code.
public CustomerRepository(IForceClient client)
{
_client = client;
}
public async Task<long> GetTotalContacts()
{
string totalContactCountQry = "some query"
var customerCount = await _client.QueryAsync<ContactsTotal>(totalContactCountQry);
var firstOrDefault = customerCount.Records.FirstOrDefault();
return firstOrDefault != null ? firstOrDefault.Total : 0;
}
Unit Test Case Code.
[SetUp]
public void Init()
{
forceClientMock = new Mock<IForceClient>();
forceClientMock.Setup(x => x.ForceClient(It.IsAny<string>(),
It.IsAny<string>(), It.IsAny<string>(), It.IsAny<HttpClient>()))
.Return(new ForceClient(It.IsAny<string>(), It.IsAny<string>(),
It.IsAny<string>(), It.IsAny<HttpClient>()));
forceClientMock.Setup(x => x.QueryAsync<ContactsTotal>(It.IsAny<string>()))
.ReturnsAsync(new QueryResult<ContactsTotal>());
forceClientMock.Setup(x => x.QueryAsync<ContactsTotal>(It.IsAny<string>()))
.ReturnsAsync(new QueryResult<ContactsTotal>() { Records=new List<ContactsTotal>() });
}
[Test]
public void GetTotalContacts()
{
ICustomerRepository customerRepostory = new CustomerRepository(forceClientMock.Object);
Assert.AreEqual(customerRepostory.GetTotalContacts().Result,0);
}
Simple Injector Registry on application initialization
container.Register<IForceClient>((() => new ForceClient(
UserState.Current.ApiBaseUrl,
UserState.Current.AuthToken.AccessToken,
UserState.Current.ApiVersion)), Lifestyle.Transient);
The instance of ForceClient that i am creating during the registry is being created with all default valued of UserState. The actual value gets assigned once user login into the application.
I except ForceClient instance to have the updated value after login to access the sales force to retrieve the data but the program is giving error on below line DAL
var customerCount = await _client.QueryAsync<ContactsTotal>(totalContactCountQry);
The reason is that the forceClient still contain default values. How can i make sure that the FoceClient instance get created after login to use the actual value of UserState
You can accomplish what you want by using Func<T>.
Rather than IForceClient in your classe, you can inject a Func<IForceClient> :
public CustomerRepository(Func<IForceClient> clientFunc)
{
_clientFunc = clientFunc;
}
public async Task<long> GetTotalContacts()
{
string totalContactCountQry = "some query"
// calling _clientFunc() will provide you a new instance of IForceClient
var customerCount = await _clientFunc().QueryAsync<ContactsTotal>(totalContactCountQry);
var firstOrDefault = customerCount.Records.FirstOrDefault();
return firstOrDefault != null ? firstOrDefault.Total : 0;
}
The simple injector registration:
// Your function
Func<IForceClient> fonceClientFunc = () => new ForceClient(
UserState.Current.ApiBaseUrl,
UserState.Current.AuthToken.AccessToken,
UserState.Current.ApiVersion);
// the registration
container.Register<Func<IForceClient>>( () => fonceClientFunc, Lifestyle.Transient);

URL mapping with C# HttpListener

In the code below I am waiting for any call to the 8080 port.
public static void Main()
{
HttpListener listener = new HttpListener();
listener.Prefixes.Add("http://*:8080/");
listener.Start();
while(isRunning)
{
HttpListenerContext ctx = listener.GetContext();
new Thread(new Worker(ctx).ProcessRequest).Start();
}
}
Is it possible to map specific URL patterns to different behavior? I want achieve a REST-style server i.e. a call to localhost:8080/person/1 will launch getPersonHandler(int)
[Mapping("*:8080/person/$id")]
public void getPersonHandler(int id)
{
// ...
}
The Mapping syntax is just my wishful analogy to JAX-RS libraries that I know. I would like to do the same in C# (desktop C#, not asp).
You can get a similar effect without attributes
HttpListener listener = new HttpListener();
listener.Prefixes.Add("http://*:8080/");
listener.Start();
while (true)
{
HttpListenerContext ctx = listener.GetContext();
ThreadPool.QueueUserWorkItem((_) =>
{
string methodName = ctx.Request.Url.Segments[1].Replace("/", "");
string[] strParams = ctx.Request.Url
.Segments
.Skip(2)
.Select(s=>s.Replace("/",""))
.ToArray();
var method = this.GetType().GetMethod(methodName);
object[] #params = method.GetParameters()
.Select((p, i) => Convert.ChangeType(strParams[i], p.ParameterType))
.ToArray();
object ret = method.Invoke(this, #params);
string retstr = JsonConvert.SerializeObject(ret);
});
Usage would be:
http://localhost:8080/getPersonHandler/333
if you really want to use Attributes then
HttpListener listener = new HttpListener();
listener.Prefixes.Add("http://*:8080/");
listener.Start();
while (true)
{
HttpListenerContext ctx = listener.GetContext();
ThreadPool.QueueUserWorkItem((_) =>
{
string methodName = ctx.Request.Url.Segments[1].Replace("/", "");
string[] strParams = ctx.Request.Url
.Segments
.Skip(2)
.Select(s=>s.Replace("/",""))
.ToArray();
var method = this.GetType()
.GetMethods()
.Where(mi => mi.GetCustomAttributes(true).Any(attr => attr is Mapping && ((Mapping)attr).Map == methodName))
.First();
object[] #params = method.GetParameters()
.Select((p, i) => Convert.ChangeType(strParams[i], p.ParameterType))
.ToArray();
object ret = method.Invoke(this, #params);
string retstr = JsonConvert.SerializeObject(ret);
});
}
Then you can use as http://localhost:8080/Person/333 and your definitions would be
class Mapping : Attribute
{
public string Map;
public Mapping(string s)
{
Map = s;
}
}
[Mapping("Person")]
public void getPersonHandler(int id)
{
Console.WriteLine("<<<<" + id);
}
If you are working in .NET 4.0 or higher and looking for a pre-existing REST server solution that you can plug into (which it sounds like you are), you might want to check out Grapevine. You can get it using NuGet, and the project wiki has lots of sample code. Plus, it is open source, so if you just wanted to see how it can be accomplished, you can see all the source code there.
You can filter requests by path info (using regular expressions) and request methods (GET, POST, etc.).
I am the project author, and I had a similar need as the one you described. Using resources I found here and elsewhere, I built Grapevine so that I would have a solution in my back pocket whenever I needed it again (DRY).

Categories