I have a simple middleware:
public class MiddlewareInterceptor
{
RequestDelegate _next;
public MiddlewareInterceptor(RequestDelegate next)
{
_next = next;
}
public Task Invoke(HttpContext ctx)
{
ctx.Response.WriteAsync("<h2>From SomeMiddleWare</h2>");
return _next(ctx);
}
}
And in my Startup.cs Configure method, I hook it like so:
app.UseMiddleware<MiddlewareInterceptor>();
The above builds and the app seems to run fine, but my breakpoint in the interceptor Invoke method never hits. And likewise, there is never any output. I tried that with Debug.WriteLine also.
Now, I also tried this method:
public class MiddlewareInterceptor : OwinMiddleware
{
public MiddlewareInterceptor(OwinMiddleware next) : base(next){}
public override async Task Invoke(IOwinContext context)
{
Debug.WriteLine(context.Request.Uri.ToString());
await Next.Invoke(context);
}
}
And in my Startup.cs Configure method, I hook it like so:
app.Use(next => new MiddlewareInterceptor(next).Invoke);
Unfortunately, the base OwinMiddleware constructor is looking for the next OwinMiddleware as a parameter, unlike ye olde RequestDelegate. So my app.Use instantiation of my MiddlewareInterceptor fails because next is of type RequestDelegate.
Lastly, I have tried an inline function directly in the Configure method which also never hits the breakpoint:
app.Use(async (ctx, next) =>
{
System.Diagnostics.Debug.WriteLine("Hello");
await next();
});
So as it stands, it seems like I cant make a basic middleware interceptor using OWIN. What am I missing?
What is the order of the aforementioned middleware in the pipeline? Make sure this executes before anything that will terminate the request part of the pipeline; eg. UseMvc();
Related
Is there any way to run PreRequestFilters that are async? I can see that there's been a number of async request filters added, but no async version of PreRequestFilters.
It would be nice to have an async version of PreRequestFilters so that we can run async tasks before any Request Filter Attributes. The only way I can see of doing that at the moment is to use GlobalRequestFiltersAsync and make sure all Request Filter Attributes have a Priority >= 0.
There isn't an async version of PreRequestFilters but you could use a custom RequestFilter Async Attribute with a -Priortity, e.g:
public class MyAsyncAttribute : RequestFilterAsyncAttribute
{
public MyAsyncAttribute()
{
// Priority -101, before any built-in request filter attributes
Priority = (int)RequestFilterPriority.Authenticate - 1;
}
public override Task ExecuteAsync(IRequest req, IResponse res, object requestDto)
{
//...
}
}
does anybody know if there is an option to implement multiple routes in nestjs with the same path.
Lets say:
/checkout in BasketControllerNew
/checkout in BasketController
At the first controller, there is a guard which decides if the user can access the /checkout at BasketControllerNew.
Returning false will throw an ForbiddenException, fine.
If I throw a custom exception, the second route will also not be executed.
Filters seems also not able to jump to the next route.
I want to implement feature toggle functionality.
In this case for example a new checkout process with a completely new controller file.
The new checkout process should be tested by some users for example or can be enabled and disabled by feature toggles.
My preferred behaviour would be to throw a custom exception like DisabledRouteException or something like that which means "please try the next matching route".
Another possible usecase could be:
A cms with a wildcard route which tries to find pages because they do not have a specific prefix at their path
There will be a module which uses routes prefixed with moduleA/.
As long as the module is not enabled for a specific customer, the moduleA/* should be handled by the wildcard route because there can be pages at this path.
Has anybody an idea how to implement such things?
Thanks a lot for your support and keep healthy.
Daxi
I have found a solution, which works for me:
Summary:
Multiple routes with same path
Guard which throws a Exception
Filter which catches the exception and executes the next route.
Example code for controller:
#Controller()
export class TestController {
#Get()
#UseGuards(TestGuard)
getHello(): string {
return "Hello";
}
#Get()
#UseGuards(TestGuard)
getHello2(): string {
return "Hello2";
}
#Get()
getHello3(): string {
return "Hello3";
}
}
Example code for guard:
#Injectable()
export class TestGuard implements CanActivate {
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
// add logic here to switch between execution or skip
throw new NotFoundException('Module not active');
}
}
Example code for filter:
#Catch(NotFoundException)
export class TestFilter implements ExceptionFilter {
catch(exception: NotFoundException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const next = ctx.getNext();
next();
}
}
Enable the filter globaly in main.ts:
async function bootstrap() {
const app = await NestFactory.create(TestModule);
app.useGlobalFilters(new TestFilter());
await app.listen(3000);
}
To get a proper handling, the code can be improved by generating a custom exception and filter only that, currently all 404s will trigger the next route.
At this example the guard will always throw the exception which ends up at this behaviour:
guard for getHello will throw the NotFoundException
filter will trigger the next route
guard for getHello2 will throw also the NotFoundException
filter will again trigger the next route
getHello3 will be executed (no guard active)
My code is only a small POC which can be improved as described and should be improved.
The test was only a very small quick and dirty solution, but if you will need a similar solution, now you can start at the same point.
Kind regards,
Daxi
Am I missing something, or is it just not possible to extend arbitrary Node modules like you would, say, a Java class?
Concrete example:
I need passport-remember-me to expose the req object to the _issue method. What I tried to do was to extend that function (RememberMe.Strategy), modify the _issue function, then delegate to the original parent class' function for the actual business logic:
// 1: Extend RememberMeStrategy
function IWillRememberYou (options, verify, issue) {
RememberMeStrategy.call(this, options, verify, issue);
}
util.inherits(RememberMeStrategy, IWillRememberYou);
// 2: Override some method
IWillRememberYou.prototype.authenticate = (req, options) => {
// Save original function
const issue = this._issue;
// Wrap the supplied callback so it can now be sent extra args
this._issue = (user, issued) => {
// Send in additional parameter
issue(req, user, issued);
};
};
What this gives me is an empty this context inside IWillRememberYou.authenticate as well as inside RememberMeStragety.authenticate. Why is this happening??
What the parent class looks like (the third-party Node module)
function Strategy(options, verify, issue) {
// ...
passport.Strategy.call(this);
// ...
this._issue = issue;
}
util.inherits(Strategy, passport.Strategy);
Strategy.prototype.authenticate = function(req, options) {
// ...
// My end goal is to send (req, user, issued) to that callback
this._issue(user, issued);
};
Don't use arrow functions when doing OO. That's because arrow functions are deliberately designed to break how this works. Instead do:
IWillRememberYou.prototype.authenticate = function (req, options) {
/* .. */
};
Remember, with arrow functions you basically bind this to the context where the function is defined. If you defined it outside of any function then this will be the global object or undefined if in strict mode.
What this boils down to is that arrow functions breaks inheritance.
I have an mvc 5 controller that makes use of some async data access code. I've written a simple test using nUnit. The test doesn't complete, it just spins until i cancel it. afaik i've set up the test correctly; it's awaiting the controller action is marked as async and returns a task. Am i missing something? Interestingly, the test works when i mock out the dependencies using moq, but if i go for an integration test with the actual dependencies in place, it just spins forever.
the a simplified test:
[Test]
public async Task Get_WhenProductHasData_ReturnsView()
{
// Arrange
...
// Act
PartialViewResult actualResult = await _controller.Widget(_productId1) as PartialViewResult;
// Assert
Assert.That(actualResult, Is.Not.Null);
...
}
And here's the simplified controller
public async Task<ActionResult> Widget(string productId)
{
ProductStats stats = await _statsService.GetProductStatsAsync(productId);
return PartialView(stats);
}
Try this instead:
[Test]
public async Task Get_WhenProductHasData_ReturnsView()
{
// Arrange
...
// Act
var result = await _controller.Widget(_productId1);
// Assert
Assert.That(result as PartialViewResult, Is.Not.Null);
}
Note that the "Act" line is simply awaiting and the result is then cast as a PartialViewResult on the Assert.That line, if it was null or not a PartialViewResult type it would return null. Either way you get what you're looking for.
Specifically when doing MonoDroid uses of threads all the documentation I can find recommends calling RunOnUiThread() to call the callback. There is a similar function that can be used on MonoTouch however both of them require a GUI (Activity or whatever its counter part is on IOS). What I would like is to be able to start a thread, pass in a callback and call that callback on the thread that started the thread. For example
ThreadPool.QueueUserWorkItem(state =>
{
//Do Stuff
execute_callback_magically_on_main_thread(() => callback(response));
});
Any ideas? To be clear I would prefer this to not need a handle to the Activity etc.
What if you do something like this? (assuming they have the same signature) I haven't messed with RunOnUiThread, so I don't know it's signature.
public delegate void InvokeOnUIMethod(Action action);
public void CallingMethod()
{
//iOS
MyMethod(InvokeOnMainThread, () => { /* Your callback functionality */ });
//Android
MyMethod(RunOnUiThread, () => { /* Your callback functionality */ });
}
public void MyMethod(InvokeOnUIMethod execute_callback_magically_on_main_thread, Action callback)
{
System.Threading.ThreadPool.QueueUserWorkItem(state =>
{
//Do Stuff
execute_callback_magically_on_main_thread(() => callback(response));
});
}
I hope this helps.
Using the Alpha builds (Hopefully soon to be available as stable) you can use the new Async await idiom.
here is an overview on MSDN:
http://msdn.microsoft.com/en-gb/library/vstudio/hh191443.aspx
and here is a great video series on Channel9:
http://channel9.msdn.com/Series/Three-Essential-Tips-for-Async/Tip-1-Async-void-is-for-top-level-event-handlers-only
I found a solution that works and does not appear to be dependent on either platform.
Task<string> t = new Task<string>(() =>
{
//Do Stuff
return "my results";
});
t.ContinueWith(task =>{
if(callback != null)
callback(task.Result);
}, TaskScheduler.FromCurrentSynchronizationContext());
t.Start();
The important part is the TaskScheduler.FromCurrentSynchronizationContext() which tells the "ContinueWith" to execute on the original thread.