Apr 30, 2012 at 10:44 PM
Edited Apr 30, 2012 at 10:47 PM
|
I'm working on an application which, as suggested by MVC4, is utilizing knockout.js and the WebAPI. One of the things I love about T4MVC is the ability to work with ActionResult objects rather than arbitrarily passing
string values. So naturally, rather than write:
var url = "/api/PackSchedules?$top=" + pageSize + "&$skip=" + ((pageIndex - 1) * pageSize);
$.getJSON(url, function (data) {
viewModel.packSchedules(data);
});
I wanted to write something along the lines of:
var url = "@Url.Action(MVC.PackSchedules.Get())?$top=" + pageSize + "&$skip=" + ((pageIndex - 1) * pageSize);
$.getJSON(url, function (data) {
viewModel.packSchedules(data);
});
However, T4MVC doesn't appear to handle the ApiController at this time. Does anyone think I'm crazy or does this seem like a good use of the tool?
Thanks,
Vinney
EDIT: Removed extraneous code regions
|
|
|
Coordinator
Apr 30, 2012 at 11:22 PM
|
I think something could probably be done, though it might be a fair bit different from what happens with regular MVC controllers. In regular MVC, we rely on the action returning something that extends ActionResult, allowing us to use something that looks
like regular calls to the action.
But in WebAPI, the methods don't return any common base class, so the same technique wouldn't work. We could still generate methods that have the same signature but are not actually the same method (so things like Go To Definition wouldn't work).
The other thing is that T4MVC relies on MVC framework methods to generate the path. e.g. when you call T4MVC's flavor of ActionLink, it in turns calls MVC's flavor, passing the controller/action names. But from what I can see in WebAPI, the path is typically
hard coded. Or maybe there is a helper as well that most people just don't use?
|
|
|
|
|
Yes, I see the intricacies involved. I think it's understandable that T4MVC woudn't provide the same functionality of a standard MVC action method but do you see any value in having the relative link available, similar to the way scripts
and content are discovered with the Links namespace?
Thanks,
Vinney
|
|
|
Coordinator
May 3, 2012 at 6:20 PM
|
Can you clarify what you mean by the 'relative link' in this context? Thanks!
|
|
|
May 4, 2012 at 4:34 AM
Edited May 4, 2012 at 4:35 AM
|
Sure, to recap, the functionality I was looking for was the ability reference the to replace
var url = '\api\products';
with
var url = @Url.Action(Api.Products());
Where "Api" might be a T4MVC namespace providing access to the WebAPI routes. Parameters could also be included in the same fashion.
var url = @Url.Action(Api.Products(1));
The idea is that the url variable could be used to retrieve data as in
$.getJSON(url, function(data) {...});
Does this seem sane? To be honest, I'm not exactly sure how kosher it is to have a WebAPI and MVC web client living in the same project but this is the way my first WebAPI project looks. I've also recently created a small
javascript library to store the api urls and this seems to be working fine (for a magic string implementation). Thanks again for the consideration.
|
|
|
Coordinator
May 4, 2012 at 5:16 PM
Edited May 4, 2012 at 5:17 PM
|
I'm pretty new to WebAPI as well. I think it does make sense. But it seems WebAPI currently makes it pretty difficulty to generate links through routes. I just filed a bug on that http://aspnetwebstack.codeplex.com/workitem/121.
Stepping back, there are really two levels of hard coding things:
- Directly hard coding the path is the worst, as it makes assumptions on the route definitions.
- Going through a method like Url.RouteLink. Here, you don't hard code any route knowledge, but you just hard code controller/action names. The problem is that in WebAPI even doing that seems difficult right now.
Anyway, I think something can conceivably be done to improve this in T4MVC to improve things.
The hardest part is probably finding the time to work on it! Contributions are welcome :)
|
|
|
|
|
I think T4MVC is a quintessential MVC package add-on. It's one of the first things I do when I click File > New Project (because I haven't ventured into creating custom VS project templates where I would surely include T4MVC as my default project
template!). All that is to say, I would be glad to contribute to the project. My only hesitation is that my knowledge/experience with WebAPI and REST in general is lacking enough that I'm concerned I would rollout a somewhat naive solution. That said, let
me see if I can architect a plan and I'll get back to you. Sound good?
|
|
|
Coordinator
May 7, 2012 at 1:41 AM
|
I think the key is to take scenarios one by one and see how some things can be changed into a T4MVC flavor. But in the case of WebAPI, you have to start with something that actually uses some API to produce path. So per that bug I filed, the non-T4MVC way
is:
Url.RouteUrl(new { Controller = "PackSchedules", HttpRoute = true })
And presumably that can become
Url.Action(MVC.PackSchedule.Get())
And that would internally call the non-T4MVC one. So similar to what T4MVC does today, but with different underlying logic.
|
|
|
|
|
Hi @davidebbo! I was just noticing that the MVC team added a fix for your bug report. Yay us! Does this fix make the WebAPI templating any more feasible? I'm afraid I do have to plead ignorance in this regard. Thanks!
|
|
|
|
|
in fork RRoesler/WebAPI I have just committed an attempt to handle WebAPI controllers in T4MVC.
What I did was
a) Used IsController to determine what type of controller was found (MVC or API)
b) In ProcessControllerActionMethods, for WebAPI Controller, look for HTTP Verbs to identify actions
c) For WebAPI actions, pretend that they return ActionResult regardless of what they actually return
d) For WebAPI, generate a new T4MVC class instead of extendings (with partial) the original controller
e) For WebAPI, the generated controller mocks are kinda like NoRealController generation
Kinda ugly which is why I'm not creating a pull request yet.
|
|
|
Coordinator
Nov 1, 2012 at 6:30 AM
|
@rroesler: the general direction sounds about right, as clearly the standard T4MVC approach won't work. If you get to a point that you feel good enough about, we can think about how to get it in!
|
|
|
Editor
Nov 2, 2012 at 7:09 PM
|
I just started tinkering with MVC4 and I wonder if we should change the approach that T4MVC takes?
Currently T4MVC extendeds the controller and overrides the action methods. One of the properties it adds is Actions, which is just a pointer to the static instance of the overloaded class.
What if we instead just create a separate class, like what is done for controller-less views, and define all actions there, and have the Actions properties and the MVC properties point to it. We also could make those actions return IT4MVCActionLink
or something similar. A majority of the usage for T4MVC would stay the same and we would no longer have to overload the ActionResult classes. We could still use the same extension methods, and it would work with the WebApi since we are not overloading anymore.
Is there really any major advantage to overloading the Controller? I Might tinker with this idea over the next few weeks as I experiment with MVC4.
|
|
|
Coordinator
Nov 2, 2012 at 8:46 PM
|
I think the main thing we would lose is the ability to hit "Go to definition" on an action method in a T4MVC call, and have it actually go to the real action and not the generated code. That was the main reason behind the current inheritance design.
A similar one was refactoring. e.g. if you rename a controller action, the refactoring engine will successfully fix up the T4MVC calls that go to that action. At least it works for calls that come from .cs files, and not from views (since refactoring doesn't
work in views - maybe with Reshaper it does?).
Does that make sense?
Now the big question is: are we paying too big of a price for these benefits, in term of code complexity and ability to deal with these new situations?
|
|
|
|
|
I did something similar last year on T4MVC when it was still hosted with MvcContrib (see rroesler/RRoeslerPatches1 under MvcContrib)
In my case, the driver was the fact that the T4MVC added parameter less methods broke some refactoring for me.
(I also created View references as constants and a few other things that I needed)
In this project, for WebAPI I did exactly what you suggested in rroesler/WebAPI. The solution still have some problems. For example, there is a problem between MVC routes and WebAPI routes which I still need to fix.
|
|
|
Editor
Nov 15, 2012 at 7:07 PM
Edited Nov 20, 2012 at 7:05 PM
|
I have an initial concept of WebAPI support, This is actually not MVC4 support since WebAPI can be added to an MVC3 project. If you guys want to check out the fork I created for it and give suggestions on areas I may have gone overboard
on let me know.
http://t4mvc.codeplex.com/SourceControl/network/forks/mswainatwork/t4mvc?branch=webapi
[Edit]
I re-did my WebApi implementation. It now sits beside the current T4MVC instead of just heavily modifying it. This does cause code duplication to allow the two to co-exists, but hopefully if this pans out we can depreciate the old way.
|
|
|
|
|
Hello,
I was looking for T4MVC for Web APIand was pointed to this thread.
Was any evolution on this? Is it dependent on next version of Web API?
thank You,
Miguel
|
|
|
|
|
I have not had a chance to do any more work on T4MVC for WebAPI since that earlier posting. Currently our development efforts are focusing elsewhere where T4MVC can not contribute, so, for now, this is not on the top of my mind. Sorry.
Randy
|
|