Trying to pass parameters between pages and blocks in Episerver seems to give a lot of people headaches and can be the root of a lot of frustration. One of the main issues I see a lot of people struggle with is understanding the difference between standard MVC Routing and Episerver routing. I can hold my hands up as someone who's been working with MVC for years and, on occasion, I can still waste an afternoon scratching my head as to why my action hasn't been hit or my data is missing. Most of the situations when you want to deal with custom routing can be boiled down to these scenarios:
- Custom Url's
- Passing parameters via the Url
- Passing custom data between controllers (pages and blocks)
Today, I will be covering the issues of passing custom data between pages and blocks.
Model Binding Not Working
One of the nice features of MVC is the pre-populating of parameters 'magically' via a thing called the model binder. The model binder takes the values coming from an HTML page and then maps it to a corresponding model. This model might be a single parameter like an integer or a string, or if could be a complex object. For example in a web form, you may have a textbox with an id of 'textbox', if you used the below code when you submit the form MVC should auto bind the input value parameter called textbox to contain your textboxes value. In short it matches a form elements id/name with that of the input parameters specified on your actions.
In a lot of projects that I've worked on, trying to get this to work in Episerver seems to be a little bit more frustrating than working on a plain MVC site. In MVC the Url maps to controller and action methods. In Episerver the Url and the traditional MVC route to a controller are different. In an Episerver application, Episerver hi-jacks the HTTP request and based on the URL, figures out what controller should be used.
Episerver then creates a Current Page object which contains all the information about the current page back and then loads the correct controller, so the page can be rendered. to process the request. If you found yourself unable to figure out why your data is missing then read on...
I Can't Find My Route Date
The first tip I suggest when your data is not being passed around correctly is to stick a breakpoint in action method of the controller for the page type you are working with and using the 'Add Watch' in Visual studio to have a look at the route data. From here, you can tell if you are passing the information you think you are into the controller. To find the route data you will need to have a look inside:
If the data you are expecting to see within your Route Data then it is likely that there is an issue in the code that's making the request. If this request has come from a form make sure you're using the correct POST or GET, make sure your forms are working. In an extreme case, you could try manually setting your route data in code. This can be done using:
If you use the snippet above your controller you can add the following code to test that your data is being passed correctly.
If your data is not being passed correctly into your controllers then it is very likely you've done something to mess up your routing. In these scenarios, I'd check your route mapping table (usually in the global.ascx) and start to look if you have anything like a custom segments or routes defined. If you do, try disabling them until the data passes correctly.
Sometimes a bug in your route can cause these types of issues to occur because you may be accidentally invoking an incorrect controller or action. In these situations, the tool to try and help figure out what's going wrong is Route Debugger. To install Route Debugger open the 'Nugent Package Manage' console and type:
In your app settings in your web.config you may also want to check that it installed correctly and is enabled. If it is you should see the following:
Getting routing to work can be very time-consuming. I've seen a number of people fall into the same types of traps so don't get yourself too worked up about it if you find yourself in the same situation. My first tip is to make sure the data you are trying to pass around is actually being passed around. You can do this by looking into the Route collection.
If the data is there, then it will likely to be something your controller, maybe a typo in your variable names. If the data is not there then you can try manually adding data into the route table to make sure everything is working as it should. If you have manually added data into the route values and it is still missing, I would recommend disabling all of your custom routes and segments and try again. Continue disabling until the data passes as expected. Then add everything back, one step at a time, to discover where the offending code was hiding.