2

I don't know if this is the right way to approach something, but I'm hoping it is. The example below is a heavy controller and is absolutely the wrong approach, but it get's the idea of what I'm looking for across.

public class PeopleController : Controller
{
    public ActionResult List(string? api)
    {
        MyViewModel Model = new MyViewModel();

        if (api == "json") {

            // I'd like to return the Model as JSON

        } else if (api == "XML") {

            // I'd like to return the Model as XML

        } else {

            return View(Model);
        }
    }
}

Now what I need to be able to do is return the Model to the View if it's being requested like this:

http://example.com/People/List

But I'd like it to output JSON if it's requested like this:

http://example.com/People/List/?api=json

Or output XML if it's requested like this:

http://example.com/People/List/?api=xml

Is this just plain wrong? If not, what is the best approach to achieve this?

I was thinking of achieving it with a Custom MultiPurposeResult that could do all the filtering for me and then return it as this

public class PeopleController : Controller
{
    public MultiPurposeResult List(string? api)
    {
        MyViewModel Model = new MyViewModel();
        return MultiPurpose(Model);      }
    }
}
2
  • As a side note, MultiPurposeResult isn't the best name... I'd love to know what a proper Result name should be... I always seem to struggle with naming. Commented Sep 30, 2011 at 0:30
  • Maybe RestActionResult is a better name ? Commented Sep 30, 2011 at 1:10

2 Answers 2

5

Agree with @Matt. Don't explicitly ask for the response type, infer it from the contentType in the request, which is more RESTful.

For example, created a basic enum type to encapsulate the response types you want:

public enum RestfulResultType
{
   Json,
   Html,
   Xml
}

Then create a custom model binder than sets this property in your action, depending on the content type.

Then your controller could look like this:

public ActionResult List(RestfulResultType resultType)
{
   var data = repo.GetSomeData();

   switch (resultType)
   {
      case RestfulResultType.Json:
         return Json(data);
      case RestfulResultType.Xml:
         return XmlResult(data); // MvcContrib
      case RestfulResultType.Html:
         return View(data);
   }
}

If you need any more customization than the regular helpers provide, then create custom ActionResult's.

You can leave the return type as ActionResult - that's the point, so that the controller can return different formats.

ResfulResultTypeModelBinder.cs:

public class ResfulResultTypeModelBinder: IModelBinder
{
   public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
   {
     if (controllerContext.HttpContext.Request.ContentType == "application/json")
        return RestfulResultType.Json;
     // other formats, etc.
   }
}

Global.asax:

ModelBinders.Binders.Add(typeof(RestfulResultType), new RestfulResultTypeModelBinder());
Sign up to request clarification or add additional context in comments.

7 Comments

I like this, except I don't want to write a switch for each ActionResult (I have dozens throughout my app)... I think I'll still create a custom return type. Could you elaborate a little on the enum RestfulResultType?
@rock - nothing much to it. Just an alternative to magic strings. If not a switch, then how can you return different types? What do you mean "each ActionResult"? Do you mean each "result type" (e.g json, xml). How can there be dozens?
In my restful app I've got dozens of Actions... (sorry, not ActionResults). I don't want to write a switch into each Action for each Controller, I'd rather write a Custom Result Type, and write the switch into it.
As for the enum, how does it get set? Do I still pass the format in the querystring? Sorry, I don't know enough about the actual Http request.
i added an example for the model binder
|
1

You can create a custom MultiPurposeResult but I personally would lose the string? api from the method signature, instead have the MultiPurpose look for the presence of Request["format"] and then make the determination of what format to possible output the results in. Since the format doesn't nessecarily have anything to do with the ActionResult but more the format of the response.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.