How do I get Web API to render a Razor view using the model that it returns? And only XML/JSON when the accept headers (or .extension) is set? Is this even possible?
It seems crazy to require one set of controllers for rendering HTML and another for JSON/XML if they're working on the same models.
Update Darrel Miller has already written a ViewEngineFormatter for Razor which might do the trick, though haven't tried it yet.
I asked a similar question about this in the past on StackOverflow, because I wanted to do the same thing. However, I eventually ended up with an "Api" area and set of controllers, and a standard set of MVC controllers for the website.
In hindsight this actually wasn't a bad thing. I've found I tend to do different things in each set of controllers anyway. My views aren't just CRUD but tend to contain extra contextual data, so returning view models specific to that page is nice.
I think if I had stuck to my goal of combining the two I might have ended up with either over-complicated controllers or a user experience that wasn't as optimal as it could have been. So while this isn't a direct answer to your question, in my experience not being able to do this might not be such a bad thing.
Instead I've ended up with a rich set of builders and commands that most of my controllers delegate to. That way I can reuse most of the controller logic while being able to do specific things for API versus the web:
http://www.paulstovell.com/clean-aspnet-mvc-controllers
Yes, it is how it is designed for: Web API for data and MVC for rendered views. I know that some people will try adding view engine support to web API but it is not designed for it.
My personal view on this is that this parallel world between MVC and Web API (which is the source of most criticisms while community has generally praised the product) is mainly a consequence of the fact that Web API has been added to MVC without having a reference (or knowledge of it).
As Jon Galloway said on a recent podcast, had the team have HTTP knowledge they have now (as well as hindesight of the popularity of REST API now which they did not have then), they would have designed just a single pipeline serving data and rendered view alike.
I can only speculate that the future version of MVC/Web API will be presented as a single pipeline. In fact, this parallel world might have been a careful plan to unify them in the near future.
It seems crazy to require one set of controllers for rendering HTML
and another for JSON/XML if they're working on the same models.
AFAIK, that's how it is. Standard controllers should be used for rendering HTML and ApiControllers for JSON/XML.
It seems crazy to require one set of controllers for rendering HTML
and another for JSON/XML if they're working on the same models.
Web API is exactly what it is called - a technology for creating API's.
If you are creating an ASP.NET MVC application and want to return some JSON for your own purpose then you don't need content negotiation etc. therefore you don't need Web API (just use plain old good JsonResult).
If you want to create a reusable API than Web API is what you need but your client application should consume it in the same way as everybody else.
Web API isn't meant to be a "hammer" for "nailing" all non-HTML requests - use it when you need it.
I am looking for something similar to this, but not entirely. Through scouring the web, I found a couple posts by Fredrik Normen. He writes about this exact problem space and actually identifies a third-party solution in the second post listed. Basically, the solution involves creating a custom MediaTypeFormatter that knows how to handle views using the Razor engine provided by Microsoft (through the use of a third-party library).
Using Razor engine together with Asp.Net Web API to create a
Hypermedia API
Using Razor together with ASP.NET Web API
ASP.Net Web API and using Razor the next step
Hopefully Microsoft will implement something soon in Web API as Hypermedia seems to be gaining traction.
Hope this helps!
Related
I need to create a website where some of it's pages should be accessible from external clients via an API, but I still want to make regular MVC Razor views to retrieve, display and manipulate the same data.
What's the best way to achieve this?
Update
What the API will have to expose is just data manipulation.
For the web pages, I still want to benefit from the razor chtml views, I prefer not polluting my views with redundant jQ or JS nor data- attributes that consume the data.
Just create an MVC project with the pages you want, and then create ApiControllers (from the Web API framework) to serve as RESTful endpoints. You can program your views to retrieve data from the API actions as JSON objects, and consume them with javascript. Other people can hit the same API actions and use the data in some other way.
If you want to start with a WebApi, and build basic views based on the same data that someone else could access via that API, you could inject your WebApi controllers into your normal MVC controllers, and invoke their methods to get the data that you need to build your ViewModels. This should work all right as long as your API controllers don't need to do anything "outside the box" like inspecting the Request object directly.
A more robust method would be to create a "Manager" layer that handles all the business logic of your application, and then have your ApiControllers be nothing but thin wrappers around calls to their respective Manager classes. This would add a little maintenance cost, but it would adhere to the Single Responsibility Principle a little better.
The easiet way is to use just MVC.
You can also combine MVC + WebAPI in one site.
The reasons to go with the first option is simplicity, and learning maintaining one framework and one set of abstractions.
However if you have any of the following requirements, adding Web API becomes interesting:
1. You want to do content negotiation for response types (say XML vs. Json for the same action).
2. You want to support CORS
3. You want a help page for your API.
4. You want to structure your Url space for your API with rest and resource centric approach (basically GET /resource rather than /resource/GetData).
5. Easier to unit test controllers and actions.
Both frameworks are built by the same team, they both support attribute routing and many similar concepts, and both work well together with one another. I've seen folks take both approaches successfully. Also note that visual studio has templates that combines both of them from the get go.
In my current project I'm using backbone.js as a frontend technology. Ans I should note that I'm still on MVC3 but ready to move on;) Is it reasonable to create api area as data endpoint for my client part. Of course I can avoid it and leave just a plain controller in non-area, exterior part of my project. What is the best practice?
It is good practice to have a separate area for your client API that your backbone models interact with. Separation of concerns, readability and all that.
I would recommend using WebAPI for your API instead of standard MVC controllers though. It is easy to add via nuget, takes minimal config to set up, and it works well with Backbone's HTTP-Verb based approach to model CRUD operations.
If you are already planning on using WebAPI, then please ignore me! If you can't for whatever reason, then I would still say a separate area is a good approach.
I'm writting an application that has many Ajax widgets (Kendo-UI to be percise). It's starting to get messy to have all those Ajax responses without the standard controllers so I was starting to consider making each entities their own controller. If I'm taking the time to do this, I figured I might as well go foward and do those as WebAPIs since I was planning to do this in a not so close future, but hey, it would be done already...
So my question is: Is it a good practice to use an MVC application's own Web API as a Ajax Widget feeds or is there any reason to stick with standard Controllers?
I've seen some arguments about performance, but I don't think this applies to this situation. I believe it was more of a "Controller calling WebAPI" situation which has obvious performance hits. But since it's already a client side Ajax call, weither it goes into a standard MVC Controller or a WebAPI controller shouldn't change a thing, would it?
Edit
Additional information regarding the project:
I am using Entity Framework for the data access.
I have a repository pattern going on with UnitOfWork.
I am using proper a MVC structure (EF POCOs AutoMapped to DTO POCOs in the repository and fed into View Models by the controllers)
This is a MVC 4 project on .NET 4.0
There is a lot of database relationships (specially for the object I'm working with at the moment)
I don't know about "good practice", but it's certainly not "bad practice". I see no difference whether you do it in the app or a different one.
I think its a good thing but only if what you are doing in the API is kept as generic as possible to other applications and services can reuse the API.
Both the applications I have written and continue to maintain use pretty much the exact same stack as your app.
I have recently re-factored one of the applications to use the API for all the common things like lists that I'm binding to Kendo ComboBoxes etc. in my views. Its a fairly large application that re-uses a lot of the same lists such as states, priorities, complexities across various Entities and views so it makes sense to put those in the API.
I haven't gone as far as going the whole hog through. I draw the line with things like this:
public ActionResult GetAjaxProjectsList([DataSourceRequest]DataSourceRequest request)
{
return Json((DataSourceResult)GetProjectsList().ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
That is very specific to how the Kendo Grid wants the data back. Nothing else I have connecting to this app will use this data in this format so I keep it in the controller.
In short... I use the API for common things within the same MVC app and things that I allow to be used by other applications or services, like Excel.
i have to create a new asp.net mvc page that integrates content provided by a cms on the server side static. my mvc page provides a masterpage with the navigation and certain links should point to pages of the cms (which is installed on the same server). it should be something like a "server side iframe".
my idea is to create a controller which loads the page of the cms using a webrequest, extracts the body part of the page and passes the extracted data to the view. the view simply outputs the passed html. i also plan to add some logic to pass post requests to the cms (for news letter subscriptions, contact forms, ...)
now my question is: is it possible to implement this solution? or is there a better way to do this on the server side?
Could you use Application Request Routing to just hand off requests to your CMS, or do you need to include the externally provided content within an existing masterpage?
If you need to use the masterpage I would stick to the solution you suggest, although I might investigate the most robust and efficient option for querying the content from the CMS and perhaps if caching would be a good option.
It is undoubtedly possible, but keeping track of users, authentication, cookies etc. seems like a really tedious job. Also, embedding css classes, hard-coded styling etc. from the CMS in your MVC site could give you a severe headache.
If the CMS isn't home-brewed it probably has an API. In that case I would much prefer to use the API to get at the data I needed and then render that data using pure MVC. This will give you a much cleaner and more stable integration with the CMS.
I'm checking out Web API and I'm not sure how asp.net mvc and web api can or should work together.
I want to implement Backbone on the client side, but I'm not sure if I should implement an ApiController or a normal Controller on the server side?
The way I'm doing things (Getting current user / account information) is that a base ApiController will have some of the same functionality as a base Controller would, which would lead to a bit of duplicate functionality, but not sure what would be the other trade offs.
Or would you only create an ApiController for a public service that you want to provide and stick to Controllers for the web app?
If you're planning an API, use the ApiController. If you're doing Web UI stuff, use the classic Controller. That's what both are made for.
This is almost exactly the situation I am in, except that I am using Knockout.js rather than Backbone. I have views for Create and Edit and within each view, a very complex Knockout.js UI which does loads of Ajaxing of JSON back and forth to the server.
Under MVC3 I was using numerous JsonResult methods within the same controller which rendered the views. I've been experimenting with the RC of MVC4 and was pondering whether to go down the "route" (ho ho) of using an API controller for the Ajax requests. I like the strongly typed HTTP classes and the fact that JSON.NET is more integrated, but at this stage, I have to say that the end result of having a separate API controller for my own internal use just didn't feel right. Like you, I found that I ended up with a lot of duplication around security, and the separation of what was related logic simply by content type made things more confusing rather than cleaner.
So at this point (although I have been known to be fickle) I plan to keep using standard MVC controllers for my current context, but I'll jump at a chance to use the shiny new Web API if I end up exposing a public API.