Web API and Navigation Framework Crumbs

Jan 3, 2014 at 8:53 PM
Edited Jan 3, 2014 at 8:54 PM
Hi Graham,

Wishing you Happy New Year. As mentioned in my previous post, we are using Navigation Framework and Web API in ASP .NET Web Forms application. I am trying to access Crumbs in Web API but StateController.Crumbs property always returns 0 items. This property returns different value when accessed in Page_Load event. I have few questions:
  1. How can I access Crumbs in Web API controller?
  2. Is it possible to access Crumbs on client side with JavaScript? I want to populate breadcrumb control from JavaScript/jQuery.
My Web API Controller is in same project as ASP .NET Web Forms application.

Thanks,
Coordinator
Jan 3, 2014 at 11:37 PM
Hi,

Happy New Year to you too, it's great to hear from you again.

I don't think it's quite what you're after but you can access Crumbs in Web API. Taking the same example StateInfo configuration from your previous post, inside a Web API method you could perform a couple of Navigations in a row:
StateController.Navigate("Person", NavigationMode.Mock);
StateController.Navigate("Select", NavigationMode.Mock);
After the second Navigation the StateController Crumbs will contain 1 item.

But I guess you mean that if you make a Web API call from the Details.aspx page then the Crumbs would be empty even though they would contain 1 item if accessed in the Page_Load event? That's true, the State information isn't passed when an Web Api call is made so the Crumbs will be 0. Similarly, the State information isn't passed to the client so the Crumbs aren't available to JavaScript on the client side.

Having said that, I'm always looking to add new features and it sounds like you're trying some interesting stuff. Could you tell me more about what you're up to, please?

Cheers,
Graham
Jan 7, 2014 at 1:48 PM
Hi Graham,

I agree with your analysis for State Information. Since State information is not passed Web API or client is not able to access Crumbs.

I inherited ASP .NET Web Forms application last year. As I was familiar with benefits for navigation abstraction, I introduced Navigation Framework immediately. Moving forward as we add more features to the application, we are relying less on ASP .NET controls and more on JavaScript and Web APIs. The main objective is to keep code behind empty and use CSS and JavaScript framework for UI. With this background in mind, here are few scenarios:
  1. We are introducing breadcrumb control for each page. As we are populating all controls by making calls to Web APIs, I need a way to access Crumbs in Web API Controller.
  2. The other scenario is to generate NavigateUrl on client. This will allow me to generate url from JavaScript and use it (for e.g. to navigate to a different page on button click.)
I am aware that solution to some of the above use cases may not be possible as Navigation framework is a server side framework. But I just wanted to list use cases for contextual purposes.

Thanks,
Coordinator
Jan 7, 2014 at 8:00 PM
Thanks for for providing the context. I'm guessing that if Crumbs were accessible in Web API then you wouldn't need Crumbs client side because you could generate the links server side and pass them back to the client.

I think making Crumbs available in Web Api would be a really great Navigation enhancement. I've got a rough idea of how this could be implemented and was wondering if you'd like to have a go at it? Here's an idea of what I'm thinking about.
  1. In Web Forms, send a Url to the client that contains the current State and NavigationData.
  2. On the client, in JavaScript pass the Url generated at step 1 in the request headers of the ajax request.
  3. In Web Api, retrieve the request header passed in step 2 and parse the Url to set up the Crumbs.
If you're interested I'll go into more details about how each step can be implemented (it's not as scary as it might sound).

Cheers,
Graham
Jan 13, 2014 at 1:42 PM
Hi Graham,

I am sorry for responding late. I was busy in few critical production issues. I am interested in exploring approach suggested by you. If you can provide some detail about step #1 then I can start work on it.

Thanks,
Coordinator
Jan 13, 2014 at 8:37 PM
It's great you're interested, I was worried I'd scared you off. Create yourself a fork of the project and let's dig a little deeper into the first point.

Creating a Url that holds the current State and NavigationData can be done by calling:
var refreshUrl = StateController.GetRefreshLink(new NavigationData(true));
GetRefreshLink ensures it contains the current State and passing new NavigatonData(true) ensures it contains all the current NavigationData.

This refreshUrl can be sent to the client by calling RegisterClientScriptBlock on the ScriptManager (there's an example of something similar in the AddHistoryPoint method of the StateController). For now this code is best placed in the StateAdapter class, although we might create a custom Control for this at a later date. So, at the bottom of the DeterminePostBackMode method of the StateAdapter add a listener to the Page PreRenderComplete event and register the script block from there.

That should be all that's needed for the first point. Let me know how you get on.

Cheers,
Graham
Jan 14, 2014 at 8:14 PM
Ok. I will create a fork and start work on implementation. Please give a day or two to get back to you.
Coordinator
Apr 10, 2014 at 6:47 PM
Edited Apr 10, 2014 at 6:48 PM
Hi, How are you getting on?

Since we last chatted I've had a rethink and have bigger and better plans for providing Web Api Navigation support. I think I can abstract the Navigation from Web Forms so that I can fully support Navigation in Web Api (or MVC). What I mean is you'll be able to define Web Api States. So, for your example use case you could define a Web Api state called Values like this
<dialog key="Person" initial="Listing" path="~/Listing.aspx">
    <state key="Listing" page="~/Listing.aspx">
        <transition key="Select" to="Details"/>
    </state>
    <state key="Details" page="~/Details.aspx">
        <transition key="Info" to="Values"/>
    </state>
    <state key="Values" apiController="Values" action="Index">
    </state>
</dialog>
Then if you make an ajax call on the Details.aspx Page to StateController.GetNavigationLink("Info"), in your Api Controller method you'll have full access to all the State and Crumbs, so you could return the CrumbTrail back to the client for example.

Sound exciting? I've just started work on this in my Abstract Navigation fork
Apr 11, 2014 at 7:02 PM
Hi Graham,

I hope you are doing well. I just got back to work after 4 weeks of vacation. I haven't started any implementation work from our last conversation due to vacation and changes in projects at work.

Your idea looks very promising. Will it work in a situation in which web forms and web api live in same project?

I am available to help out in implementation (development) or testing alpha/beta version. Please let me know in case you need another set of hands.

Please keep sending use cases for validation.

Regards,
Coordinator
Apr 12, 2014 at 8:37 PM
Welcome back.

The plan is it'll work with Web Forms and Web Api and even MVC in the same project. You'll be able to have any mixture of States you want, e.g., an MVC State that navigates to a Web Forms State which makes an Ajax navigation to a Web Api State.

I don't want to bring Web Api or MVC dependencies into the Navigation project. Instead, I'm going to make the Navigation framework extensible so that I can write separate projects to provide Web Api and MVC Navigation support. That way, any other .NET Web framework can hook into the Navigation framework.

Thanks for your offer of help. Once I've firmed up the changes to the Navigation framework, I can see opportunities arising to work on the Web Api/MVC Navigation projects.
Coordinator
Apr 22, 2014 at 6:50 PM
I've finished the work of abstracting the Navigation so it can work in MVC and Web Api and merged this work into the main branch. I've only gone so far with this abstraction; by that I mean it's still dependent on the System.Web namespace and so must be hosted in IIS. That's no problem for Web Forms and MVC because they also have this dependency but WebApi doesn't, it can be self hosted for example. However, I want to wait and see where Microsoft are going with OWIN before I make any move in this direction. This works for your situation because your Web Api is in your Web Forms project.

The next job is to create the projects that add Navigation support to Mvc and Web Api. I'm going to start with Mvc and have created a NavigationMvc fork.
Would you be interested in working on the Web Api support?
Coordinator
May 9, 2014 at 8:12 PM
Edited May 10, 2014 at 10:19 AM
I've got some good news. I've finished the projects that add Mvc and WebApi support!

You can see it working if you download the code and run the NavigationSample project. The url /List runs the 'old' Web Forms sample, the url /MvcList runs the Mvc sample and the url /Person.html runs the Web Api sample. You can see from the StateInfo.config that all the States are configured in the one Web Project.

Would you be interested in testing out the NavigationWebApi project to see if it fits the bill for you?
May 13, 2014 at 4:35 AM
It is an excellent news. It seems that I missed few messages in the thread.

I will download NavigationWebApi project and test it this week.
Coordinator
May 13, 2014 at 6:56 PM
Great, thanks. Any problems getting it up and running let me know.
Coordinator
Jun 18, 2014 at 8:57 PM
Sorry for not being in touch for a while, just wondering if you've given Navigation for WebApi a go yet?
I'm guessing you have but ran into problems building it?
Well, I've made things a lot simpler now so it would be great if you could give it another try, please?

Instead of having separate projects, I've incorporated both Mvc and WebApi into the core Navigation project (and deleted both NavigationMvc and NavigationWebApi). So you just have to replace your current Navigation.dll with the new one (once it's released, you'll just have to update your Navigation NuGet package).

To get your hands on the Navigation.dll follow these steps:
  1. Download the source
  2. Open a Visual Studio Command Prompt
  3. cd to the folder the source is in
  4. Run the command 'msbuild build.xml /t:Navigate'
  5. When the command complete (takes about a minute) a Build folder will be created alongside the source folder
  6. Find the Navigation.dll for the framework of .NET you're using inside the bin folder of the Build folder
It should be fully backward compatible so to start using it you'll just need to define some WebApi states in your StateInfo.config file. These are different to WebForms states because they don't have a page attribute, but instead they have controller and action attributes. You can see an example in the StateInfo.config file of the Navigation.Sample project.

I hope this helps. If you're having any problems please let me know because it'll really help me iron out issues.

Cheers,
Graham
Coordinator
Jul 13, 2014 at 4:34 PM
I've just released Navigation for ASP.NET 1.9 with suppport for WebApi.
Update your Navigation NuGet package and you're good to go. Add a WebApi State to your StateInfo.config (by setting the apiController and action attributes) and you'll be able to access the Crumbs in your WebApi method.