2

I want to implement the MVVM Light INavigationService interface in a DotVVM project; but I don't know how to do that. The most important method that I need to implement is NavigateTo(string pageKey) method.

I am using a SpaContentPlaceHolder in my MasterPage and I want to change the content (RouteName) of the SpaContentPlaceHolder by calling the NavigateTo method.

1 Answers1

1

If you are in the viewmodel, you can just call Context.RedirectToRoute("YourRoute", new { Param1 = something }).

If you want to redirect from a different place, the easiest way is to create INavigationService interface and implement it to call the method on IDotvvmRequestContext (which is already registered in the ASP.NET Core dependency injection container):

public interface INavigationService 
{
    void NavigateTo(string routeName, object routeParameters);
}

public class DotvvmNavigationService 
{
    private IDotvvmRequestContext context;

    public DotvvmNavigationService(IDotvvmRequestContext context) {
        this.context = context;
    }

    public void NavigateTo(string routeName, object routeParameters) {
        this.context.RedirectToRoute(routeName, routeParameters);
    }
}

Then, you can just register the implementation as a scoped dependency in Startup.cs and you should be able to get it anywhere you need.

services.AddScoped<DotvvmNavigationService>();
Tomáš Herceg
  • 1,595
  • 1
  • 13
  • 18
  • I followed your instructions; but on `this.context.RedirectToRoute(routeName)` method, it throws an exception that says "Cannot access a disposed object. Object name: 'IServiceProvider'." – Amir Abdollahi Nov 18 '18 at 18:03
  • It looks like the method is called from a different thread or from a task. The redirect can be done only on threads that process HTTP requests. – Tomáš Herceg Nov 19 '18 at 12:28
  • It is working now. My method was an async method so I changed it to a normal synchronous method and it is working now. Thanks a lot. – Amir Abdollahi Nov 19 '18 at 13:38
  • And another point: It threw the DotvvmInterruptRequestExecutionException on `RedirectToRoute` method and I just unchecked the "Break when this exception is thrown" checkbox as you have written [here](https://www.dotvvm.com/blog/1/Why-I-am-getting-the-DotvvmInterruptRequestExecutionException-). Thanks again. – Amir Abdollahi Nov 19 '18 at 13:47
  • Is there any way to force the Redirect method to be called on the thread that processed HTTP requests? For example `runOnUiThread` and `Control.Invoke` methods do a similar thing in Android and WinForms. Is there such a method in DotVVM? – Amir Abdollahi Nov 27 '18 at 14:33
  • The problem is that web applications are by definition multi-threaded and there may be multile HTTP requests at the time, so you cannot just say run in HTTP context thread because the app wouldn't know on which one. Do you have some background thread in your application? – Tomáš Herceg Nov 27 '18 at 18:33
  • I have an async method that controls the login process. If the authentication was successfull, it calls the `NavigateTo` method of `INavigationService` and it redirects to the Home page. The problem is with async method. After I changed that method to non-async method, it worked well. But I want my method to be async, for some reasons. – Amir Abdollahi Nov 27 '18 at 19:37