How to Redirect in Mvc Action from OrderPlaceEvent

2020-07-24 05:07发布

问题:

I am using nopCommerce3.40

I am using OrderPlacedEvent of nopCommerce. I want to redirect to my controller action from this void method.

public class OrderPlaceEvents : IConsumer<OrderPlacedEvent>
    {
       public void HandleEvent(OrderPlacedEvent eventMessage)
       {
          //some code for redirect to controller action

       }
   }

how to redirect in mvc action from HandleEvent method

回答1:

It's not possible. Furthermore, you should not do it because some further actions related to order placement are invoked.



回答2:

As Maz says, you should not interrupt the processing to perform the redirect right at the handler, but there are some workarounds that will let you to accomplish the task.

Here follows a generic method to perform a redirection after the action has completed. You will need to apply a custom filter that will perform the redirection. You can trigger redirection from anywhere in your code including, of course, while processing any event.

  • First you will need a service to centralice control. Something like this. Feel free to improve it adding routes and other refinements.

    public interface IRedirectionService
    {
            string RedirectTo { get; set; }
    }
    
    public class RedirectionService : IRedirectionService
    {
            public string RedirectTo { get; set; }
    }
    
  • Then register it per request at the dependency registrar.

    builder.RegisterType<RedirectionService>()
       .As<IRedirectionService>()
       .InstancePerHttpRequest();
    
  • Next thing you will need is an ActionFilter.

    public class RedirectAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            base.OnActionExecuted(filterContext);
    
            var service= EngineContext.Current.Resolve<IRedirectionService>();
            if (!string.IsNullOrWhiteSpace(service.RedirectTo))
            {
                filterContext.Result = new RedirectResult(service.RedirectTo);
            }
        }
    }
    
  • And now the last decision. How to apply this filter? Well... You can...

    1. Add it directly to the BasePublicController (or BaseNopController)
    2. Add it directly, but only to some controllers or actions of your choice
    3. Implement the IFilterProvider interface if you want to inject the action filter without altering any base code (for instance if you are implementing a plugin). Read this marvelous article from Woon Cherk on how to do it.

Doesn't matter which option you choose, run some tests to check you didn't break anything. I would be a pain affect the IPN handler, for instance...

  • And finally, trigger the redirect just by injecting an instance of IRedirectionService and running

    _redirectService.RedirectTo = "http://www.google.com";
    

This solution is pretty straightforward and works like a charm. But do not forget about performing some integration tests.

Note: This answer was provided for nopCommerce 3.20, but it should work as well for later versions with minor changes