iT邦幫忙

0

(已解)OWIN Self-Host API 問題 WPF NET6

  • 分享至 

  • xImage

解決了
下述寫法是 Framework的寫法
NET的寫法

public static void OpenServer()
{
var builder = WebApplication.CreateBuilder(new string[] { });
builder.Services.AddControllers();
var app = builder.Build();
app.Urls.Add("http://0.0.0.0:8080"); // 手動設定port
app.MapControllers();
app.RunAsync();
}

參考資料程式碼: 微軟文件網路文件

目前是用WPF NET6
我照文件上的程式碼實作後
Program.cs的 (WPF 我寫在 MainWindow.xaml.cs內的 public MainWindow()中)
using (WebApp.Start<Startup>(url: baseAddress))
VS會過測 但用POSTMAE丟資料會跑出 Error: connect ECONNREFUSED 127.0.0.1:8080

然後用主控台.Net Framework 寫後
會變成 VS不過測 跳出錯誤訊息

using (WebApp.Start<Startup>(url: baseAddress)) //這行
System.NullReferenceException: 'Object reference not set to an instance of an object.'

程式碼 Startup.cs跟 TestController.cs 一樣
只有NET Framwork用Program.cs
WPF NET6用MainWindow.xaml.cs

Startup.cs

using System.Web.Http;
//using System.Web.Http.Cors;
using Microsoft.Owin;
using Owin;

[assembly: OwinStartup(typeof(SelfHostConsole.Startup))]
namespace SelfHostConsole
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // 如需如何設定應用程式的詳細資訊,請瀏覽 https://go.microsoft.com/fwlink/?LinkID=316888
            // Configure Web API for self-host. 
            HttpConfiguration config = new HttpConfiguration();
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
            //Enable CORS
            //config.EnableCors(new EnableCorsAttribute("*", headers: "*", methods: "*"));
            app.UseWebApi(config);
        }
    }
}

TestController.cs

using System.Collections.Generic;
using System.Web.Http;

namespace SelfHostConsole
{
    public class TestController : ApiController
    {
        private static List<MyModel> list = new List<MyModel>()
        {
            new MyModel(){Name="name1", Value="value1"},
            new MyModel(){Name="name2", Value="value2"},
        };

        // GET api/test 
        public IEnumerable<MyModel> Get()
        {
            return list;
        }

        // GET api/test/1 
        public MyModel Get(int id)
        {
            if (id < 0 || id >= list.Count)
                return null;
            return list[id];
        }

        // POST api/test 
        public IEnumerable<MyModel> Post([FromBody] MyModel newData)
        {
            list.Add(newData);
            return list;
        }
    }

    public class MyModel
    {
        public string? Name { get; set; }
        public string? Value { get; set; }
    }
}

Program.cs(主控台.Net Framework)

using Microsoft.Owin.Hosting;
using OwinSelfhostSample;

namespace SelfHostConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            string baseAddress = "http://localhost:9000/";

            // Start OWIN host 
            using (WebApp.Start<Startup>(url: baseAddress))
            {
                // Create HttpClient and make a request to api/values 
                HttpClient client = new HttpClient();

                var response = client.GetAsync(baseAddress + "api/values").Result;

                Console.WriteLine(response);
                Console.WriteLine(response.Content.ReadAsStringAsync().Result);
                Console.ReadLine();
            }
        }
    }
}

MainWindow.xaml.cs (WPF NET6)

using DataBindingOneWay;
using Microsoft.Owin.Hosting;
using System;
using System.Windows;
using System.Windows.Controls;
using SelfHostConsole;
namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {  
        public MainWindow()
        {
            InitializeComponent();
            DataContext = Employee.GetEmployee();

            string baseAddress = "http://localhost:8080/";
            using (WebApp.Start<Startup>(baseAddress))
            {
                Console.WriteLine("Wait for a request ...");
                Console.ReadLine();
            }

        }
    }
}
柯柯 iT邦新手 2 級 ‧ 2023-03-16 08:40:47 檢舉
移到上面
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

0
JamesDoge
iT邦高手 1 級 ‧ 2023-03-15 09:04:47

問題可能出在 WPF NET6 中的 MainWindow.xaml.cs
using (WebApp.Start<Startup>(baseAddress)) 裡,您用 Console.ReadLine() 等待輸入,但在 WPF 應用程式中,您應該避免使用控制台 I/O。這可能導致 OWIN 自我託管 Web API 在收到請求時無法正確響應。

要解決這個問題,請將 OWIN 自我託管 Web API 啟動代碼移動到 MainWindow 類別的成員變量,並在應用程式關閉時處理 IDisposable。

以下是修改後的 MainWindow.xaml.cs:

using DataBindingOneWay;
using Microsoft.Owin.Hosting;
using System;
using System.Windows;
using SelfHostConsole;

namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, IDisposable
    {
        private IDisposable _webApp;

        public MainWindow()
        {
            InitializeComponent();
            DataContext = Employee.GetEmployee();

            string baseAddress = "http://localhost:8080/";
            _webApp = WebApp.Start<Startup>(baseAddress);
            Console.WriteLine("Wait for a request ...");
        }

        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);
            Dispose();
        }

        public void Dispose()
        {
            _webApp?.Dispose();
        }
    }
}
柯柯 iT邦新手 2 級 ‧ 2023-03-15 09:17:54 檢舉

一開始不用using的話 POSTMAN會卡在 SEND request 一直跑

public MainWindow()
{
    InitializeComponent();
    DataContext = Employee.GetEmployee();

    string baseAddress = "http://localhost:8080/";
    WebApp.Start<Startup>(baseAddress);
}

https://ithelp.ithome.com.tw/upload/images/20230315/20109961tpyQ5cMKNo.jpg

柯柯 iT邦新手 2 級 ‧ 2023-03-15 09:44:55 檢舉

目前找到另一個問題是 打開程式後 PING http://localhost:8080/ PING不到 所以是不是伺服器根本沒開到

我要發表回答

立即登入回答