【问题标题】:How to make ASP.NET MVC Action return different formats?如何让 ASP.NET MVC Action 返回不同的格式?
【发布时间】:2011-09-30 00:08:34
【问题描述】:

我不知道这是否是处理某事的正确方法,但我希望是这样。下面的示例是一个重型控制器,绝对是错误的方法,但它理解了我正在寻找的东西。

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);
        }
    }
}

现在我需要做的是将模型返回给视图,如果它被这样请求:

http://example.com/People/List

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

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

如果有这样的请求,也可以输出 XML:

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

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

我正在考虑使用自定义 MultiPurposeResult 来实现它,它可以为我完成所有过滤,然后将其返回

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

【问题讨论】:

  • 附带说明,MultiPurposeResult 不是最好的名称...我很想知道正确的 Result 名称应该是什么...我似乎总是在命名方面遇到困难。
  • 也许RestActionResult 是一个更好的名字?

标签: asp.net-mvc web-services asp.net-mvc-3 actionresult


【解决方案1】:

同意@Matt。不要显式询问响应类型,推断从请求中的 contentType 中推断出来,这样更 RESTful。

例如,创建了一个基本的枚举类型来封装你想要的响应类型:

public enum RestfulResultType
{
   Json,
   Html,
   Xml
}

然后创建一个自定义模型绑定器,然后根据内容类型在您的操作中设置此属性。

那么你的控制器可能看起来像这样:

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);
   }
}

如果您需要比常规助手提供的更多自定义,请创建自定义 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.
   }
}

Global.asax:

ModelBinders.Binders.Add(typeof(RestfulResultType), new RestfulResultTypeModelBinder());

【讨论】:

  • 我喜欢这个,除了我不想为每个 ActionResult 编写一个开关(我的应用程序中有几十个)......我想我仍然会创建一个自定义返回类型。你能详细说明一下enum RestfulResultType吗?
  • @rock - 没什么大不了的。只是魔术弦的替代品。如果不是开关,那么你怎么能返回不同的类型呢?你是什​​么意思“每个ActionResult”?您是指每个“结果类型”(例如 json、xml)。怎么会有几十个?
  • 在我宁静的应用程序中,我有几十个动作......(抱歉,不是 ActionResults)。我不想为每个Controller的每个Action写一个switch,我宁愿写一个Custom Result Type,把switch写进去。
  • 至于枚举,它是如何设置的?我仍然在查询字符串中传递格式吗?抱歉,我对实际的 Http 请求了解不够。
  • 我为模型绑定器添加了一个示例
【解决方案2】:

您可以创建自定义 MultiPurposeResult 但我个人会从方法签名中丢失 string? api,而是让 MultiPurpose 查找 Request["format"] 的存在,然后确定什么格式可能输出结果。由于格式与 ActionResult 没有任何关系,但更多的是响应的格式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-15
    • 1970-01-01
    相关资源
    最近更新 更多