2016-03-17 150 views
0

我有一個控制器返回一個自定義的XML字符串,因爲使用Api的應用程序需要一個沒有任何屬性的特定格式,並且沒有默認XML字符串上的<?xml ... />標籤。 編輯:消費者也沒有要求'text/xml'的請求標頭。ASP.NET 5 MVC 6 XML響應標頭

我在我的Startup.cs ConfigureServices看起來是這樣的:

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:application/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(盧卡蓋爾西的回答後): 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

查看MVC 6中有關Formatters的非常詳細的文章。它是更新後的版本。我想這會有所幫助。

要修改responde將如何產生你可以使用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

它仍然返回'text/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動作)和'person'類文件,所以我懷疑有什麼東西會覆蓋它。儘管如此,我已經將我的代碼更新爲新增內容,但仍然返回text/plain。 – AppSum

+0

@Asum [This answer](http://stackoverflow.com/a/23381647/67392)可能會有所幫助:看起來您不能直接直接操作內容類型。 – Richard

+0

我解決了頭,但現在我使用XMLformatter,現在XML再次具有屬性。有沒有辦法改變格式化程序將對象序列化爲XML的方式? – AppSum

相關問題