web-dev-qa-db-ja.com

.net core 2.0 web apihttppostとxml入力がnullとして入力されます

.net core 2.0 web apiHttpPostメソッドを取得してxml入力を処理しようとしています。

期待される結果:テストエンドポイントがPostmanから呼び出される場合、入力パラメーター(以下のコードのxmlMessage)には、PostmanHttpPost本体から送信される値が含まれている必要があります。

実際の結果:入力パラメータがnullです。

Web APIプロジェクトのstartup.csには、次のコードがあります。

public class Startup
{
   public Startup(IConfiguration configuration)
   {
      Configuration = configuration;
   }

   public IConfiguration Configuration { get; }

   // This method gets called by the runtime. Use this method to add services to the container.
   public void ConfigureServices(IServiceCollection services)
   {
      services.AddMvc()
      .AddXmlDataContractSerializerFormatters();
   }

   // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
   public void Configure(IApplicationBuilder app, IHostingEnvironment env)
   {
      if (env.IsDevelopment())
      {
         app.UseDeveloperExceptionPage();
      }
      app.UseMvc();
   }
}

コントローラー内:

[HttpPost, Route("test")]
public async Task<IActionResult> Test([FromBody] XMLMessage xmlMessage)
{
    return null; //not interested in the result for now
}

XMLMessageクラス:

[DataContract]
public class XMLMessage
{
    public XMLMessage()
    {
    }

    [DataMember]
    public string MessageId { get; set; }
}

Postmanヘッダーの場合:

Content-Type:application/xml

Http Post Body:

<XMLMessage>
  <MessageId>testId</MessageId>
</XMLMessage>

私を正しい方向に向けることができる助けに感謝します。前もって感謝します..

5
Matt.G

DataContract/DataElementアノテーションタイプの代わりにXmlRoot/XmlElementを使用する必要があります。以下は、それを機能させるために変更する必要があるものです。

Startup.csで

public void ConfigureServices(IServiceCollection services){
    services.AddMvc(options =>
    {
        options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
    });
    // Add remaining settings
}

XMLMessageクラス:

[XmlRoot(ElementName = "XMLMessage")]
public class TestClass
{
    //XmlElement not mandatory, since property names are the same
    [XmlElement(ElementName = "MessageId")]
    public string MessageId { get; set; }
}

他の部分(コントローラーとヘッダー)は見栄えがします。

MichałBiałeckiは、このトピックについて非常に素晴らしい投稿を作成しました。より詳細な実装については、それを参照してください: ASP.Net MVCコントローラーでXML要求を受け入れる

3
devhiram

私はそれを機能させることができました。私が変更しなければならなかったのはメソッドStartup.ConfigureServices 次のように:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
            .AddXmlSerializerFormatters(); 
}
2
Rui Jarimba

Startup.cs

using System.IO;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace test
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.Microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc(config =>
            {
                config.InputFormatters.Add(new XmlSerializerInputFormatter());
            }).AddXmlDataContractSerializerFormatters();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc();
        }
    }
}

Controller.cs

using System.Runtime.Serialization;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

namespace test.Controllers
{
    [DataContract]
    public class TestClass
    {
        [DataMember]
        public string Message { get; set; }
    }

    [Route("[controller]")]
    public class TestController : Controller
    {
        [HttpPost, Route("test")]
        public async Task<IActionResult> Test([FromBody]TestClass test)
        {
            return Ok("OK");
        }

    }

}

Program.cs

microsoft.AspNetCoreを使用します。 Microsoft.AspNetCore.Hostingを使用する;

namespace test
{
    public class Program
    {
        public static void Main(string[] args)
        {
            BuildWebHost(args).Run();
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();
    }
}

test.csproj

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netcoreapp2.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.9" />
  </ItemGroup>
</Project>
1
Liu