Как заставить ASP.NET MVC Action возвращать разные форматы? - PullRequest
2 голосов
/ 30 сентября 2011

Я не знаю, является ли это правильным подходом к чему-то, но я надеюсь, что это так.Приведенный ниже пример является тяжелым контроллером и является абсолютно неправильным подходом, но он дает представление о том, что я искал.

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

Теперь мне нужно иметь возможность вернуть модельв View, если он запрашивается следующим образом:

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

Ответы [ 2 ]

5 голосов
/ 30 сентября 2011

Согласен с @Matt. Не запрашивайте явно тип ответа, вывод его из contentType в запросе, который является более RESTful.

Например, создан базовый тип enum для инкапсуляции нужных типов ответов:

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());
1 голос
/ 30 сентября 2011

Вы можете создать пользовательский MultiPurposeResult , но я лично потерял бы string? api из сигнатуры метода, вместо этого в MultiPurpose ищите наличие Request["format"] и затем определите, какой формат можно выводить результаты в. Поскольку формат не всегда имеет какое-либо отношение к ActionResult, но больше относится к формату ответа.

...