如何使ASP.NET MVC Action返回不同的格式?

Cha*_*ell 2 asp.net-mvc web-services actionresult asp.net-mvc-3

我不知道这是否是接近某事的正确方法,但我希望它是.下面的例子是一个沉重的控制器,绝对是错误的方法,但它让我知道我正在寻找什么.

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我需要做的是将Model返回给View,如果它是这样请求的话

http://example.com/People/List

但我希望它输出JSON,如果这样请求它

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

如果像这样请求输出XML

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

这是完全错的吗?
如果没有,实现这一目标的最佳方法是什么?

我想用一个Custom MultiPurposeResult来实现它,它可以为我做所有的过滤,然后将其返回

public class PeopleController : Controller
{
    public MultiPurposeResult List(string? api)
    {
        MyViewModel Model = new MyViewModel();
        return MultiPurpose(Model);      }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑
我发现这个博客的方法与我的第一个代码块相同.
http://shouldersofgiants.co.uk/Blog/post/2008/10/16/Creating-a-RESTful-Web-Service-Using-ASPNet-MVC-Part-5a-e28093-HTTP-Response-Codes.aspx

RPM*_*984 5

同意@Matt.不要明确要求响应类型,从请求中的contentType 推断它,这更加RESTful.

例如,创建一个基本的枚举类型来封装所需的响应类型:

public enum RestfulResultType
{
   Json,
   Html,
   Xml
}
Run Code Online (Sandbox Code Playgroud)

然后创建自定义模型绑定器,而不是在操作中设置此属性,具体取决于内容类型.

然后您的控制器可能如下所示:

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);
   }
}
Run Code Online (Sandbox Code Playgroud)

如果您需要比常规帮助程序提供的更多自定义,则创建自定义ActionResult.

您可以将返回类型保留为ActionResult- 这就是要点,以便控制器可以返回不同的格式.

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.
   }
}
Run Code Online (Sandbox Code Playgroud)

Global.asax中:

ModelBinders.Binders.Add(typeof(RestfulResultType), new RestfulResultTypeModelBinder());
Run Code Online (Sandbox Code Playgroud)