WPF的数据源可以WebService或WCF也可以是WebApi,也可以直接连接数据库读取数据,WebService或WCF以及WebApi是绕开直接连接数据库通过Api接口应用程序操作数据。而WebApi提供了两种数据输出格式xml和json,本文演示“WPF与WebApi数据交互基础”,开发者需要对WPF项目基本的入门,以及ASP.NET的WebApi项目有基本的了解,本文不会全面展开介绍这两种项目基础,需要有大致了解后可以迅速上手本文的示例。
第一步:创建WPF项目,在Visual Studio中新建,选择项目类型“Windows 桌面”,再选择“WPF 应用”项目名称命名为“WebApiCall”,项目路径位置,根据情况选择盘符路径,框架版本:选择.NET FrameWork 4.7,点击确定创建了WPF项目,如下图:
创建完WPF项目后,默认建立了窗体MainWindow.xaml,后面读取操作WebApi数据就在默认的窗体中完成,WPF应用程序的准备工作已经就绪。
第二步:创建ASP.NET WebApi应用程序,同样在Visual Studio中新建项目,选择Web类型,选择ASP.NET Web应用程序,项目名命名为“CustomersManager”,框架版本:同样选择.NET FrameWork 4.7,应用程序类型:选择Web API,添加文件夹和核心引用,选择MVC和Web API。如下图:
WebApi项目创建之后,在Models文件目录中新建Customer和CustomerCenter类,Customer类属性字段分别为:public Int64 CustomerID ,public decimal Score , public int Rank ;CustomerCenter类主要用来处理数据集合,建立public IEnumerable<Customer> Customers()处理数据内容列表, public IEnumerable<Customer> CustomersByRank()加入排序修饰。下面是详细代码:
namespace CustomersManager.Models
{
/// <summary>
/// WPF与WebApi数据交互基础(08.06.2024)
/// Copyright (C) 遗昕传媒 | weisim3.com
/// </summary>
public class Customer
{
public Int64 CustomerID { get; set; }
public decimal Score { get; set; }
public int Rank { get; set; }
}
/// <summary>
/// WPF与WebApi数据交互基础(08.06.2024)
/// Copyright (C) 遗昕传媒 | weisim3.com
/// </summary>
public class CustomerCenter
{
/// <summary>
/// Customers data(XinSoft/昕软,Mr.Tang,09.30.202309.29.2023)
/// </summary>
public IEnumerable<Customer> Customers()
{
List<Customer> customers = new List<Customer>() {
new Customer(){ CustomerID=15514665,Score=99 },
new Customer(){ CustomerID=81546541,Score=126},
new Customer(){ CustomerID=1745431,Score=156},
new Customer(){ CustomerID=6144320,Score=93},
new Customer(){ CustomerID=11028481,Score=93},
new Customer(){ CustomerID=8009471,Score=93},
new Customer(){ CustomerID=38819,Score=92},
new Customer(){ CustomerID=5538819,Score=95},
new Customer(){ CustomerID=5630019,Score=94},
new Customer(){ CustomerID=76786448,Score=156}
};
return customers;
}
/// <summary>
/// CustomersByRank -> Customers ranks of scores Info(XinSoft/昕软,Mr.Tang,09.30.2023)
/// </summary>
///
public IEnumerable<Customer> CustomersByRank()
{
List<Customer> customers = new List<Customer>();
var OrderCustomer = Customers().OrderBy(c => c.CustomerID).OrderByDescending(c => c.Score);
int rank = 0;
foreach (var item in OrderCustomer)
{
rank++;
Customer customer = new Customer();
customer.CustomerID = item.CustomerID;
customer.Score = item.Score;
customer.Rank = rank;
customers.Add(customer);
}
return customers;
}
}
}
接着在Controllers控制器目录,打开“ValuesController.cs”WebApi控制器文件类,该文件在WebApi创建完成后自动创建,将默认的string类型的Get()方法修改成public IEnumerable<Customer> Get()用于调用 CustomerCenter类中CustomersByRank()数据排序列表。[Route("Customer")]路由指定为“ Customer”,代码如下:
CustomerCenter Customer = new CustomerCenter();
// GET api/values
[Route("Customer")]
public IEnumerable<Customer> Get()
{
//return new string[] { "value1", "value2" };
return Customer.CustomersByRank();
}
WebApi控制器文件数据引入和路由设置好之后,可以在浏览器中打开Customer路径下数据详细内容,在当期示例运行在浏览器中的地址为“http://localhost:54164/Customer”,运行结果如下图:
此时,WebApi的数据服务已经建立好,回到WPF项目,在项目中新建一个Customer类,这里的字段属性和WebApi的Models中的Customer类完全一直,用于承接WebApi的数据,所以保持一致。然后在MainWindow.xaml添加DataGrid数据控件用来显示数据列表。DataGrid命名为“CustomerList”,列属性对应Customer类的CustomerID、Rank、Score三个字段。如下代码:
<Window x:Class="WebApiCall.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:WebApiCall" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"><!--WPF与WebApi数据交互基础(08.06.2024) Copyright (C) 遗昕传媒 | weisim3.com-->
<Grid Name="PannelAll"> <DataGrid Name="CustomerList" AutoGenerateColumns="False" HorizontalAlignment="Left" Height="247" VerticalAlignment="Top" Width="{Binding ElementName=PannelAll, Path=ActualWidth}"> <DataGrid.Columns> <DataGridTextColumn x:Name="CustomerID" Binding="{Binding Path=CustomerID}" Header="CustomerID" Width="300"/> <DataGridTextColumn x:Name="Rank" Binding="{Binding Path=Rank}" Header="Rank"/> <DataGridTextColumn x:Name="Score" Binding="{Binding Path=Score}" Header="Score"/> </DataGrid.Columns> </DataGrid> </Grid> </Window>
窗体后台:在MainWindow.xaml.cs文件中的MainWindow()方法中,采用HttpClient client = new HttpClient(),通过JsonConvert.SerializeObject(customer)将数据Json序列化。HttpClient的BaseAddress读取Webapi的url地址,指定到Customer控制器方法路径上,最后DataGrid绑定序列化之后的数据。代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Newtonsoft.Json;
namespace WebApiCall
{
public partial class MainWindow : Window
{/// <summary>
/// WPF与WebApi数据交互基础(08.06.2024)
/// Copyright (C) 遗昕传媒 | weisim3.com
/// </summary> public MainWindow()
{
InitializeComponent();
HttpClient client = new HttpClient();
Customer customer = new Customer();
//string json = JsonConvert.SerializeObject(customer);
client.BaseAddress = new Uri("http://localhost:54164/");
client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync("Customer").Result;
if (response.IsSuccessStatusCode)
{var users = response.Content.ReadAsAsync<IEnumerable
<Customer>>().Result; else {
CustomerList.ItemsSource = users;
}MessageBox.Show("Error Code" + response.StatusCode + " : Message - " + response.ReasonPhrase);
}
}
}
}
效果如下:
项目目录说明与提示:下图:packages文件包是WebApi项目所需包文件,在下载文件中没有包含此文件夹,用户读者下载后创建WebApi项目会自动生成该文件夹。对应的配置在packages.config文件中,参考下面代码文件。
packages.config 代码 复制
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Antlr" version="3.5.0.2" targetFramework="net47" />
<package id="bootstrap" version="3.3.7" targetFramework="net47" />
<package id="jQuery" version="3.3.1" targetFramework="net47" />
<package id="Microsoft.AspNet.Mvc" version="5.2.4" targetFramework="net47" />
<package id="Microsoft.AspNet.Mvc.zh-Hans" version="5.2.4" targetFramework="net47" />
<package id="Microsoft.AspNet.Razor" version="3.2.4" targetFramework="net47" />
<package id="Microsoft.AspNet.Razor.zh-Hans" version="3.2.4" targetFramework="net47" />
<package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net47" />
<package id="Microsoft.AspNet.Web.Optimization.zh-Hans" version="1.1.3" targetFramework="net47" />
<package id="Microsoft.AspNet.WebApi" version="5.2.4" targetFramework="net47" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.4" targetFramework="net47" />
<package id="Microsoft.AspNet.WebApi.Client.zh-Hans" version="5.2.4" targetFramework="net47" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.4" targetFramework="net47" />
<package id="Microsoft.AspNet.WebApi.Core.zh-Hans" version="5.2.4" targetFramework="net47" />
<package id="Microsoft.AspNet.WebApi.HelpPage" version="5.2.4" targetFramework="net47" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.4" targetFramework="net47" />
<package id="Microsoft.AspNet.WebApi.WebHost.zh-Hans" version="5.2.4" targetFramework="net47" />
<package id="Microsoft.AspNet.WebPages" version="3.2.4" targetFramework="net47" />
<package id="Microsoft.AspNet.WebPages.zh-Hans" version="3.2.4" targetFramework="net47" />
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="2.0.0" targetFramework="net47" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net47" />
<package id="Modernizr" version="2.8.3" targetFramework="net47" />
<package id="Newtonsoft.Json" version="11.0.1" targetFramework="net47" />
<package id="WebGrease" version="1.6.0" targetFramework="net47" />
</packages>
packages.config不同系统版本或.net版本,以及Visual Studio版本都会有版本差异,这部分仅作为提示内容,不是本文的关键重点。