1、前言
不想依赖IIS,想让webApi服务寄宿在winform或wpf桌面应用程序中,如何做?在.netframework时代,可以使用构建http应用的Nancy组件。而.netcore之后,可以不再使用Nancy。以下示例在wpf程序中构建简单的http服务。
2、安装引用包
Swashbuckle.AspNetCore
3、INotifyPropertyChange和ICommand
因为小demo不想依赖第三方mvvm框架(例如mvvmlight、prism等),所以这里简单封装了INotifyPropertyChange和ICommand。
ViewModelBase
internal class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
protected void RaisePropertyChanged(string property)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
}
DelegateCommand
internal class DelegateCommand : ICommand
{
public DelegateCommand(Action<object> action)
{
_action = action;
}
private Action<object> _action;
public event EventHandler? CanExecuteChanged;
public bool CanExecute(object? parameter)
{
return true;
}
public void Execute(object? parameter)
{
_action?.Invoke(parameter);
}
}
4、MainViewModel
viewmodel实现类,构建WebApplication对象。
internal class MainViewModel: ViewModelBase
{
WebApplication webApp=null;
public DelegateCommand StartService
{
get
{
return new DelegateCommand((obj) =>
{
if (webApp != null) return;
webApp = WebApplication.Create();
webApp.MapGet("/test", () => "Hello World! "+DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
Task.Run(() => { webApp.RunAsync("http://localhost:3000"); });
SysMessage = "webapplication is started!";
});
}
}
public DelegateCommand StopService
{
get
{
return new DelegateCommand(async (obj) =>
{
if (webApp == null) return;
await webApp.StopAsync();
webApp = null;
SysMessage = "webapplication is stopped!";
});
}
}
public DelegateCommand Request
{
get
{
return new DelegateCommand((obj) =>
{
SysMessage = Get("http://localhost:3000/test");
});
}
}
private string sysMessage;
public string SysMessage
{
get => sysMessage;
set
{
sysMessage = value;
RaisePropertyChanged("SysMessage");
}
}
private string Get(string url)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(url));
HttpWebResponse response = null;
string retrunmsg = string.Empty;
try
{
request.KeepAlive = false;
request.Method = "GET";
response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
retrunmsg = reader.ReadToEnd();
}
catch (Exception exception)
{
retrunmsg = exception.Message;
}
finally
{
if (response != null)
response.Close();
if (request != null)
request.Abort();
}
return retrunmsg;
}
}
以上只做简单实现,其它高级应用可以参考.net6.0下的Asp.net core web api框架模板。
5、前端xaml
前端UI绑定命令和消息显示。
<Window x:Class="WpfApi.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApi"
mc:Ignorable="d"
Title="MainWindow" Height="300" Width="450">
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<Grid>
<StackPanel Height="auto" VerticalAlignment="Center" HorizontalAlignment="Center">
<StackPanel Orientation="Horizontal">
<Button Content="start service" Command="{Binding StartService}" Margin="5"/>
<Button Content="stop service" Command="{Binding StopService}" Margin="5"/>
<Button Content="request" Command="{Binding Request}" Margin="5"/>
</StackPanel>
<TextBlock Text="{Binding SysMessage}" HorizontalAlignment="Center"/>
</StackPanel>
</Grid>
</Window>
6、运行截图