You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#的WPF/Windows Store应用中通过WebService读写SQL Server图片

实现WPF/Windows Store通过Web服务检索SQL Server图片并显示到Image控件

我来帮你完善这个从SQL Server取图片、通过Web服务传输,最终在WPF/Windows Store应用的Image控件显示的完整流程。你的现有代码已经有了开头,我们把它补全并优化,同时覆盖客户端的实现。

一、Web服务端完善

首先你需要定义一个Customer实体类,用来封装返回给客户端的数据——这里我们把图片转换成Base64字符串(相比直接传二进制,Base64在Web服务中更易处理):

public class Customer
{
    public int ID { get; set; }
    public string PictureBase64 { get; set; } // 用Base64格式存储图片数据
    public string Customer_Name { get; set; }
    public string Contact_No { get; set; }
    public DateTime Time_In { get; set; }
}

然后补全你的Web服务方法,处理数据库查询和图片转换:

[WebMethod]
public List<Customer> GetRecentUnsoldCustomers()
{
    List<Customer> customerList = new List<Customer>();
    Connection con = new Connection();
    
    try
    {
        con.Start();
        // 保留你的原查询逻辑,注意Date字段需为日期类型
        string query = @"Select ID,Picture, Customer_Name, Contact_No, Time_In 
                         from Customers_Data 
                         WHERE ( Date >= dateadd(day,datediff(day,7,GETDATE()),0) 
                                 AND Date < dateadd(day,datediff(day,0,GETDATE()),1)) 
                               And (Sale_Made='No')";
        DataTable dt = con.Select(query);
        
        foreach(DataRow row in dt.Rows)
        {
            Customer customer = new Customer();
            customer.ID = Convert.ToInt32(row["ID"]);
            customer.Customer_Name = row["Customer_Name"].ToString();
            customer.Contact_No = row["Contact_No"].ToString();
            customer.Time_In = Convert.ToDateTime(row["Time_In"]);
            
            // 处理数据库中的二进制图片,转为Base64
            if(row["Picture"] != DBNull.Value)
            {
                byte[] imageBytes = (byte[])row["Picture"];
                customer.PictureBase64 = Convert.ToBase64String(imageBytes);
            }
            
            customerList.Add(customer);
        }
    }
    catch(Exception ex)
    {
        // 建议添加日志记录,这里直接抛出便于客户端排查
        throw new Exception("获取客户数据失败: " + ex.Message);
    }
    finally
    {
        con.Stop();
    }
    
    return customerList;
}

二、WPF客户端实现

1. XAML布局

先在XAML里定义显示客户列表和图片的UI:

<Window x:Class="WpfImageDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="未成交客户列表" Height="450" Width="800">
    <Grid>
        <ListBox x:Name="CustomerList" Margin="10">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal" Padding="5">
                        <!-- 显示图片 -->
                        <Image Width="120" Height="120" Source="{Binding CustomerImage}" 
                               Stretch="UniformToFill" Margin="0,0,10,0"/>
                        <!-- 显示客户信息 -->
                        <StackPanel>
                            <TextBlock Text="{Binding Customer_Name}" FontSize="16" FontWeight="Bold"/>
                            <TextBlock Text="{Binding Contact_No}" Margin="0,2,0,0"/>
                            <TextBlock Text="{Binding Time_In, StringFormat='到店时间: {0:yyyy/MM/dd HH:mm}'}" 
                                       Margin="0,2,0,0" Foreground="Gray"/>
                        </StackPanel>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>

2. 代码后台处理

添加Web服务引用后,在代码后台获取数据并把Base64转成WPF能识别的BitmapImage:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Media.Imaging;
// 替换成你的Web服务引用命名空间
using WpfImageDemo.MyWebService;

namespace WpfImageDemo
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            // 异步加载数据,避免阻塞UI
            LoadCustomerDataAsync();
        }

        private async void LoadCustomerDataAsync()
        {
            try
            {
                // 实例化Web服务代理
                using(var client = new Service1SoapClient())
                {
                    List<Customer> customers = await client.GetRecentUnsoldCustomersAsync();
                    
                    // 转换为本地ViewModel,方便绑定图片
                    var viewModels = customers.Select(c => new CustomerViewModel
                    {
                        Customer_Name = c.Customer_Name,
                        Contact_No = c.Contact_No,
                        Time_In = c.Time_In,
                        CustomerImage = ConvertBase64ToBitmapImage(c.PictureBase64)
                    }).ToList();
                    
                    CustomerList.ItemsSource = viewModels;
                }
            }
            catch(Exception ex)
            {
                MessageBox.Show($"加载数据失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        // 将Base64字符串转为BitmapImage
        private BitmapImage ConvertBase64ToBitmapImage(string base64String)
        {
            if(string.IsNullOrEmpty(base64String))
                return null;
                
            byte[] imageBytes = Convert.FromBase64String(base64String);
            using(var ms = new MemoryStream(imageBytes))
            {
                BitmapImage bitmap = new BitmapImage();
                bitmap.BeginInit();
                bitmap.CacheOption = BitmapCacheOption.OnLoad; // 确保流关闭后图片仍可用
                bitmap.StreamSource = ms;
                bitmap.EndInit();
                return bitmap;
            }
        }
    }

    // 本地ViewModel类,用于UI绑定
    public class CustomerViewModel
    {
        public string Customer_Name { get; set; }
        public string Contact_No { get; set; }
        public DateTime Time_In { get; set; }
        public BitmapImage CustomerImage { get; set; }
    }
}

三、Windows Store应用客户端实现

Windows Store应用的逻辑和WPF类似,只是图片转换的API略有不同:

1. 图片转换方法

private async Task<BitmapImage> ConvertBase64ToBitmapImageAsync(string base64String)
{
    if(string.IsNullOrEmpty(base64String))
        return null;
        
    byte[] imageBytes = Convert.FromBase64String(base64String);
    using(var ms = new InMemoryRandomAccessStream())
    {
        await ms.WriteAsync(imageBytes.AsBuffer());
        ms.Seek(0);
        
        BitmapImage image = new BitmapImage();
        await image.SetSourceAsync(ms);
        return image;
    }
}

2. 数据加载逻辑

private async void Page_Loaded(object sender, RoutedEventArgs e)
{
    try
    {
        using(var client = new MyWebService.Service1SoapClient())
        {
            var customers = await client.GetRecentUnsoldCustomersAsync();
            var viewModels = new ObservableCollection<CustomerViewModel>();
            
            foreach(var c in customers)
            {
                viewModels.Add(new CustomerViewModel
                {
                    Customer_Name = c.Customer_Name,
                    Contact_No = c.Contact_No,
                    Time_In = c.Time_In,
                    CustomerImage = await ConvertBase64ToBitmapImageAsync(c.PictureBase64)
                });
            }
            
            CustomerListView.ItemsSource = viewModels;
        }
    }
    catch(Exception ex)
    {
        await new MessageDialog($"加载失败: {ex.Message}").ShowAsync();
    }
}

四、关键注意事项

  • 数据库字段类型:确保SQL Server中Picture字段是varbinary(max)类型,适合存储图片二进制数据。
  • 性能优化:如果图片较大,建议先压缩图片再存储/传输,Base64会比原二进制大33%左右,大图片可能影响传输速度。
  • 异步处理:客户端一定要用异步方法调用Web服务,避免UI线程阻塞导致应用假死。
  • 异常处理:在Web服务和客户端都要添加完善的异常捕获,方便排查问题。
  • Windows Store权限:在Package.appxmanifest中开启Internet (Client)权限,确保应用能访问Web服务。

内容的提问来源于stack exchange,提问作者shahzad_Ali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:03:49