C# Web API 2 POST请求在mono上不起作用

C# Web API 2 POST请求在mono上不起作用,c#,asp.net,linux,asp.net-web-api,mono,C#,Asp.net,Linux,Asp.net Web Api,Mono,我想在Linux机器上编写一个带有WebAPI2的REST服务器,使用mono,而不使用IIS或其他东西 我所做的: 创建了一个空的C#控制台应用程序 添加了Nuget包:Microsoft.AspNet.WebApi.OwinSelfHost、WebApi.Cors以处理Cors请求 然后我创建了一个Startup.cs来定义我的配置 public class Startup { public void Configuration(IAppBuilder app) {

我想在Linux机器上编写一个带有WebAPI2的REST服务器,使用mono,而不使用IIS或其他东西

我所做的:

  • 创建了一个空的C#控制台应用程序
  • 添加了Nuget包:Microsoft.AspNet.WebApi.OwinSelfHost、WebApi.Cors以处理Cors请求

  • 然后我创建了一个Startup.cs来定义我的配置

    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseWebApi(ConfigureWebApi());
        }
    
        private HttpConfiguration ConfigureWebApi()
        {
    
            var config = new HttpConfiguration();
            var cors = new EnableCorsAttribute("*", "*", "*");
            config.EnableCors(cors);
            //Attribute Routing aktivieren
            config.MapHttpAttributeRoutes();
            config.Routes.MapHttpRoute(
    
                "DefaultApi",
    
                "api/{controller}/{id}",
    
                new { id = RouteParameter.Optional });
    
            return config;
        }
    }
    
  • 编辑my Program.cs以充当服务器

        class Program
        {
        static void Main(string[] args)
        {
            string baseUrl = "http://*:5000";
            using (WebApp.Start<Startup>(baseUrl))
            {
                Console.WriteLine("Press Enter to quit.");
                Console.ReadKey();
    
            }
        }
    }
    
  • 最后是负责处理请求的BooksController:

    public class BooksController : ApiController
    {
        public BooksController()
        {}
    
        public async Task<IHttpActionResult> Get()
        {
            List<Book> list = new List<Book>();
            list.Add(new Book() { Name = "myBook",Author = "John" ,Id=1});
            list.Add(new Book() { Name = "myBook2",Author = "Peter",Id=2 });
            return Ok(list);
        }
    
        public async Task<IHttpActionResult> Post(Book requestData)
        {
            return Created<Book>("api/books/" + requestData.Id, requestData);
        }
    }
    
    公共类控制器:ApiController
    {
    公共图书管理员()
    {}
    公共异步任务Get()
    {
    列表=新列表();
    添加(新书(){Name=“myBook”,Author=“John”,Id=1});
    添加(新书(){Name=“myBook2”,Author=“Peter”,Id=2});
    返回Ok(列表);
    }
    公共异步任务发布(Book requestData)
    {
    创建的返回(“api/books/”+requestData.Id,requestData);
    }
    }
    
  • 我在Linux机器上用mono-4.0.2启动了整个应用程序 并使用“postman”应用程序测试应用程序,以创建不同的HTTP请求

    我已经通过对/api/books的GET请求测试了服务器,它成功了

    我的问题是,当我执行POST请求时,会出现“500内部服务器错误” 答复

    我的发帖请求是这样的

    奇怪的是,当我在.NET Framework上的windows机器上运行我的应用程序时,POST请求工作正常


    我不明白为什么它不在mono上工作!希望有人知道答案。

    现在我自己找到了答案:-)

    问题在于启动文件中包含的CORS包

    在Windows上没有问题,但在Linux和mono上,POST请求不再有效


    当我删除两行Cors时,它也在mono上工作。

    正如您在自己的回答中所说,问题在于mono中的Cors实现

    如果您需要CORS,可以使用变通方法。这就是我所做的,改编自以下要点:


    嗨,我有同样的问题,但我的webapi中没有任何COR。我把我的问题贴在这里:如果你能帮忙,请告诉我。我也有类似的问题。我尝试了很多解决方案,但都不管用。
    public class BooksController : ApiController
    {
        public BooksController()
        {}
    
        public async Task<IHttpActionResult> Get()
        {
            List<Book> list = new List<Book>();
            list.Add(new Book() { Name = "myBook",Author = "John" ,Id=1});
            list.Add(new Book() { Name = "myBook2",Author = "Peter",Id=2 });
            return Ok(list);
        }
    
        public async Task<IHttpActionResult> Post(Book requestData)
        {
            return Created<Book>("api/books/" + requestData.Id, requestData);
        }
    }
    
    /// <summary>
    /// Work around a bug in mono's implementation of System.Net.Http where calls to HttpRequestMessage.Headers.Host will fail unless we set it explicitly.
    /// This should be transparent and cause no side effects.
    /// </summary>
    private class MonoPatchingDelegatingHandler : DelegatingHandler {
        protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
            request.Headers.Host = request.Headers.GetValues("Host").FirstOrDefault();
            return await base.SendAsync(request, cancellationToken);
        }
    }
    
    if(Type.GetType("Mono.Runtime") != null) {
        config.MessageHandlers.Add(new MonoPatchingDelegatingHandler());
    }
    config.EnableCors();