2016-03-17 6 views
0

У меня есть контроллер, который возвращает пользовательскую строку XML, потому что приложение, которое потребляет Api, нуждается в определенном формате без каких-либо атрибутов и без тега <?xml ... /> поверх строк XML по умолчанию , EDIT: потребитель также не имеет заголовка запроса, который запрашивает текст/xml.ASP.NET 5 MVC 6 Заголовок ответа XML

Мои ConfigureServices в моем Startup.cs выглядит следующим образом:

public void ConfigureServices(IServiceCollection services) 
    { 
     // Add framework services. 
     var mvc = services.AddMvc(); 

     mvc.AddMvcOptions(options => 
     { 
      options.InputFormatters.Remove(new JsonInputFormatter()); 
      options.OutputFormatters.Remove(new JsonOutputFormatter()); 
     }); 

     mvc.AddXmlDataContractSerializerFormatters(); 
    } 

В мой контроллер, я пытался несколько решений я нашел в Интернете (закомментированного), но никто не даст мне содержание XML с ответом заголовка 'Content-Type: применение/XML' в хромированных Devtools:

[HttpGet("{ssin}")] 
[Produces("application/xml")] 
public string Get(string ssin) 
{  
    var xmlString = ""; 
    using (var stream = new StringWriter()) 
    { 
     var xml = new XmlSerializer(person.GetType()); 
     xml.Serialize(stream, person); 
     xmlString = stream.ToString(); 
    } 
    var doc = XDocument.Parse(xmlString); 
    doc.Root.RemoveAttributes(); 
    doc.Descendants("PatientId").FirstOrDefault().Remove(); 
    doc.Descendants("GeslachtId").FirstOrDefault().Remove(); 
    doc.Descendants("GeboorteDatumUur").FirstOrDefault().Remove(); 
    doc.Descendants("OverledenDatumUur").FirstOrDefault().Remove(); 
    Response.ContentType = "application/xml"; 
    Response.Headers["Content-Type"] = "application/xml"; 

    /*var response = new HttpResponseMessage 
    { 
     Content = new StringContent(doc.ToString(), Encoding.UTF8, "application/xml"), 
    };*/ 
    return doc.ToString(); //new HttpResponseMessage { Content = new StringContent(doc., Encoding.UTF8, "application/xml") }; 
} 

Что я могу попытаться получить его ответить приложения/XML? Response

EDIT1 (после ответа Luca Ghersi в): Startup.cs:

public Startup(IHostingEnvironment env) 
    { 
     // Set up configuration sources. 
     var builder = new ConfigurationBuilder() 
      .AddJsonFile("appsettings.json") 
      .AddEnvironmentVariables(); 
     Configuration = builder.Build(); 
    } 

    public IConfigurationRoot Configuration { get; set; } 

    // This method gets called by the runtime. Use this method to add services to the container. 
    public void ConfigureServices(IServiceCollection services) 
    { 
     // Add framework services. 
     var mvc = services.AddMvc(config => { 
      config.RespectBrowserAcceptHeader = true; 
      config.InputFormatters.Add(new XmlSerializerInputFormatter()); 
      config.OutputFormatters.Add(new XmlSerializerOutputFormatter()); 
     }); 

     mvc.AddMvcOptions(options => 
     { 
      options.InputFormatters.Remove(new JsonInputFormatter()); 
      options.OutputFormatters.Remove(new JsonOutputFormatter()); 
     }); 

     //mvc.AddXmlDataContractSerializerFormatters(); 
    } 
    /* 
    * Preconfigure if the application is in a subfolder/subapplication on IIS 
    * Temporary fix for issue: https://github.com/aspnet/IISIntegration/issues/14 
    */ 
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
    { 
     app.Map("/rrapi", map => ConfigureApp(map, env, loggerFactory)); 
    } 


    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 
    public void ConfigureApp(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
    { 
     loggerFactory.AddConsole(Configuration.GetSection("Logging")); 
     loggerFactory.AddDebug(); 

     //app.UseIISPlatformHandler(); 

     app.UseMvc(routes => 
     { 
      routes.MapRoute(
       name: "default", 
       template: "{controller=Home}/{action=Index}/{id?}"); 
     }); 
    } 

    // Entry point for the application. 
    public static void Main(string[] args) => WebApplication.Run<Startup>(args); 

Контроллер:

 [HttpGet("{ssin}")] 
    [Produces("application/xml")] 
    public IActionResult Get(string ssin) 
    { 
     var patient = db.Patienten.FirstOrDefault(
      p => p.Rijksregisternummer.Replace(".", "").Replace("-", "").Replace(" ", "") == ssin 
     ); 

     var postcode = db.Postnummers.FirstOrDefault(p => p.PostnummerId == db.Gemeentes.FirstOrDefault(g => 
      g.GemeenteId == db.Adressen.FirstOrDefault(a => 
       a.ContactId == patient.PatientId && a.ContactType == "pat").GemeenteId 
      ).GemeenteId 
     ).Postcode; 

     var person = new person 
     { 
      dateOfBirth = patient.GeboorteDatumUur.Value.ToString(""), 
      district = postcode, 
      gender = (patient.GeslachtId == 101 ? "MALE" : "FEMALE"), 
      deceased = (patient.OverledenDatumUur == null ? "FALSE" : "TRUE"), 
      firstName = patient.Voornaam, 
      inss = patient.Rijksregisternummer.Replace(".", "").Replace("-", "").Replace(" ", ""), 
      lastName = patient.Naam 
     }; 
     var xmlString = ""; 
     using (var stream = new StringWriter()) 
     { 
      var opts = new XmlWriterSettings { OmitXmlDeclaration = true }; 
      using (var xw = XmlWriter.Create(stream, opts)) 
      { 
       var xml = new XmlSerializer(person.GetType()); 
       xml.Serialize(xw, person); 
      } 
      xmlString = stream.ToString(); 
     } 
     var doc = XDocument.Parse(xmlString); 
     doc.Root.RemoveAttributes(); 
     doc.Descendants("PatientId").FirstOrDefault().Remove(); 
     doc.Descendants("GeslachtId").FirstOrDefault().Remove(); 
     doc.Descendants("GeboorteDatumUur").FirstOrDefault().Remove(); 
     doc.Descendants("OverledenDatumUur").FirstOrDefault().Remove(); 

     return Ok(doc.ToString()); 

ответ

0

Похоже, этот article является то, что вы ищете. Вместо того, чтобы пытаться сделать это вручную, вы должны попробовать XML форматировщик, как это:

// Add framework services. 
    services.AddMvc(config => 
    { 
    // Add XML Content Negotiation 
    config.RespectBrowserAcceptHeader = true; 
    config.InputFormatters.Add(new XmlSerializerInputFormatter()); 
    config.OutputFormatters.Add(new XmlSerializerOutputFormatter()); 
    }); 

Это outputFormatter dependes на:

"Microsoft.AspNet.Mvc.Formatters.Xml": "6.0.0-rc1-final" 

Кроме того, необходимо оставить [Produces("application/xml")] как атрибут метода, как описано в это answer.

Проверьте также эту чрезвычайно подробную статью о Formatters в MVC 6. Это обновленная версия. Думаю, это будет полезно.

Чтобы изменить как будет Отвечает генерироваться вы можете использовать XmlWriterSettings приемят варианты, как это (подробнее here):

var settings = new XmlWriterSettings { OmitXmlDeclaration = true }; 
config.OutputFormatters.Add(new XmlSerializerOutputFormatter(settings); 

Надеется, что это помогает!

+0

Спасибо за быстрый ответ, но, к сожалению (я забыл упомянуть об этом, добавив его на мой пост), потребитель не добавляет заголовок запроса «text/xml», поэтому согласование контента не является вариантом. Я должен заставить его либо запросить xml, либо заставить заголовок ответа ответить, что он возвращает «application/xml». – AppSum

+0

Забудьте о согласовании содержимого.Если вы удалите форматировщик JSON, как и вы, и оставите только XML, он должен работать, я думаю, потому что он будет единственным доступным форматом для ASP.NET. –

+0

По-прежнему он возвращает текст/plain. Я добавлю EDIT1 на свой пост, чтобы показать свои изменения. – AppSum

0

Создайте параметры дополнений XmlWriter, чтобы заблокировать создание декларации XML. Затем используйте одну из перегрузок XmlSerializer.Serialize, которая принимает XmlWriter. XmlWriter можно записать в строку (см here):

using (var sw = new StringWriter()) { 
    var opts = new XmlWriterSettings { OmitXmlDeclaration = true }; 
    using (var xw = XmlWriter.Create(sw, opts) { 

    xml.Serialize(xw, person); 

    } 
    xmlString = sw.ToString(); 
} 

NB Вы уже садилось Response.ContentType поэтому что-то другое, если переопределение этого. Проверьте фильтры и модули, которые могут переопределять настройки.

+0

Это файл-новый проект с 1 контроллером с 2 действием (индекс, показывающий, что api работает и действие ssin), и файл класса «человек», поэтому я сомневаюсь, что что-то его переопределяет. Тем не менее, я обновил свой код до ваших дополнений, но он все равно возвращает текст/plain. – AppSum

+0

@Asum [Этот ответ] (http://stackoverflow.com/a/23381647/67392) может помочь: появляется, что вы напрямую не можете напрямую манипулировать типом контента. – Richard

+0

Я решил заголовок, но теперь я использую XMLformatter, и теперь XML имеет атрибуты снова. Есть ли способ изменить способ, с помощью которого форматтер сериализует объект в XML? – AppSum

 Смежные вопросы

  • Нет связанных вопросов^_^