0

I currently have a MVC 3 Web Application with around 50 Views.

Is it somehow possible to provide some kind of API next to my Views so everything still works fine and dandy?

My kinda perfect world idea:

Server is running and every request gets to its view. The user can decide in his get request if he wants the raw data in lets say JSON. Additional to the raw data also the Structure/Names of the Viewmodel will be parsed so the Modelbinder can do his stuff.

or another approach might be to somehow deactivate my Views to have only the API available (again with raw data and structure).

Is this even possible (the modelbinder is kinda a big concern) and maybe even without much effort/trouble to do?

David
  • 1,601
  • 3
  • 22
  • 33
Vulcano
  • 415
  • 10
  • 25
  • Maybe you'd want to add an ASP.NET Web API to your application? You might like to have a look at my question on how to add Web API capabilities to an MVC 4 Internet Application: http://stackoverflow.com/questions/11990036/how-to-add-web-api-to-an-existing-asp-net-mvc-4-web-application-project. Hope you find this helpful. – aknuds1 Aug 27 '12 at 10:04

2 Answers2

3

If you don't want to do everything all over again with WebAPI, you can implement some ActionFilterAttribute to change the ActionResult based on some querystring f.i. Something like this:

public class ResultSwitcherAttribute: ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext.HttpContext.Request["data"] != null && filterContext.HttpContext.Request["data"] == "json")
        {
            filterContext.Result = new JsonResult
                {
                    Data = (filterContext.Result as ViewResult).Model,
                    JsonRequestBehavior = JsonRequestBehavior.AllowGet
                };
        }
    }
}

Then, you'll register that either in application_start or per controller/action like this:

[ResultSwitcherAttribute]
public class HomeController : Controller
{
    public ActionResult Index()
    {

        return View(new TestModel()
            {
                Web = "http://www.mywebpage.com", Name = "Yngve"
            });
    }
}

When you now access your url with ?data=json you'll get a JSON-representation of the Model, instead of the view.

EDIT: Code sample updated

Yngve B-Nilsen
  • 9,606
  • 2
  • 36
  • 50
  • Nice idea. But it's better to do it in `OnResultExecuting` so that the view isn't rendered as HTML first and then as JSON. The alternative is to create a new controller method (in the base controller or an extension method) than either returns a `ViewResult` or a `JsonResult` – jgauffin Aug 27 '12 at 10:46
  • @jgauffin If I'm not mistaken, I don't think you can switch out the Result in the OnResultExecuting/Executed, since the ActionExecuted will run after, wrapping the Model in the ViewResult... If you know how, please show me :) – Yngve B-Nilsen Aug 27 '12 at 10:53
  • The action methods are invoked before the result methods. Since the action is the one selecting which result to execute. – jgauffin Aug 27 '12 at 10:59
  • thx for the input, ill try around a bit and respond back. but idk if i can do it today – Vulcano Aug 27 '12 at 11:06
  • @jgauffin I did try with both OnResultExecuting and OnResultExecuted, but I wasn't able to switch out the Result in either one of them.. – Yngve B-Nilsen Aug 27 '12 at 11:06
  • 1
    seems like you are correct (by switching to OnActionExecuted ;)) – jgauffin Aug 27 '12 at 11:36
0

Consider adding an ASP.NET Web API to your app. It's extremely simple to implement, entailing little more than adding an API controller with methods corresponding to your REST actions. I don't know how one would go about adding this to an MVC 3 app, but I have a recipe for MVC 4 Internet Applications in this stackoverflow question. So, if you're fine with upgrading your project so that it is Web API capable, perhaps to MVC 4, I think it'd represent a good alternative.

To learn ASP.NET Web API, this tutorial is a good place to start.

Community
  • 1
  • 1
aknuds1
  • 65,625
  • 67
  • 195
  • 317
  • i don't want to create another controller which either calls the normal controller for every function or does the 1:1 the same stuff as my original controller. i somehow want to have 1 controller and according to a flag either the json or the normal view should be rendered. – Vulcano Aug 27 '12 at 10:48