Отправка XML-ответа из MVC Rest API

#.net #xml #asp.net-mvc #asp.net-mvc-4 #rest

#.net #xml #asp.net-mvc #asp.net-mvc-4 #rest

Вопрос:

Я пытаюсь реализовать службу MVC Rest API, которая возвращает XML.

Код выглядит примерно так:

 public IEnumerable<XDocument> getXml(...)
        {
            XDocument responseXml = MakeHttpRequestAndGetResponseXML(...);
            return responseXml;
        }
  

Но, конечно, это не сработает, это просто моя попытка, которая не удалась. Когда у меня есть XML-ответ в XDocument объекте, как я могу вернуть его как действительный XML через мой веб-сервис?

Ответ №1:

Что я обычно делал в прошлом для этого, так это создавал DTO для представления вашего XML и присваивал вашим свойствам DTO атрибуты сериализации для описания XML:

 [DataContract(Name = "Service", Namespace = "")]
public class ServiceApiDTO
{
    [DataMember(IsRequired = true, Order = 0, EmitDefaultValue = false)]
    public string Name { get; set; }

    [DataMember(IsRequired = true, Order = 1, EmitDefaultValue = false)]
    public string Description { get; set; }

    [DataMember(IsRequired = true, Order = 2, EmitDefaultValue = false)]
    public string Url { get; set; }

    [DataMember(IsRequired = false, Order = 3, EmitDefaultValue = false)]
    public DepartmentApiDTO Department { get; set; }

    [DataMember(IsRequired = false, Order = 4, EmitDefaultValue = false)]
    public string SLA { get; set; }

    [DataMember(IsRequired = false, Order = 5, EmitDefaultValue = false)]
    public string Cost { get; set; }

    [DataMember(IsRequired = true, Order = 6, EmitDefaultValue = false)]
    public ServiceStatusApiDTO CurrentStatus { get; set; }

    [DataMember(IsRequired = true, Order = 7, EmitDefaultValue = false)]
    public UserApiDTO CreatedBy { get; set; }
}
  

а затем создайте WebApiController для предоставления этих DTO через HttpGet:

 public class ServicesController : ApiController
{
    private readonly IServiceService _serviceService;

    public ServicesController(IServiceService serviceService)
    {
        _serviceService = serviceService;
    }

    //
    // GET: /api/Services/Service.{ext}/{url}

    [HttpGet]
    public ServiceApiDTO Service(string url)
    {
        var service = _serviceService.GetServiceByUrl(url);

        if (service == null)
        {
            var error = new HttpError(String.Format("No service found with URL = '{0}'", url));

            throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound, error));
        }

        var serviceDTO = Mapper.Map<Service, ServiceApiDTO>(service);

        return serviceDTO;
    }
}
  

и затем скажите моему WebApiConfig обрабатывать расширения Xml и Json:

 public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "ActionApi",
            routeTemplate: "api/{controller}/{action}.{ext}",
            defaults: new { ext = "xml|json" }
        );

        config.Routes.MapHttpRoute(
            name: "ActionApiServiceUrl",
            routeTemplate: "api/{controller}/{action}.{ext}/{url}",
            defaults: new { url = RouteParameter.Optional, ext = "xml|json" }
        );

        var jsonFormatter = config.Formatters.JsonFormatter;
        var xmlFormatter = config.Formatters.XmlFormatter;

        jsonFormatter.AddUriPathExtensionMapping("json", "application/json");
        xmlFormatter.AddUriPathExtensionMapping("xml", "text/xml");
    }
}
  

Как только у вас все настроено, вы можете получить доступ к своему API, например, http://localhost/api/Services/Service.xml/urlParameter для ответа в формате XML или http://localhost/api/Services/Service.json/urlParameter для ответа в формате JSON.

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

К вашему сведению, некоторые из используемых здесь технологий — AutoMapper для сопоставления объекта домена с DTO и CastleWindsor для внедрения зависимостей сервисов в WebApiController.