How do you mock IContextChannel in a WCF ServiceAuthorizationManager? - c#

I am trying to write unit tests for a custom ServiceAuthorizationManager. The call to CheckAccessCore takes an OperationContext as a parameter. To instantiate an OperationContext, one must pass an IContextChannel to the constructor. Using MOQ, I've declared an IContextChannel:
private OperationContext _context;
private Mock<IContextChannel> _contextChannelMock;
Then I attempt to create the OperationContext:
_context = new OperationContext(_contextChannelMock.Object);
But this line throws an exception:
Result Message: Initialization method
Urs.EnterpriseServices.Providers.Tests.UrsServiceAuthorizationManager_Tests.SetUp
threw exception. System.InvalidOperationException:
System.InvalidOperationException: Invalid IContextChannel passed to
OperationContext. Must be either a server dispatching channel or a
client proxy channel..
How do I mock, a server dispatching channel?

You can't directly. See if WCFMock will help.

Related

Unhandled ObjectDisposedException C#

I'm programming a wiki with razor pages in the blazor framework.
Everything was going fine, then I got this error message:
fail: Microsoft.EntityFrameworkCore.Database.Connection[20004]
An error occurred using the connection to database 'aspnet-InternesWiki-8BAA8CA5-BC83-4528-BE5F-4E702A44D17F' on server '(localdb)\MSSQLLocalDB'.
fail: Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher[8]
Failed to invoke hub method 'ConnectCircuit'.
System.ObjectDisposedException: Cannot access a disposed object.
at Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost.SetCircuitUser(ClaimsPrincipal user)
at Microsoft.AspNetCore.Components.Server.ComponentHub.ConnectCircuit(String circuitIdSecret)
at lambda_method11(Closure , Object )
at Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher1.ExecuteMethod(ObjectMethodExecutor methodExecutor, Hub hub, Object[] arguments) at Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher1.g__ExecuteInvocation|16_0(DefaultHubDispatcher1 dispatcher, ObjectMethodExecutor methodExecutor, THub hub, Object[] arguments, AsyncServiceScope scope, IHubActivator1 hubActivator, HubConnectionContext connection, HubMethodInvocationMessage hubMethodInvocationMessage, Boolean isStreamCall)
This is where the error occurs:
public async Task<bool> Insertiket(Eintrage eintag)
{
_context.Eintrage.Add(eintag);
_context.SaveChangesAsync();
return true;
}
SaveChangesAsync() It is no longer executed.
Hopefully you can help me, I don't know what to do.
Many thanks in advance
all project files:
https://anonfiles.com/j1c4Fet1y1/InternesWiki_7z
Reading the exception carefully, we see this:
Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher[8] Failed to invoke hub method 'ConnectCircuit'. System.ObjectDisposedException: Cannot access a disposed object.
It's not a database issue, it's a SignalR one. By reading the SignalR Hubs API Guide at the Hub Object Lifetime section we learn this:
Because instances of the Hub class are transient, you can't use them to maintain state from one method call to the next. Each time the server receives a method call from a client, a new instance of your Hub class processes the message
Now, I don't have the full picture of your architecture, my guess is that you have multiple method calls with that db write operation at the end, when the original Hub class generated at the first method call had already been disposed.

SignalR Error: Failed to bind arguments received in invocation '(null)'

In my SignalR client (WinForms) I'm getting the following exception on just one method. The callback code is:
onUpdate = Client.HubService.On<Job>("MyMethod", o => MyMethod(o));
And the exception is:
Microsoft.AspNetCore.SignalR.Client.HubConnection: Error: Failed to bind arguments received in invocation '(null)' of 'MyMethod'.
System.InvalidOperationException: There are no callbacks registered for the method 'MyMethod'
bei Microsoft.AspNetCore.SignalR.Client.HubConnection.ConnectionState.Microsoft.AspNetCore.SignalR.IInvocationBinder.GetParameterTypes(String methodName)
bei Microsoft.AspNetCore.SignalR.Protocol.JsonHubProtocol.ParseMessage(ReadOnlySequence`1 input, IInvocationBinder binder)
The call in the server is:
await hubContext.Clients.All.MyMethod(entity);
Everything looks like it's setup correctly. However I always get the exception.
What am I missing?

How to handle OdataException in DefaultODataPathHandler.Parse at global level?

DefaultODataPathHandler.Parse(string serviceRoot, string odataPath, IServiceProvider requestContainer)
is throwing ODataException when I try to send a wrong data type to a
OData controller function. For example, calling GetOrders(date = 20181001), (with an integer instead of a date (2018-10-01)), throws ODataException with message:
not able to cast Edm.Int32 to Emd.DateTime
How can I handle this exception at global level?

System.TypeAccessException when running unit test

I'm using xunit to write some unit tests that will be testing a subclass of HttpClient that I've written that also uses a DelegateHandler. I'm trying to use a HttpMessageHandler to mock the responses that I'd be getting from calling the Get/Post calls on the HttpClient. I'm passing the message handler to my delete handler's constructor through a HttpClientHandler.CreatePipeline() call. However, when I run the unit test, I get this exception:
System.TypeAccessException : Attempt by security transparent method 'System.Net.Http.HttpClientFactory.CreatePipeline(System.Net.Http.HttpMessageHandler, System.Collections.Generic.IEnumerable`1<System.Net.Http.DelegatingHandler>)' to access security critical type 'System.Net.Http.HttpMessageHandler' failed.
Stack Trace:
at System.Net.Http.HttpClientFactory.CreatePipeline(HttpMessageHandler innerHandler, IEnumerable`1 handlers)
My constructor looks like this:
public MyHttpClient(HttpMessageHandler handler) :
base(HttpClientFactory.CreatePipeline(
new HttpClientHandler(),
new[]
{
new MyDelegateHandler(handler)
}))
{ }
Constructor for my delegate handler:
public MyDelegateHandler(HttpMessageHandler messageHandler) :
base(messageHandler)
{ }
And some code from my unit test:
var handler = new MyMessageHandler("response content");
MyHttpClient client = new MyHttpClient(handler);
var task = client.GetAsync("https://example.com");
(note that the exception occurs before I get to call GetAsync())
I've tried adding security attributes to all my calls, including the method that runs the unit test (from this question: Attempt by security transparent method X to access security critical method Y failed)
I've also tested by removing the delegate handler completely and passing the message handler directly into the MyHttpClient constructor and that works fine.
I've also tried adding any number/combination of the following attributes to the AssemblyInfo.cs files:
[assembly: SecurityRules(SecurityRuleSet.Level1)]
[assembly: AllowPartiallyTrustedCallers]
[assembly: SecurityTransparent()]
Is there anything else I can do to get around the access exception? I'd like to be able to test the delegate handler.
UPDATE: It appears I am getting this exception whether I am passing in a message handler or not. Simply calling the CreatePipeline() method throws this exception.

Return a new object for each Returns() in NSubstitute

I have created a substitute which mocks a web service interface for my unit testing which includes the following method definition:
public Message Invoke(Message input)
This method is called using:
var reply = webService.Invoke(messageObject)
When I make multiple calls to the same method, it is throwing the following exception:
System.InvalidOperationException : This message cannot support the operation because it has been read.
Here is my Nsubstitute mock code:
outputMessageObj = GetResponseMessage()
wsMock.Invoke(Arg.Any<Message>()).Returns(outputMessageObj)
How do I ensure that a new outputMessage object is returned each time the call is made?
Got it, just use a lambda to invoke a method which returns a new Message object each time:
wsMock.Invoke(Arg.Any<Message>()).Returns(x => GetResponseMessage())

Categories