Лучший способ структурировать код для ASP.NET MVC REST API, который отделен от форматов данных? - PullRequest
7 голосов
/ 08 июня 2011

Я создаю REST API в ASP.NET MVC.Я хочу, чтобы формат запроса и ответа был JSON или XML, однако я также хочу упростить добавление другого формата данных и простого создания сначала только XML, а позднее - JSON.

По сути, я хочу указать всю внутреннюю работу моих запросов API GET / POST / PUT / DELETE, не думая о том, в каком формате были введены данные или как они будут оставлены, и я мог бы легко указатьформат позже или измените его для каждого клиента.Таким образом, один парень мог использовать JSON, один парень мог использовать XML, один парень мог использовать XHTML.Затем позже я мог бы добавить еще один формат без необходимости перезаписывать тонну кода.

Я НЕ хочу добавлять кучу операторов if / then в конец всех моих действий, чтобы они определялиформат данных, я предполагаю, что есть какой-то способ, которым я могу сделать это, используя интерфейсы или наследование или тому подобное, просто не уверен, что лучший подход.

Ответы [ 3 ]

7 голосов
/ 08 июня 2011

Сериализация

Для этого предназначен конвейер ASP.NET. Действия вашего контроллера не возвращают результат клиенту, а скорее объект результата (ActionResult), который затем обрабатывается на последующих этапах в конвейере ASP.NET. Вы можете переопределить класс ActionResult. Обратите внимание, что FileResult, JsonResult, ContentResult и FileContentResult встроены в MVC3.

В вашем случае , вероятно, лучше вернуть что-то вроде RestResult объекта. Этот объект теперь отвечает за форматирование данных в соответствии с запросом пользователя (или какими-либо дополнительными правилами, которые у вас могут быть):

public class RestResult<T> : ActionResult
{
    public override void ExecuteResult(ControllerContext context)
    {
        string resultString = string.Empty;
        string resultContentType = string.Empty;

        var acceptTypes = context.RequestContext.HttpContext.Request.AcceptTypes;

        if (acceptTypes == null)
        {
            resultString = SerializeToJsonFormatted();
            resultContentType = "application/json";
        }
        else if (acceptTypes.Contains("application/xml") || acceptTypes.Contains("text/xml"))
        {
            resultString = SerializeToXml();
            resultContentType = "text/xml";
        }

       context.RequestContext.HttpContext.Response.Write(resultString);
        context.RequestContext.HttpContext.Response.ContentType = resultContentType;
   }
}

Десериализация

Это немного сложнее. Мы используем метод Deserialize<T> в базовом классе контроллера. Обратите внимание, что этот код не готов к работе , поскольку чтение всего ответа может привести к переполнению вашего сервера:

protected T Deserialize<T>()
{
    Request.InputStream.Seek(0, SeekOrigin.Begin);
    StreamReader sr = new StreamReader(Request.InputStream);
    var rawData = sr.ReadToEnd(); // DON'T DO THIS IN PROD!

    string contentType = Request.ContentType;

    // Content-Type can have the format: application/json; charset=utf-8
    // Hence, we need to do some substringing:
    int index = contentType.IndexOf(';');
    if(index > 0)
        contentType = contentType.Substring(0, index);
    contentType = contentType.Trim();

    // Now you can call your custom deserializers.
    if (contentType == "application/json")
    {
        T result = ServiceStack.Text.JsonSerializer.DeserializeFromString<T>(rawData);                
        return result;
    }
    else if (contentType == "text/xml" || contentType == "application/xml")
    {
        throw new HttpException(501, "XML is not yet implemented!");
    }
}
0 голосов
/ 08 июня 2011

Просто хотел поставить это здесь для справки, но я обнаружил, что использование ASP.NET MVC может быть не лучшим способом сделать это:

Windows Communication Foundation (WCF) обеспечивает единую модель программирования для быстрого построения ориентированных на сервис приложения, которые общаются через Интернет и предприятие

Разработчики веб-приложений сегодня сталкиваются с новыми проблемами вокруг того, как выставлять данные и сервисы. Облако, перейти к устройствам и перейти к основанные на браузере фреймворки, такие как JQuery все больше и больше размещаются требования по всплытию такие функциональность в веб-стиле. Предложение веб-API WCF ориентировано на предоставляя разработчикам инструменты для сочинить простой, но мощный приложения, которые играют в этом новом Мир. Для разработчиков, которые хотят пойти дальше, чем просто разоблачение по HTTP, наш API позволит вам получить доступ ко всем богатство HTTP и применять RESTful ограничения в вашем разработка приложения. Эта работа эволюция HTTP / ASP.NET AJAX функции, уже поставленные в .Net 4.0.

http://wcf.codeplex.com/

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

0 голосов
/ 08 июня 2011

В этой статье рассказывается, как делать именно то, что вы хотите. Я использовал его, когда создавал свой MVC REST API в прошлом проекте.

http://omaralzabir.com/create_rest_api_using_asp_net_mvc_that_speaks_both_json_and_plain_xml/

...