Web API 2 POST-Request无法使用单

时间:2015-07-23 14:49:31

标签: c# asp.net linux asp.net-web-api mono

我想在Linux机器上编写带有WEB API 2的REST服务器,单声道没有IIS或其他东西。

我做了什么:

  1. 创建了一个空的C#控制台应用程序
  2. 添加了Nuget-Package:Microsoft.AspNet.WebApi.OwinSelfHost,WebApi.Cors用于处理CORS-Request

  3. 然后我创建了一个Startup.cs来定义我的Config;

    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;
        }
    }
    
  4. 编辑我的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();
    
            }
        }
    }
    
  5. 在此步骤中,我添加了一个Model Class Book

    public class Book
    {
        public String Name { get; set; }
        public String Author { get; set; }
    
        public int Id { get; set; }
    }
    
  6. 最终应该处理请求的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);
        }
    }
    
  7. 我在带有mono-4.0.2的Linux机器上启动了整个应用程序 并使用&#34; postman&#34; -Application测试应用程序以创建不同的HTTP请求。

    我已经通过GET-Request / api / books测试服务器并且它有效!

    我的问题是,当我执行POST请求时,我得到了一个&#34; 500内部服务器错误&#34; 响应。

    我的POST-Request看起来像这样 enter image description here

    奇怪的是,当我在.NET Framework上的Windows机器上运行我的应用程序时,POST-Request工作没有问题!

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

2 个答案:

答案 0 :(得分:4)

正如您在自己的回答中所说,问题在于Mono中的CORS实现。

如果您需要CORS,可以使用解决方法。这就是我所做的,改编自这个要点:https://github.com/SEEK-Jobs/whatsupwithmono/issues/6

/// <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);
    }
}

然后在调用ConfigureWebApi之前的config.EnableCors中,执行此操作:

if(Type.GetType("Mono.Runtime") != null) {
    config.MessageHandlers.Add(new MonoPatchingDelegatingHandler());
}
config.EnableCors();

答案 1 :(得分:3)

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

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

在Windows上它没有问题,但在Linux和单声道上,POST-Request不再有效了!

当我删除两个Cors Lines时,它也在单声道上工作。