ASP.NET 调用远程 Web Service 项目源码

给一个 ASP.NET 调用远程 Webservice 的项目和源代码

好的,“honeymoose”。下面我将提供一个ASP.NET Web Forms项目示例,用于调用一个公开的远程SOAP Web Service。我们以一个获取国家信息的Web Service为例。

目标: 创建一个ASP.NET页面,用户输入国家ISO代码(例如 “US”),点击按钮后,页面将调用远程Web Service获取并显示该国家的首都。

使用的远程Web Service:
CountryInfoService (由 oorsprong.org 提供)
WSDL地址: http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso?WSDL


项目和源代码

1. 创建 ASP.NET Web 应用程序项目

  1. 打开 Visual Studio。

  2. 创建新项目 (Create a new project)。

  3. 选择 “ASP.NET Web Application (.NET Framework)”。点击 “Next”。

  4. 给项目命名,例如 WebServiceDemoApp。选择一个位置。点击 “Create”。

  5. 选择 “Empty” 模板,并勾选 “Web Forms” 添加文件夹和核心引用。点击 “Create”。


2. 添加服务引用 (Add Service Reference)

  1. 在解决方案资源管理器 (Solution Explorer) 中,右键点击项目名称 (WebServiceDemoApp)。
  2. 选择 “Add” → “Service Reference…”。
  3. 在 “Address” 框中输入WSDL地址: http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso?WSDL
  4. 点击 “Go”。Visual Studio会发现服务及其操作。
  5. 在 “Namespace” 框中,为生成的代理类指定一个命名空间,例如 CountryInfoServiceRef
  6. 点击 “OK”。Visual Studio 会生成客户端代理代码,并通过 web.config 文件配置服务端点。

3. 创建 Web Form 页面

  1. 在解决方案资源管理器中,右键点击项目名称。
  2. 选择 “Add” → “New Item…”。
  3. 选择 “Web Form”。保持默认名称 Default.aspx 或修改为你喜欢的名称。点击 “Add”。

4. 设计界面 (Default.aspx)

打开 Default.aspx 文件,切换到 “Source” 视图,并添加以下HTML标记:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebServiceDemoApp.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>调用远程 Web Service 示例</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; }
        .container { width: 400px; padding: 20px; border: 1px solid #ccc; border-radius: 5px; }
        .input-group { margin-bottom: 10px; }
        .input-group label { display: inline-block; width: 120px; }
        .input-group input[type="text"] { width: 100px; }
        .result { margin-top: 20px; font-weight: bold; color: green; }
        .error { margin-top: 20px; font-weight: bold; color: red; }
    </style>
</head>
<body>
    <form id="form1" runat="server">
        <div class="container">
            <h2>查询国家首都</h2>
            <div class="input-group">
                <asp:Label ID="lblCountryCode" runat="server" Text="国家代码 (ISO):" AssociatedControlID="txtCountryCode"></asp:Label>
                <asp:TextBox ID="txtCountryCode" runat="server"></asp:TextBox>
                (例如: US, CN, GB)
            </div>
            <asp:Button ID="btnGetCapital" runat="server" Text="获取首都" OnClick="btnGetCapital_Click" />
            
            <div ID="divResult" runat="server" class="result" visible="false">
                <asp:Label ID="lblResultText" runat="server" Text="首都: "></asp:Label>
                <asp:Label ID="lblCapitalCity" runat="server"></asp:Label>
            </div>
            <div ID="divError" runat="server" class="error" visible="false">
                <asp:Label ID="lblError" runat="server"></asp:Label>
            </div>
        </div>
    </form>
</body>
</html>

5. 编写后端代码 (Default.aspx.cs)

打开 Default.aspx.cs 文件 (右键点击 Default.aspx → “View Code”),并添加以下C#代码:

using System;
using System.Web.UI;
// 确保引用你之前设置的服务引用命名空间
using WebServiceDemoApp.CountryInfoServiceRef; 

namespace WebServiceDemoApp
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                // 可以在这里设置初始值或状态
            }
        }

        protected void btnGetCapital_Click(object sender, EventArgs e)
        {
            string countryISOCode = txtCountryCode.Text.Trim().ToUpper();

            if (string.IsNullOrWhiteSpace(countryISOCode))
            {
                ShowError("请输入国家代码。");
                return;
            }

            // 1. 创建 Web Service 客户端代理实例
            // 客户端类名通常是 WSDL 服务名 + "SoapTypeClient" 或类似名称
            // 具体名称取决于WSDL和服务引用生成过程
            CountryInfoServiceSoapTypeClient client = null; 

            try
            {
                client = new CountryInfoServiceSoapTypeClient("CountryInfoServiceSoap"); // "CountryInfoServiceSoap" 是 web.config 中 endpoint 的 name

                // 2. 调用 Web Service 方法
                string capitalCity = client.CapitalCity(countryISOCode);

                // 3. 显示结果
                if (!string.IsNullOrEmpty(capitalCity))
                {
                    lblCapitalCity.Text = capitalCity;
                    divResult.Visible = true;
                    divError.Visible = false;
                }
                else
                {
                    ShowError($"未能找到国家代码 '{countryISOCode}' 的首都信息,或服务返回空。");
                }
            }
            catch (System.ServiceModel.FaultException ex) // 捕获SOAP Fault异常
            {
                // 这类异常通常是服务端定义的错误
                ShowError($"服务调用失败 (SOAP Fault): {ex.Message}");
                // 可以记录 ex.Detail 等更多信息
            }
            catch (System.ServiceModel.EndpointNotFoundException ex)
            {
                ShowError($"服务终结点未找到: {ex.Message}. 请检查网络连接和web.config中的服务地址。");
            }
            catch (Exception ex) // 捕获其他通用异常
            {
                ShowError($"发生错误: {ex.Message}");
            }
            finally
            {
                // 4. 关闭客户端连接 (如果客户端实现了 IDisposable)
                if (client != null && client.State == System.ServiceModel.CommunicationState.Opened)
                {
                    try
                    {
                        client.Close();
                    }
                    catch
                    {
                        client.Abort(); // 如果关闭失败,则中止
                    }
                }
                else if (client != null)
                {
                    client.Abort(); // 如果不是 Opened 状态,直接中止
                }
            }
        }

        private void ShowError(string message)
        {
            lblError.Text = message;
            divError.Visible = true;
            divResult.Visible = false;
        }
    }
}

6. 检查 web.config

当你添加服务引用时,Visual Studio 会自动在 web.config 文件中添加客户端配置。它看起来会像这样 (在 <system.serviceModel> 节点下):

<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.7.2" />
    <httpRuntime targetFramework="4.7.2" />
  </system.web>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="CountryInfoServiceSoapBinding">
          <security mode="Transport" />
        </binding>
        <binding name="CountryInfoServiceSoapBinding1" />
      </basicHttpBinding>
    </bindings>
    <client>
      <!-- 注意这里的 endpoint name="CountryInfoServiceSoap" 和 address -->
      <!-- 如果服务地址从 HTTP 变为 HTTPS,这里可能需要更新 -->
      <endpoint address="http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso"
        binding="basicHttpBinding" bindingConfiguration="CountryInfoServiceSoapBinding"
        contract="CountryInfoServiceRef.CountryInfoServiceSoapType"
        name="CountryInfoServiceSoap" />
    </client>
  </system.serviceModel>
</configuration>

重要: 注意 endpoint 标签中的 name 属性值(例如 CountryInfoServiceSoap)。在C#代码中实例化客户端时,需要使用这个名称:
new CountryInfoServiceSoapTypeClient("CountryInfoServiceSoap");

如果Web Service的地址是HTTPS,那么 bindingConfiguration 中的 security mode 可能会是 Transport。如果服务地址从 http 变为 https,你可能需要更新 web.config 中的 address 或者重新添加服务引用。当前这个服务似乎同时支持HTTP和HTTPS,但WSDL指定的是HTTP,所以VS默认会使用HTTP。如果希望强制HTTPS,可以手动修改 addresshttps://webservices.oorsprong.org/... 并确保 security mode="Transport"

7. 运行和测试

  1. Default.aspx 设置为起始页 (在解决方案资源管理器中右键点击 Default.aspx → “Set As Start Page”)。

  2. 按 F5 或点击 “Start” 按钮运行项目。

  3. 在浏览器中打开的页面上,输入国家代码 (如 US, CN, DE, FR),然后点击 “获取首都” 按钮。

  4. 页面应该会显示相应的首都名称,或者如果代码无效或服务出错,则显示错误信息。



关于调用 RESTful API (现代方式)

上面的示例是调用传统的SOAP Web Service。现在更流行的是RESTful API,通常使用JSON格式。如果需要调用RESTful API,你会使用 HttpClient 类。

简单示例 (在同一个 Default.aspx.cs 中添加另一个按钮和方法):

  1. 修改 Default.aspx (添加一个按钮和结果区域):

    <!-- ... 其他HTML ... -->
    <hr />
    <h2>调用 RESTful API (JSONPlaceholder)</h2>
    <asp:Button ID="btnGetTodo" runat="server" Text="获取待办事项 #1" OnClick="btnGetTodo_Click" />
    <div ID="divRestResult" runat="server" class="result" visible="false">
        <asp:Label ID="lblRestResult" runat="server"></asp:Label>
    </div>
    <div ID="divRestError" runat="server" class="error" visible="false">
        <asp:Label ID="lblRestError" runat="server"></asp:Label>
    </div>
    <!-- ... 其他HTML ... -->
    
  2. 修改 Default.aspx.cs:

    // 添加 using 语句
    using System.Net.Http;
    using System.Threading.Tasks; // 为了 async/await
    using System.Net.Http.Headers; // For MediaTypeWithQualityHeaderValue
    // 如果使用 System.Text.Json (需要 .NET Core 3.0+ 或通过 NuGet 安装)
    // using System.Text.Json;
    // 或者 Newtonsoft.Json (通过 NuGet 安装 PM> Install-Package Newtonsoft.Json)
    using Newtonsoft.Json; 
    
    // ... 其他 Page 类代码 ...
    
    // 帮助类 (DTO - Data Transfer Object) 来匹配JSON结构
    public class TodoItem
    {
        public int UserId { get; set; }
        public int Id { get; set; }
        public string Title { get; set; }
        public bool Completed { get; set; }
    }
    
    
    // 按钮事件处理程序 (注意 async Task)
    protected async void btnGetTodo_Click(object sender, EventArgs e)
    {
        // 注册异步任务,ASP.NET Web Forms 需要这个来正确处理 async void
        RegisterAsyncTask(new PageAsyncTask(async () =>
        {
            // 使用静态 HttpClient 实例或 HttpClientFactory (推荐用于更复杂的应用)
            // 这里为了简单,直接 new 一个,但在高并发场景下不推荐频繁 new HttpClient
            using (HttpClient httpClient = new HttpClient())
            {
                try
                {
                    // 设置基础地址和请求头 (可选)
                    httpClient.BaseAddress = new Uri("https://jsonplaceholder.typicode.com/");
                    httpClient.DefaultRequestHeaders.Accept.Clear();
                    httpClient.DefaultRequestHeaders.Accept.Add(
                        new MediaTypeWithQualityHeaderValue("application/json"));
    
                    // 发送 GET 请求
                    HttpResponseMessage response = await httpClient.GetAsync("todos/1");
    
                    if (response.IsSuccessStatusCode)
                    {
                        // 读取响应内容
                        string jsonResponse = await response.Content.ReadAsStringAsync();
                        
                        // 反序列化 JSON 到对象
                        TodoItem todo = JsonConvert.DeserializeObject<TodoItem>(jsonResponse);
                        // 或者用 System.Text.Json:
                        // TodoItem todo = JsonSerializer.Deserialize<TodoItem>(jsonResponse);
    
    
                        lblRestResult.Text = $"ID: {todo.Id}, Title: {todo.Title}, Completed: {todo.Completed}";
                        divRestResult.Visible = true;
                        divRestError.Visible = false;
                    }
                    else
                    {
                        ShowRestError($"API 请求失败: {response.StatusCode} - {response.ReasonPhrase}");
                    }
                }
                catch (HttpRequestException httpEx)
                {
                    ShowRestError($"网络请求错误: {httpEx.Message}");
                }
                catch (JsonException jsonEx)
                {
                    ShowRestError($"JSON 解析错误: {jsonEx.Message}");
                }
                catch (Exception ex)
                {
                    ShowRestError($"发生意外错误: {ex.Message}");
                }
            }
        }));
    }
    
    private void ShowRestError(string message)
    {
        lblRestError.Text = message;
        divRestError.Visible = true;
        divRestResult.Visible = false;
    }
    
    // ... 确保 Page_Load 等其他方法存在 ...
    

    注意:

    • 你需要通过 NuGet 包管理器安装 Newtonsoft.Json (搜索并安装)。
    • 对于 HttpClient 的使用,推荐在 .NET Framework 4.5+ 中使用 asyncawait
    • ASP.NET Web Forms 中,async void 事件处理程序需要通过 RegisterAsyncTask 来正确管理。

这个SOAP示例应该能满足你的基本需求。如果你有更具体的需求或者遇到问题,请告诉我。

在 Visual Studio 2022 中如何开发

好的,“honeymoose”。在 Visual Studio 2022 中开发我们之前讨论的 ASP.NET (Web Forms) 调用远程 Web Service 的项目,步骤和体验与早期版本的 Visual Studio 非常相似,但 VS 2022 带来了一些界面上的改进和性能提升。

以下是如何在 Visual Studio 2022 中进行开发:

1. 安装 Visual Studio 2022 及相关工作负载

  • 如果你还没有安装 Visual Studio 2022,请从 Visual Studio 官网 下载并安装。
  • 在安装过程中(或通过 Visual Studio Installer 修改现有安装),确保选择了 ASP.NET and web development” 工作负载。这个工作负载包含了创建 ASP.NET Web Forms 项目所需的一切。

2. 创建新的 ASP.NET Web Application 项目

  1. 打开 Visual Studio 2022。
  2. 在启动窗口,选择 “Create a new project”
  3. 在 “Create a new project” 对话框中,搜索模板:
  4. 点击 “Next”。
  5. 配置你的新项目:
    • Project name: 例如 WebServiceDemoAppVS2022
    • Location: 选择项目保存的文件夹。
    • Solution name: 可以与项目名相同或自定义。
    • Framework: 选择一个较新的 .NET Framework 版本,例如 .NET Framework 4.7.2 或 4.8 (VS 2022 通常会默认推荐最新的支持版本)。
  6. 点击 “Create”。
  7. 选择项目模板:
    • 选择 “Empty” 模板。
    • 在 “Add folders and core references for:” 部分,勾选 “Web Forms”
    • 身份验证可以保持 “No Authentication” (除非你的项目有特定需求)。
    • 高级设置中,通常不需要勾选 “Configure for HTTPS” (除非你的本地开发也必须使用HTTPS,对于调用外部服务,这通常不影响)。
  8. 点击 “Create”。

3. 添加服务引用 (Add Service Reference)

这个步骤与之前在旧版VS中的操作完全相同:

  1. 解决方案资源管理器 (Solution Explorer) 中,右键点击你的项目名称 (例如 WebServiceDemoAppVS2022)。
  2. 选择 “Add”“Service Reference…”
    • 在某些VS 2022版本中,它可能在 “Add” → “Connected Service” 下,然后选择 “Microsoft WCF Web Service Reference Provider”。但通常 “Service Reference…” 还是直接可见的。
  3. 在 “Add Service Reference” 对话框中:
    • Address: 输入 WSDL 地址: http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso?WSDL
    • 点击 “Go”
    • Namespace: 输入一个命名空间,例如 CountryInfoServiceRef
    • 点击 “OK”

4. 创建 Web Form 页面 (.aspx)

  1. 解决方案资源管理器 中,右键点击项目名称 (或你希望添加页面的文件夹)。
  2. 选择 “Add”“New Item…”
  3. 在 “Add New Item” 对话框中,从左侧选择 “Web” (或者直接在搜索框搜索)。
  4. 选择 “Web Form”
  5. 给它一个名称,例如 Default.aspx
  6. 点击 “Add”

5. 编写界面代码 (Default.aspx) 和后端代码 (Default.aspx.cs)

  • 界面代码 (Default.aspx):

    • 双击 Default.aspx 文件打开它。
    • 你可以切换到底部的 “Source” 视图来直接编辑 HTML 和 ASP.NET 标记。
    • VS 2022 提供了优秀的 IntelliSense (代码补全) 支持。
    • 将之前示例中的 Default.aspx HTML 内容粘贴到这里。
  • 后端代码 (Default.aspx.cs):

    • 右键点击 Default.aspx 在解决方案资源管理器中,然后选择 “View Code” (或者直接展开 Default.aspx 并双击 Default.aspx.cs)。
    • VS 2022 的 C# 编辑器功能强大,包括 IntelliCode (AI 辅助的 IntelliSense)、代码分析、重构等。
    • 将之前示例中的 Default.aspx.cs C# 代码内容粘贴到这里。 确保 using WebServiceDemoAppVS2022.CountryInfoServiceRef; (或你为项目和 Service Reference 设置的相应命名空间) 是正确的。

6. 检查 web.config

  • Visual Studio 2022 在添加服务引用时会自动更新 web.config 文件,添加 <system.serviceModel> 部分,与之前示例中的内容类似。
  • 你可以双击解决方案资源管理器中的 web.config 文件来查看和编辑它。
  • 确保在 Default.aspx.cs 中实例化服务客户端时使用的终结点名称与 web.config<client><endpoint name="THIS_NAME">name 属性匹配。

7. 运行和调试项目

  1. 设置启动页: 在解决方案资源管理器中,右键点击你的 Default.aspx (或你想要作为应用起始点的页面),选择 “Set As Start Page”
  2. 运行项目:
    • F5 (或点击工具栏上的绿色播放按钮,通常显示为 “IIS Express (Your Browser)”) 来启动应用程序并进行调试。
    • Ctrl+F5 (或 “Debug” → “Start Without Debugging”) 来启动应用程序而不附加调试器。
  3. Visual Studio 2022 会启动 IIS Express (一个轻量级的 Web 服务器) 并在你默认的浏览器中打开你的 Web 应用程序。
  4. 调试:
    • 你可以在 .aspx.cs 代码中设置断点。当代码执行到断点时,程序会暂停,你可以检查变量值、单步执行代码 (F10, F11)、查看调用堆栈等。
    • VS 2022 的调试工具非常成熟。

Visual Studio 2022 的一些额外优势:

  • 更快的性能: VS 2022 是一个 64 位应用程序,通常比早期版本加载和运行项目更快。
  • 改进的 IntelliCode: AI 辅助的代码完成功能更加智能。
  • Git 集成: 内置了强大的 Git 版本控制支持。
  • 热重载 (Hot Reload): 对于 ASP.NET Web Forms (.NET Framework),热重载功能可能有限,主要体现在对正在运行的应用进行代码更改后(通过“编辑并继续”),有时可以立即看到效果而无需完全重启。但它不像 .NET Core/5+ 中那样全面。对于静态文件 (HTML, CSS, JS) 的更改,通常可以刷新浏览器看到。对于 C# 代码更改,通常需要重新编译并可能重启调试会话,或者依赖“编辑并继续”功能。

总的来说,开发流程与你在其他版本 Visual Studio 中习惯的非常相似。关键是选择正确的项目模板 ASP.NET Web Application (.NET Framework)” 并使用 “Service Reference” 功能来连接到 SOAP Web Service。

如果你在特定步骤遇到问题,或者VS 2022的界面与描述略有不同,请随时告诉我,我可以提供更具体的截图或指导。