自托管Web Api C#与Windows窗体错误

时间:2013-06-06 16:27:31

标签: c# winforms asp.net-web-api self-hosting

我参加了一个示例项目webapi Self Hosting,即Microsoft页面。 webapi正确启动,但在访问该地址时,它会给出以下错误。我正在使用VS2010和Windows Forms。使用控制台应用程序,它的工作和Windows窗体无法正常工作。

程序代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Web.Http.SelfHost;
using System.Web.Http;
using System.Net.Http;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {

        HttpSelfHostServer server;
        HttpSelfHostConfiguration config;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

            var config = new HttpSelfHostConfiguration("http://localhost:9090");

            config.Routes.MapHttpRoute(
                "API Default", "api/{controller}/{id}",
                new { id = RouteParameter.Optional });

            using (HttpSelfHostServer server = new HttpSelfHostServer(config))
            {
                server.OpenAsync().Wait();
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri("http://localhost:9090");

            //Console.WriteLine("Products in '{0}':", category);

            string query = string.Format("api/products?category={0}", "testes");

            var resp = client.GetAsync(query).Result;
            //resp.EnsureSuccessStatusCode();

            var products = resp.Content.ReadAsAsync<string>().Result;
            MessageBox.Show(products);
        }
    }
}

控制器:

namespace SelfHost
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Web.Http;


    public class ProductsController : ApiController
    {

        public string GetProductsByCategory(string category)
        {
            return (category ?? "Vazio");
        }
    }
}

错误:

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Object reference not set to an instance of an object.
</ExceptionMessage>
<ExceptionType>System.NullReferenceException</ExceptionType>
<StackTrace>
at System.Web.Http.SelfHost.HttpSelfHostServer.ProcessRequestContext(ChannelContext channelContext, RequestContext requestContext)
</StackTrace>
</Error>

1 个答案:

答案 0 :(得分:3)

我看到你的代码有很多错误,我认为我不能将它们全部包含在评论中。也许你会修复它们 - 这个例外就会消失。

的问题:

  1. 在此代码server.OpenAsync().Wait();之后,您在Dispose上调用server方法(因为您在using语句中包装了所有内容)。这意味着当OpenAsync完成时(此任务将在服务器运行时完成) - 在此之后您将关闭服务器。

  2. 当您在任务上调用Wait时,主线程上有一堆死锁。请查看此文章http://blogs.msdn.com/b/pfxteam/archive/2011/01/13/10115163.aspx

  3. 这是我尝试重写您的示例以解决这两个问题:

    public partial class Form1 : Form
    {
        HttpSelfHostServer server;
        HttpSelfHostConfiguration config;
    
        public Form1()
        {
            InitializeComponent();
        }
    
        private async void button1_Click(object sender, EventArgs e)
        {
            config = new HttpSelfHostConfiguration("http://localhost:9090");
    
            config.Routes.MapHttpRoute(
                "API Default", "api/{controller}/{id}",
                new { id = RouteParameter.Optional });
    
            HttpSelfHostServer server = new HttpSelfHostServer(config);
            await server.OpenAsync();
            // Server is running: you can show something to user like - it is running
            MessageBox.Show("Server is ready!");
        }
    
        private async void button2_Click(object sender, EventArgs e)
        {
            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri("http://localhost:9090");
    
            string query = string.Format("api/products?category={0}", "testes");
    
            var resp = await client.GetAsync(query);
    
            var products = await resp.Content.ReadAsAsync<string>();
            MessageBox.Show(products);
        }
    }