V1.0 SDK 到 V2.0 SDK迁移指南

更新时间:
复制 MD 格式

将现有.NET应用从V1.0 SDK迁移至V2.0 SDK时,需要调整依赖包、客户端和接口调用代码。本文对照两个版本的用法,说明迁移方式以及超时、HTTPS、代理、重试和异常处理的配置差异。

适用范围

本文适用于使用V1.0 .NET SDK的开发者。V1.0、V2.0表示SDK的架构版本,不等同于NuGet包的版本号。

运行本文“迁移说明”中的代码示例前,安装.NET SDK并配置访问凭据。配置访问凭据参考管理访问凭证。调用接口的身份还需具备相应权限。

重要

V1.0 SDK 即将逐步停止维护,后续将不再提供功能更新与问题修复。V2.0 SDK 目前处于持续维护与迭代中,我们强烈建议您尽早完成迁移,以获得更好的功能支持与长期保障。

V2.0 SDK的主要变化

V2.0 SDK由领域特定语言(DSL)Darabonba生成,主要变化如下:

  • V1.0 SDK依赖SDK Core(aliyun-net-sdk-core)处理OpenAPI请求。V2.0 SDK通过DSL表达参数处理、请求组装和响应处理等逻辑,不再依赖V1.0的SDK Core包。

  • 业务参数与运行时参数分离。业务参数通过Request对象设置,直接初始化该对象即可,无需调用单独的函数生成;超时、代理等参数通过RuntimeOptions设置。

  • 每个云产品SDK提供独立的Client。可以按产品分别配置访问凭据、地域、超时、代理和重试参数,避免不同产品混用客户端配置。

迁移说明

迁移时,需要调整依赖包、客户端初始化和接口调用代码,并检查原有运行时配置。以下示例以云服务器ECS为主。

说明

各示例独立使用。含Main方法的示例展示完整程序结构;仅含CreateClient方法或配置语句的示例属于代码片段,需要放入现有项目。运行前替换尖括号占位符,不要将多个示例的Main方法合并。

SDK依赖

V1.0 SDK

V1.0云产品SDK提供Request、Response和响应反序列化对象。OpenAPI请求的主要逻辑集中在SDK Core中,包括访问凭据、HTTP请求、认证信息、签名算法和异常处理等。以ECS为例,在项目目录中执行以下命令:

# 包括访问凭据、对OpenAPI的HTTP请求、认证信息、签名算法、异常处理等
dotnet add package aliyun-net-sdk-core

# 云产品SDK,命名:aliyun-net-sdk-${产品名}
dotnet add package aliyun-net-sdk-ecs

V2.0 SDK

V2.0云产品SDK包含接口的参数处理、请求组装和响应处理逻辑,实现了与V1.0 SDK Core包的解耦。使用云产品SDK时,只需关注云产品本身的SDK包依赖。以ECS为例:

dotnet add package AlibabaCloud.SDK.Ecs20140526

配置客户端和请求

初始化客户端

V1.0 SDK

V1.0 SDK使用SDK Core中的DefaultAcsClient处理不同产品的请求。初始化时传入地域配置和访问凭据。Endpoint相关配置详见配置Endpoint。

using System;
using Aliyun.Acs.Core;
using Aliyun.Acs.Core.Profile;
using Aliyun.Acs.Core.Auth;

namespace AlibabaCloud.SDK.Sample
{
    class Program
    {
        static void Main(string[] args)
        {
            AlibabaCloudCredentialsProvider provider = new AccessKeyCredentialProvider(
                Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_ID"),
                Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
            // 传入地域配置和访问凭据。
            IClientProfile profile = DefaultProfile.GetProfile("cn-hangzhou");
            DefaultAcsClient client = new DefaultAcsClient(profile, provider);
        }
    }
}
重要

单Client的模式存在线程不安全的问题,且在不同产品之间混用一个profile信息,容易造成权限管理问题,因此强烈建议您迁移到V2.0 SDK。

V2.0 SDK

V2.0 SDK支持特化调用和泛化调用两种方式,客户端初始化方式分别为:

  1. 特化调用:每个产品维护各自的Client,各个产品互不影响,但相同配置也可以共用,例如config.Credential = '指向同一个CredentialsClient'。

    // 客户端初始化方法片段;由调用方调用CreateClient。
    using System;
    
    namespace AlibabaCloud.SDK.Sample
    {
        public class Sample
        {
            public static AlibabaCloud.SDK.Ecs20140526.Client CreateClient()
            {
                Aliyun.Credentials.Client credential = new Aliyun.Credentials.Client();
                AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config
                {
                    Credential = credential,
                };
                config.Endpoint = "ecs.cn-hangzhou.aliyuncs.com";
                return new AlibabaCloud.SDK.Ecs20140526.Client(config);
            }
        }
    }
  2. 泛化调用:无需安装产品SDK(例如AlibabaCloud.SDK.Ecs20140526),但需要安装核心库AlibabaCloud.OpenApiClient,使用AlibabaCloud.OpenApiClient.Client手动配置接口信息。以下示例使用Credentials工具初始化访问凭据,详情请参见管理访问凭据。

    dotnet add package AlibabaCloud.OpenApiClient
    // 客户端初始化方法片段;由调用方调用CreateClient。
    using System;
    
    namespace AlibabaCloud.SDK.Sample
    {
        public class Sample
        {
            public static AlibabaCloud.OpenApiClient.Client CreateClient()
            {
                Aliyun.Credentials.Client credential = new Aliyun.Credentials.Client();
                AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config
                {
                    Credential = credential,
                };
                config.Endpoint = "ecs.cn-hangzhou.aliyuncs.com";
                return new AlibabaCloud.OpenApiClient.Client(config);
            }
        }
    }

客户端初始化完成后,使用云产品客户端的方法或通用客户端的CallApi方法发起请求。请求客户端对象无需手动销毁,会自动被垃圾回收机制回收。

说明

不同产品使用不同访问凭据时,分别初始化客户端,避免混用配置。不要在请求执行期间修改共享的配置对象。

配置Endpoint

Endpoint是OpenAPI的服务接入域名,例如ecs.cn-hangzhou.aliyuncs.com。选择与目标产品、地域和网络类型匹配的Endpoint。

重要

在完成 Endpoint 配置迁移后,请务必仔细核对 V1.0 与 V2.0 版本的 Endpoint 地址是否完全一致,若存在差异,可能导致接口调用失败或请求被错误路由。

V1.0 SDK

V1.0 SDK的Endpoint设置方式优先级从高到低为:自定义Endpoint > 云产品SDK寻址 > SDK Core寻址 > Location服务寻址。

  1. 自定义Endpoint:

    1. 优先级最高,只对当前Request生效。调用request.SetEndpoint。

      using System;
      using Aliyun.Acs.Core;
      using Aliyun.Acs.Core.Profile;
      using Aliyun.Acs.Core.Auth;
      using Aliyun.Acs.Ecs.Model.V20140526;
      
      namespace AlibabaCloud.SDK.Sample
      {
          class Program
          {
              static void Main(string[] args)
              {
                  AlibabaCloudCredentialsProvider provider = new AccessKeyCredentialProvider(
                      Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_ID"),
                      Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
                  IClientProfile profile = DefaultProfile.GetProfile("cn-hangzhou");
                  DefaultAcsClient client = new DefaultAcsClient(profile, provider);
                  var request = new DescribeRegionsRequest();
                  request.Protocol = Aliyun.Acs.Core.Http.ProtocolType.HTTPS;
      
                  // 仅对当前请求生效。
                  request.SetEndpoint("<Endpoint>");
                  var response = client.GetAcsResponse(request);
                  Console.WriteLine(System.Text.Encoding.Default.GetString(response.HttpResponse.Content));
              }
          }
      }
    2. 全局生效,支持添加多个Endpoint。调用profile.AddEndpoint,按产品和地域添加映射。

      using System;
      using Aliyun.Acs.Core;
      using Aliyun.Acs.Core.Profile;
      using Aliyun.Acs.Core.Auth;
      using Aliyun.Acs.Ecs.Model.V20140526;
      
      namespace AlibabaCloud.SDK.Sample
      {
          class Program
          {
              static void Main(string[] args)
              {
                  AlibabaCloudCredentialsProvider provider = new AccessKeyCredentialProvider(
                      Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_ID"),
                      Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
                  IClientProfile profile = DefaultProfile.GetProfile("cn-hangzhou");
                  // 全局生效。
                  profile.AddEndpoint("cn-hangzhou", "cn-hangzhou", "Ecs", "ecs.cn-hangzhou.aliyuncs.com");
                  // 按需添加其他产品、地域的Endpoint映射。
      
                  DefaultAcsClient client = new DefaultAcsClient(profile, provider);
                  var request = new DescribeRegionsRequest();
                  request.Protocol = Aliyun.Acs.Core.Http.ProtocolType.HTTPS;
                  var response = client.GetAcsResponse(request);
                  Console.WriteLine(System.Text.Encoding.Default.GetString(response.HttpResponse.Content));
              }
          }
      }
  2. 云产品SDK寻址。

    未设置自定义Endpoint时,如果云产品中存在内置的Endpoint文件(例如ECS的Endpoint.cs),则按照下列逻辑寻址:

    1. 优先使用公网请求:如果产品网络访问方式为public(request.ProductNetwork = "public",默认值为public),且Endpoint文件中包含传入的RegionId,则根据RegionId在云产品SDK的内置Endpoint映射中自动寻址。

    2. 若ProductNetwork非public,或内置Endpoint映射中不存在传入的RegionId,则根据规则自动拼接Endpoint:[product_code][-suffix]?[-productNetwork]?.[region_id]?.aliyuncs.com,其中方括号部分是否出现取决于产品的寻址规则。

    using System;
    using Aliyun.Acs.Core;
    using Aliyun.Acs.Core.Profile;
    using Aliyun.Acs.Core.Auth;
    using Aliyun.Acs.Ecs.Model.V20140526;
    
    namespace AlibabaCloud.SDK.Sample
    {
        class Program
        {
            static void Main(string[] args)
            {
                AlibabaCloudCredentialsProvider provider = new AccessKeyCredentialProvider(
                    Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_ID"),
                    Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
                // 设置地域ID,此处以“cn-shanghai”为例。
                IClientProfile profile = DefaultProfile.GetProfile("cn-shanghai");
                DefaultAcsClient client = new DefaultAcsClient(profile, provider);
                var request = new DescribeRegionsRequest();
                request.Protocol = Aliyun.Acs.Core.Http.ProtocolType.HTTPS;
                // 设置网络访问方式,默认public表示公网。
                // 其他网络标识包括share、ipv6、proxy、inner、dualstack和vpc,需确认目标产品支持。
                request.ProductNetwork = "public";
                // 使用VPC接入时,也可以根据产品支持情况配置以下选项。
                // profile.EnableUsingVpcEndpoint();
                var response = client.GetAcsResponse(request);
                Console.WriteLine(System.Text.Encoding.Default.GetString(response.HttpResponse.Content));
            }
        }
    }
  3. SDK Core寻址。

    若云产品SDK未提供内置Endpoint映射,则根据RegionId在SDK Core中的endpoints.json进行寻址:优先从其中的云产品Endpoint中寻址;若未匹配到结果,则根据云产品的productCode在global endpoints中寻址。

  4. 调用Location服务寻址。

    说明

    不是所有的云产品都支持此寻址模式,建议使用自定义Endpoint的方式。

    SDK Core仍未找到Endpoint时,使用serviceCode和regionId调用Location服务。

    • serviceCode:由云产品SDK的Request对象提供,无需手动设置。

    • regionId:初始化客户端时指定的地域ID。

V2.0 SDK

说明

并非所有云产品SDK都支持按RegionId自动寻址。不确定产品是否支持时,自定义Endpoint。

V2.0 SDK只支持自定义设置Endpoint的方式,优先级从高到低为:自定义Endpoint(Config.Endpoint)> 自定义RegionId(Config.RegionId)。

  1. 自定义Endpoint:在初始化客户端时设置Config.Endpoint。产品接入域名可以在OpenAPI开发者门户的产品主页查看。

    // 客户端初始化方法片段;由调用方调用CreateClient。
    using System;
    
    namespace AlibabaCloud.SDK.Sample
    {
        public class Sample
        {
            public static AlibabaCloud.SDK.Ecs20140526.Client CreateClient()
            {
                Aliyun.Credentials.Client credential = new Aliyun.Credentials.Client();
                AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config
                {
                    Credential = credential,
                };
                // 设置Endpoint,域名以产品接入点列表为准。
                config.Endpoint = "ecs.cn-hangzhou.aliyuncs.com";
                return new AlibabaCloud.SDK.Ecs20140526.Client(config);
            }
        }
    }
  2. 自定义RegionId:

    1. 若云产品Client中存在RegionId和Endpoint关系对象_endpointMap(例如:Client.cs),则从该对象中通过RegionId获取对应的Endpoint。

    2. 若云产品Client中没有该对象,或者传入的RegionId在该对象中没有对应的Endpoint映射时,则根据拼接规则自动拼接Endpoint。

    // 客户端初始化方法片段;由调用方调用CreateClient。
    using System;
    
    namespace AlibabaCloud.SDK.Sample
    {
        public class Sample
        {
            public static AlibabaCloud.SDK.Ecs20140526.Client CreateClient()
            {
                Aliyun.Credentials.Client credential = new Aliyun.Credentials.Client();
                AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config
                {
                    Credential = credential,
                };
                // 自定义RegionId,由SDK解析对应的Endpoint。
                config.RegionId = "cn-hangzhou";
                return new AlibabaCloud.SDK.Ecs20140526.Client(config);
            }
        }
    }

进阶配置

HTTPS配置

通过HTTPS调用OpenAPI时,SDK默认校验SSL/TLS证书。环境缺少受信任证书时,可能导致校验失败。为保障生产环境通信安全,建议您保持开启。

警告

关闭证书校验会失去服务端身份验证,存在中间人攻击风险。以下忽略证书校验的配置仅限隔离测试环境,不用于生产环境。

V1.0 SDK

通过Request对象的Protocol属性指定HTTPS。以下为请求配置片段:

// 请求配置片段:request为已创建的Request对象。
request.Protocol = Aliyun.Acs.Core.Http.ProtocolType.HTTPS;

若在隔离测试环境确需忽略证书校验,使用以下配置片段。生产环境中强烈建议您保持开启。

// 仅限隔离测试环境;client和request为已创建的对象。
// 客户端级配置。
client.SetHttpsInsecure(true);

// 请求级配置。
request.SetHttpsInsecure(true);

V2.0 SDK

V2.0 SDK对OpenAPI的请求协议设置方式为:Config设置 > 默认,优先级依次降低。通过Config.Protocol设置客户端的请求协议;未设置时,使用OpenAPI默认支持的协议类型(HTTPS)。以下示例显式设置为HTTPS。

using System;
using AlibabaCloud.OpenApiClient.Models;
using AlibabaCloud.SDK.Ecs20140526.Models;

class Sample
{
    static void Main(string[] args)
    {
        Config config = new Config
        {
            Credential = new Aliyun.Credentials.Client(),
            Endpoint = "ecs.cn-hangzhou.aliyuncs.com"
        };
        config.Protocol = "HTTPS";
        AlibabaCloud.SDK.Ecs20140526.Client client = new AlibabaCloud.SDK.Ecs20140526.Client(config);
        DescribeInstancesRequest request = new DescribeInstancesRequest
        {
            RegionId = "cn-hangzhou"
        };
        var response = client.DescribeInstances(request);
        Console.WriteLine(response.Body.TotalCount);
    }
}

若在隔离测试环境确需忽略证书校验,将当前请求的RuntimeOptions.IgnoreSSL设置为true。生产环境中强烈建议您保持开启。

using System;
using AlibabaCloud.OpenApiClient.Models;
using AlibabaCloud.SDK.Ecs20140526.Models;
using AlibabaCloud.TeaUtil.Models;

class Sample
{
    static void Main(string[] args)
    {
        Config config = new Config
        {
            Credential = new Aliyun.Credentials.Client(),
            Endpoint = "ecs.cn-hangzhou.aliyuncs.com"
        };
        config.Protocol = "HTTPS";
        AlibabaCloud.SDK.Ecs20140526.Client client = new AlibabaCloud.SDK.Ecs20140526.Client(config);

        // 仅限隔离测试环境;生产环境不设置IgnoreSSL = true。
        RuntimeOptions runtime = new RuntimeOptions
        {
            IgnoreSSL = true
        };
        DescribeInstancesRequest request = new DescribeInstancesRequest
        {
            RegionId = "cn-hangzhou"
        };
        var response = client.DescribeInstancesWithOptions(request, runtime);
        Console.WriteLine(response.Body.TotalCount);
    }
}

代理配置

V1.0 SDK

V1.0 SDK优先使用客户端中设置的代理地址,未设置时读取代理环境变量。

支持的代理环境变量如下:

  • HTTP_PROXY或http_proxy:HTTP请求的代理地址。

  • HTTPS_PROXY或https_proxy:HTTPS请求的代理地址。

  • NO_PROXY或no_proxy:不经过代理的地址。

客户端级代理配置示例:

using System;
using Aliyun.Acs.Core;
using Aliyun.Acs.Core.Profile;
using Aliyun.Acs.Core.Auth;

namespace AlibabaCloud.SDK.Sample
{
    class Program
    {
        static void Main(string[] args)
        {
            // 运行前配置AccessKey环境变量。
            AlibabaCloudCredentialsProvider provider = new AccessKeyCredentialProvider(
                Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_ID"),
                Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
            IClientProfile profile = DefaultProfile.GetProfile("cn-hangzhou");
            DefaultAcsClient client = new DefaultAcsClient(profile, provider);
            // 客户端级代理配置优先于环境变量。
            // 设置HTTP请求代理。
            client.SetHttpProxy("http://localhost:8080");
            // 获取HTTP请求代理。
            client.GetHttpProxy();

            // 设置HTTPS请求代理。
            client.SetHttpsProxy("https://localhost:8080");
            // 代理需要认证时,用以下配置替换上一行。
            // client.SetHttpsProxy("http://<username>:<password>@localhost:8080");
            // 获取HTTPS请求代理。
            client.GetHttpsProxy();

            // 设置不经过代理的地址。
            client.SetNoProxy("example.com");
            // 获取不经过代理的地址。
            client.GetNoProxy();
        }
    }
}

V2.0 SDK

V2.0 SDK优先使用请求的RuntimeOptions代理配置,其次使用Config中的客户端代理配置。

  1. 请求级配置:通过RuntimeOptions设置当前请求使用的代理。

    using System;
    using AlibabaCloud.TeaUtil.Models;
    
    namespace demo
    {
        public class Sample
        {
            static void Main(string[] args)
            {
                var ecsConfig = new AlibabaCloud.OpenApiClient.Models.Config
                {
                    // 从环境变量中获取AccessKey ID值。
                    AccessKeyId = Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_ID"),
                    // 从环境变量中获取AccessKey Secret值。
                    AccessKeySecret = Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_SECRET"),
                    Endpoint = "ecs.cn-beijing.aliyuncs.com"
                };
    
                var ecsClient = new AlibabaCloud.SDK.Ecs20140526.Client(ecsConfig);
                var describeRegionsRequest = new AlibabaCloud.SDK.Ecs20140526.Models.DescribeRegionsRequest();
                // 运行时配置仅对传入该对象的调用生效。
                var runtimeOptions = new RuntimeOptions();
                runtimeOptions.HttpProxy = "http://127.0.0.1:9898";
                runtimeOptions.HttpsProxy = "http://<username>:<password>@127.0.0.1:8989";
                runtimeOptions.NoProxy = "127.0.0.1,localhost";
    
                var response = ecsClient.DescribeRegionsWithOptions(describeRegionsRequest, runtimeOptions);
                Console.WriteLine(response.Body.ToMap());
            }
        }
    }
  2. 客户端级配置:通过Config设置客户端使用的代理。

    using System;
    using AlibabaCloud.TeaUtil.Models;
    
    namespace demo
    {
        public class Sample
        {
            static void Main(string[] args)
            {
                var ecsConfig = new AlibabaCloud.OpenApiClient.Models.Config
                {
                    // 从环境变量中获取AccessKey ID值。
                    AccessKeyId = Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_ID"),
                    // 从环境变量中获取AccessKey Secret值。
                    AccessKeySecret = Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_SECRET"),
                    Endpoint = "ecs.cn-beijing.aliyuncs.com",
                    // 客户端级代理配置。
                    NoProxy = "127.0.0.1,localhost",
                    HttpProxy = "http://127.0.0.1:9898",
                    HttpsProxy = "http://<username>:<password>@127.0.0.1:8989"
                };
    
                var ecsClient = new AlibabaCloud.SDK.Ecs20140526.Client(ecsConfig);
                var describeRegionsRequest = new AlibabaCloud.SDK.Ecs20140526.Models.DescribeRegionsRequest();
                var runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();
    
                var response = ecsClient.DescribeRegionsWithOptions(describeRegionsRequest, runtime);
                Console.WriteLine(response.Body.ToMap());
            }
        }
    }

超时配置

V1.0 SDK

V1.0 SDK超时配置优先级从高到低为:Request设置 > Client设置 > 默认配置。默认连接超时为5秒,读超时为10秒。以下示例显式设置两个级别的超时,单位为毫秒。

using System;
using Aliyun.Acs.Core;
using Aliyun.Acs.Core.Auth;
using Aliyun.Acs.Core.Profile;
using Aliyun.Acs.Ecs.Model.V20140526;

class Sample
{
    static void Main(string[] args)
    {
        AlibabaCloudCredentialsProvider provider = new AccessKeyCredentialProvider(
            Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_ID"),
            Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        IClientProfile profile = DefaultProfile.GetProfile("cn-hangzhou");
        DefaultAcsClient client = new DefaultAcsClient(profile, provider);
        // 客户端级超时,单位为毫秒。
        client.SetConnectTimeoutInMilliSeconds(1024);
        client.SetReadTimeoutInMilliSeconds(2048);

        // 请求级设置优先于客户端级设置。
        DescribeInstancesRequest request = new DescribeInstancesRequest();
        request.RegionId = "cn-hangzhou";
        request.Protocol = Aliyun.Acs.Core.Http.ProtocolType.HTTPS;
        request.SetConnectTimeoutInMilliSeconds(1024);
        request.SetReadTimeoutInMilliSeconds(2048);
        DescribeInstancesResponse response = client.GetAcsResponse(request);
        Console.WriteLine(response.TotalCount);
    }
}

V2.0 SDK

为避免用户混淆,V2.0 SDK将超时配置这种运行时参数与业务参数分开设置。超时配置优先级从高到低为:请求的RuntimeOptions设置 > 客户端的Config设置 > 默认配置。默认连接超时为5秒,读超时为10秒,单位为毫秒。

using System;
using AlibabaCloud.OpenApiClient.Models;
using AlibabaCloud.SDK.Ecs20140526.Models;
using AlibabaCloud.TeaUtil.Models;

class Sample
{
    static void Main(string[] args)
    {
        Config config = new Config
        {
            Credential = new Aliyun.Credentials.Client(),
            Endpoint = "ecs.cn-hangzhou.aliyuncs.com"
        };
        // 客户端级超时,单位为毫秒。
        config.ConnectTimeout = 1024;
        config.ReadTimeout = 2048;
        AlibabaCloud.SDK.Ecs20140526.Client client = new AlibabaCloud.SDK.Ecs20140526.Client(config);

        // 请求级设置优先于客户端级设置。
        RuntimeOptions runtime = new RuntimeOptions
        {
            ConnectTimeout = 1024,
            ReadTimeout = 2048
        };
        DescribeInstancesRequest request = new DescribeInstancesRequest
        {
            RegionId = "cn-hangzhou"
        };
        var response = client.DescribeInstancesWithOptions(request, runtime);
        Console.WriteLine(response.Body.TotalCount);
    }
}

重试机制

两个版本均默认不进行重试。迁移到V2.0 SDK后,如需重试能力,通过RuntimeOptions开启。

V1.0 SDK

V1.0 SDK暂无重试机制。

V2.0 SDK

基于Tea的V2.0 SDK对OpenAPI请求中遇到网络问题的情况会进行重试,对于业务报错不会重试。在请求中通过运行时参数配置开启重试,优先级为RuntimeOptions > 默认;默认不重试,如果打开重试配置未配置重试次数,则默认最多重试3次。以下示例通过RuntimeOptions.Autoretry开启自动重试,并将MaxAttempts设为3。

using System;
using AlibabaCloud.TeaUtil.Models;

namespace demo
{
    public class Sample
    {
        static void Main(string[] args)
        {
            var ecsConfig = new AlibabaCloud.OpenApiClient.Models.Config
            {
                // 从环境变量中获取AccessKey ID值。
                AccessKeyId = Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_ID"),
                // 从环境变量中获取AccessKey Secret值。
                AccessKeySecret = Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_SECRET"),
                Endpoint = "ecs.cn-beijing.aliyuncs.com"
            };

            var ecsClient = new AlibabaCloud.SDK.Ecs20140526.Client(ecsConfig);
            var describeRegionsRequest = new AlibabaCloud.SDK.Ecs20140526.Models.DescribeRegionsRequest();
            // 运行时配置仅对传入该对象的调用生效。
            var runtimeOptions = new RuntimeOptions();
            // 开启自动重试机制。
            runtimeOptions.Autoretry = true;
            // 设置MaxAttempts参数。
            runtimeOptions.MaxAttempts = 3;

            var response = ecsClient.DescribeRegionsWithOptions(describeRegionsRequest, runtimeOptions);
            Console.WriteLine(response.Body.ToMap());
        }
    }
}

调用OpenAPI

特化SDK OpenAPI调用

V1.0 SDK

所有OpenAPI请求通过SDK Core统一处理。云产品SDK中提供了OpenAPI的Request和Response对象。请求OpenAPI的示例如下:

说明

以下示例调用ECS的DescribeRegions接口查询可用地域,为只读操作。

using System;
using Aliyun.Acs.Core;
using Aliyun.Acs.Core.Auth;
using Aliyun.Acs.Core.Profile;
using Aliyun.Acs.Ecs.Model.V20140526;

namespace AlibabaCloud.SDK.Sample
{
    class Program
    {
        static void Main(string[] args)
        {
            AlibabaCloudCredentialsProvider provider = new AccessKeyCredentialProvider(
                Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_ID"),
                Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
            IClientProfile profile = DefaultProfile.GetProfile("cn-hangzhou");
            DefaultAcsClient client = new DefaultAcsClient(profile, provider);

            // 实例化DescribeRegionsRequest对象。
            var request = new DescribeRegionsRequest();
            // 通过SDK Core执行实际的HTTP请求,并将返回结果序列化为SDK的Response对象。
            var response = client.GetAcsResponse(request);
            Console.WriteLine(System.Text.Encoding.Default.GetString(response.HttpResponse.Content));
        }
    }
}

V2.0 SDK

云产品SDK中提供了OpenAPI的Request和Response对象,通过云产品的Client发起调用。

创建对应接口的Request对象,并调用Client中的方法。接口版本、RPC或ROA风格及HTTP方法由产品SDK封装,无需关心。

using System;
using Newtonsoft.Json;

namespace AlibabaCloud.SDK.Sample
{
    public class Sample
    {
        public static AlibabaCloud.SDK.Ecs20140526.Client CreateClient()
        {
            Aliyun.Credentials.Client credential = new Aliyun.Credentials.Client();
            AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config
            {
                Credential = credential,
            };
            config.Endpoint = "ecs.cn-hangzhou.aliyuncs.com";
            return new AlibabaCloud.SDK.Ecs20140526.Client(config);
        }

        public static void Main(string[] args)
        {
            AlibabaCloud.SDK.Ecs20140526.Client client = CreateClient();
            AlibabaCloud.SDK.Ecs20140526.Models.DescribeRegionsRequest describeRegionsRequest = new AlibabaCloud.SDK.Ecs20140526.Models.DescribeRegionsRequest();
            AlibabaCloud.TeaUtil.Models.RuntimeOptions runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();
            AlibabaCloud.SDK.Ecs20140526.Models.DescribeRegionsResponse resp = client.DescribeRegionsWithOptions(describeRegionsRequest, runtime);
            Console.WriteLine(JsonConvert.SerializeObject(resp, Formatting.Indented));
        }
    }
}

CommonRequest调用

V1.0 SDK:CommonRequest

CommonRequest用于不依赖云产品请求模型的通用调用。需要设置以下信息:

  • Domain:产品的服务接入域名。

  • Version:接口版本,格式为YYYY-MM-DD。

  • 接口信息:根据接口风格设置Action或UriPattern。

  • RPC风格(例如ECS、RDS):使用Action指定接口名称,例如request.Action = "<Action>"。

  • ROA风格(RESTful,例如容器服务):使用UriPattern指定请求路径,例如request.UriPattern = "<UriPattern>"。

RPC示例:查询ECS实例状态。

using System.Collections.Generic;
using System;
using Aliyun.Acs.Core;
using Aliyun.Acs.Core.Exceptions;
using Aliyun.Acs.Core.Profile;
class Sample
{
    static void Main(string[] args)
    {
        // 初始化客户端。
        IClientProfile profile = DefaultProfile.GetProfile(
            // 地域ID
            "cn-hangzhou",
            // 从环境变量读取AccessKey ID。
            Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_ID"),
            // 从环境变量读取AccessKey Secret。
            Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        DefaultAcsClient client = new DefaultAcsClient(profile);
        try
        {
            // 构造请求。
            CommonRequest request = new CommonRequest();
            request.Protocol = Aliyun.Acs.Core.Http.ProtocolType.HTTPS;
            request.Domain = "ecs.aliyuncs.com";
            request.Version = "2014-05-26";
            // RPC接口通过Action指定接口名称。
            request.Action = "DescribeInstanceStatus";
            request.AddQueryParameters("RegionId", "cn-hangzhou");
            List<string> instanceIds = new List<string> { "i-bp124uve8zq7XXXXXXXX", "i-bp1axhql4dqaXXXXXXXX" };
            for (int i = 0; i < instanceIds.Count; i++)
            {
                request.AddQueryParameters($"InstanceId.{i + 1}", instanceIds[i]);
            }
            request.AddQueryParameters("PageNumber", "1");
            request.AddQueryParameters("PageSize", "30");
            // 发起请求并获取响应。
            CommonResponse response = client.GetCommonResponse(request);
            System.Console.WriteLine(response.Data);
        }
        catch (ServerException ex)
        {
            System.Console.WriteLine(ex.ToString());
        }
        catch (ClientException ex)
        {
            System.Console.WriteLine(ex.ToString());
        }
    }
}

ROA示例:查询容器服务集群。

using System;
using Aliyun.Acs.Core;
using Aliyun.Acs.Core.Exceptions;
using Aliyun.Acs.Core.Profile;
class Sample
{
    static void Main(string[] args)
    {
        // 初始化客户端。
        IClientProfile profile = DefaultProfile.GetProfile(
            // 地域ID
            "<REGION-ID>",
            // 从环境变量读取AccessKey ID。
            Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_ID"),
            // 从环境变量读取AccessKey Secret。
            Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        DefaultAcsClient client = new DefaultAcsClient(profile);
        try
        {
            // 构造请求。
            CommonRequest request = new CommonRequest();
            request.Protocol = Aliyun.Acs.Core.Http.ProtocolType.HTTPS;
            request.Domain = "cs.aliyuncs.com";
            request.Version = "2015-12-15";
            // ROA接口通过UriPattern指定请求路径。
            request.UriPattern = "/clusters";
            // 发起请求并获取响应。
            CommonResponse response = client.GetCommonResponse(request);
            System.Console.WriteLine(response.Data);
        }
        catch (ServerException ex)
        {
            System.Console.WriteLine(ex.ToString());
        }
        catch (ClientException ex)
        {
            System.Console.WriteLine(ex.ToString());
        }
    }
}

V2.0 SDK:CallApi

通过AlibabaCloud.OpenApiClient.Models.Params配置OpenAPI的基本信息,如OpenAPI的风格、API版本、请求方式等信息。通过AlibabaCloud.OpenApiClient.Client调用CallApi发起请求。Params设置示例:

参数

说明

示例值

Style

接口风格。

RPC

Version

接口版本。

2014-05-26

Method

HTTP请求方法。

POST

Action

接口名称。

DescribeRegions

Pathname

请求路径。

/

Protocol

请求协议。

HTTPS

AuthType

鉴权类型。

AK

ReqBodyType

请求体格式。

json

BodyType

响应体格式。

json

完整示例:使用AlibabaCloud.OpenApiClient.Models.Params设置接口信息,通过AlibabaCloud.OpenApiClient.Client的CallApi方法调用ECS的DescribeRegions接口。

using System;
using Newtonsoft.Json;

namespace AlibabaCloud.SDK.Sample
{
    public class Sample
    {
        public static AlibabaCloud.OpenApiClient.Client CreateClient()
        {
            Aliyun.Credentials.Client credential = new Aliyun.Credentials.Client();
            AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config
            {
                Credential = credential,
            };
            config.Endpoint = "ecs.cn-hangzhou.aliyuncs.com";
            return new AlibabaCloud.OpenApiClient.Client(config);
        }
        public static AlibabaCloud.OpenApiClient.Models.Params CreateApiInfo()
        {
            AlibabaCloud.OpenApiClient.Models.Params params_ = new AlibabaCloud.OpenApiClient.Models.Params
            {
                // 接口名称。
                Action = "DescribeRegions",
                // 接口版本。
                Version = "2014-05-26",
                // 接口协议。
                Protocol = "HTTPS",
                // HTTP请求方法。
                Method = "POST",
                AuthType = "AK",
                Style = "RPC",
                // 请求路径。
                Pathname = "/",
                // 接口请求体内容格式。
                ReqBodyType = "json",
                // 接口响应体内容格式。
                BodyType = "json",
            };
            return params_;
        }

        public static void Main(string[] args)
        {
            AlibabaCloud.OpenApiClient.Client client = CreateClient();
            AlibabaCloud.OpenApiClient.Models.Params params_ = CreateApiInfo();
            AlibabaCloud.TeaUtil.Models.RuntimeOptions runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();
            AlibabaCloud.OpenApiClient.Models.OpenApiRequest request = new AlibabaCloud.OpenApiClient.Models.OpenApiRequest();
            // 返回字典包含body、headers和statusCode。
            object resp = client.CallApi(params_, request, runtime);
            Console.WriteLine(JsonConvert.SerializeObject(resp, Formatting.Indented));
        }
    }
}

RPC示例:调用DescribeInstanceTypeFamilies查询ECS实例规格族。

using System.Collections.Generic;
using System;
namespace AlibabaCloud.SDK.Sample
{
    public class Sample
    {
        public static AlibabaCloud.OpenApiClient.Client CreateClient()
        {
            AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config
            {
                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
                AccessKeyId = Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_ID"),
                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
                AccessKeySecret = Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_SECRET"),
            };
            config.Endpoint = "ecs.cn-hangzhou.aliyuncs.com";
            return new AlibabaCloud.OpenApiClient.Client(config);
        }

        public static AlibabaCloud.OpenApiClient.Models.Params CreateApiInfo()
        {
            AlibabaCloud.OpenApiClient.Models.Params params_ = new AlibabaCloud.OpenApiClient.Models.Params
            {
                // 接口名称。
                Action = "DescribeInstanceTypeFamilies",
                // 接口版本。
                Version = "2014-05-26",
                // 接口协议。
                Protocol = "HTTPS",
                // HTTP请求方法。
                Method = "POST",
                AuthType = "AK",
                Style = "RPC",
                // 请求路径。
                Pathname = "/",
                // 接口请求体内容格式。
                ReqBodyType = "json",
                // 接口响应体内容格式。
                BodyType = "json",
            };
            return params_;
        }

        public static void Main(string[] args)
        {
            AlibabaCloud.OpenApiClient.Client client = CreateClient();
            AlibabaCloud.OpenApiClient.Models.Params params_ = CreateApiInfo();
            // 查询参数。
            Dictionary<string, object> queries = new Dictionary<string, object>();
            queries["RegionId"] = "cn-hangzhou";
            // 运行时参数。
            AlibabaCloud.TeaUtil.Models.RuntimeOptions runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();
            AlibabaCloud.OpenApiClient.Models.OpenApiRequest request = new AlibabaCloud.OpenApiClient.Models.OpenApiRequest
            {
                Query = AlibabaCloud.OpenApiUtil.Client.Query(queries),
            };
            // 读取接口返回结果。
            // 返回字典包含body、headers和statusCode。
            var response = client.CallApi(params_, request, runtime);
            Console.WriteLine(JsonConvert.SerializeObject(response, Formatting.Indented));
        }
    }
}

ROA示例:调用DescribeClustersV1查询容器服务集群。

using System;
namespace AlibabaCloud.SDK.Sample
{
    public class Sample
    {
        public static AlibabaCloud.OpenApiClient.Client CreateClient()
        {
            AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config
            {
                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
                AccessKeyId = Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_ID"),
                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
                AccessKeySecret = Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_SECRET"),
            };
            config.Endpoint = "cs.cn-hangzhou.aliyuncs.com";
            return new AlibabaCloud.OpenApiClient.Client(config);
        }

        public static AlibabaCloud.OpenApiClient.Models.Params CreateApiInfo()
        {
            AlibabaCloud.OpenApiClient.Models.Params params_ = new AlibabaCloud.OpenApiClient.Models.Params
            {
                // 接口名称。
                Action = "DescribeClustersV1",
                // 接口版本。
                Version = "2015-12-15",
                // 接口协议。
                Protocol = "HTTPS",
                // HTTP请求方法。
                Method = "GET",
                AuthType = "AK",
                Style = "ROA",
                // 请求路径。
                Pathname = "/api/v1/clusters",
                // 接口请求体内容格式。
                ReqBodyType = "json",
                // 接口响应体内容格式。
                BodyType = "json",
            };
            return params_;
        }

        public static void Main(string[] args)
        {
            AlibabaCloud.OpenApiClient.Client client = CreateClient();
            AlibabaCloud.OpenApiClient.Models.Params params_ = CreateApiInfo();
            // 运行时参数。
            AlibabaCloud.TeaUtil.Models.RuntimeOptions runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();
            AlibabaCloud.OpenApiClient.Models.OpenApiRequest request = new AlibabaCloud.OpenApiClient.Models.OpenApiRequest();
            // 读取接口返回结果。
            // 返回字典包含body、headers和statusCode。
            var response = client.CallApi(params_, request, runtime);
            Console.WriteLine(JsonConvert.SerializeObject(response, Formatting.Indented));
        }
    }
}

异常处理

V1.0 SDK

捕获ServerException和ClientException,读取ErrorCode、ErrorMessage和RequestId。请求未到达服务端时,异常可能不包含RequestId。

using System;
using Aliyun.Acs.Core;
using Aliyun.Acs.Core.Profile;
using Aliyun.Acs.Core.Exceptions;
using Aliyun.Acs.Ecs.Model.V20140526;
namespace AlibabaCloud.SDK.Sample
{
    class Program
    {
        static void Main(string[] args)
        {
            // 初始化客户端。
            IClientProfile profile = DefaultProfile.GetProfile(
                // 地域ID
                "your-region-id",
                // 从环境变量读取AccessKey ID。
                Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_ID"),
                // 从环境变量读取AccessKey Secret。
                Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
            DefaultAcsClient client = new DefaultAcsClient(profile);

            try
            {
                // 构造请求。
                DescribeInstancesRequest request = new DescribeInstancesRequest();
                request.Protocol = Aliyun.Acs.Core.Http.ProtocolType.HTTPS;
                request.PageSize = 10;

                // 发起请求并获取响应。
                DescribeInstancesResponse response = client.GetAcsResponse(request);
                System.Console.WriteLine(response.TotalCount);
            }
            catch (ServerException e)
            {
                System.Console.WriteLine(e.ToString());
                // 按业务需要处理异常。
                // 例如,打印具体的错误信息。
                Console.WriteLine("ErrorCode=" + e.ErrorCode);
                Console.WriteLine("ErrorMessage=" + e.ErrorMessage);
                // 提交工单时提供RequestId。
                Console.WriteLine("RequestId=" + e.RequestId);
            }
            catch (ClientException ex)
            {
                System.Console.WriteLine(ex.ToString());
                // 按业务需要处理异常。
                // 例如,打印具体的错误信息。
                Console.WriteLine("ErrorCode=" + ex.ErrorCode);
                Console.WriteLine("ErrorMessage=" + ex.ErrorMessage);
            }
        }
    }
}

V2.0 SDK

基于Tea的V2.0 SDK使用以下异常类型。以下属性说明以Tea 1.1.4为例:

  • TeaUnretryableException:请求无法继续重试时抛出。可以通过LastRequest属性查看最后一次请求,通过InnerException查看原因。

  • TeaException:用于传递接口错误信息。常用属性如下:

    • Code:错误码。

    • Message:错误信息。接口返回的错误信息中包含RequestId。

    • DataResult:服务端返回的详细错误信息。读取其中的字段前,先检查对象和字段是否存在。

using System;
using AlibabaCloud.OpenApiClient.Models;
using AlibabaCloud.SDK.Ecs20140526.Models;
using AlibabaCloud.TeaUtil.Models;
using Tea;

class Sample
{
    static void Main(string[] args)
    {
        Config config = new Config
        {
            Credential = new Aliyun.Credentials.Client(),
            Endpoint = "ecs.cn-hangzhou.aliyuncs.com"
        };
        AlibabaCloud.SDK.Ecs20140526.Client client = new AlibabaCloud.SDK.Ecs20140526.Client(config);
        DescribeInstancesRequest request = new DescribeInstancesRequest
        {
            RegionId = "cn-hangzhou"
        };
        RuntimeOptions runtime = new RuntimeOptions();
        try
        {
            client.DescribeInstancesWithOptions(request, runtime);
        }
        catch (TeaUnretryableException error)
        {
            Console.WriteLine(error.Message);
            // LastRequest可能包含敏感信息,不直接输出整个请求。
            if (error.InnerException != null)
            {
                Console.WriteLine(error.InnerException.Message);
            }
        }
        catch (TeaException error)
        {
            Console.WriteLine("Code=" + error.Code);
            Console.WriteLine("Message=" + error.Message);
            object requestId;
            if (error.DataResult != null && error.DataResult.TryGetValue("RequestId", out requestId))
            {
                Console.WriteLine("RequestId=" + requestId);
            }
            object recommend;
            if (error.DataResult != null && error.DataResult.TryGetValue("Recommend", out recommend))
            {
                Console.WriteLine("Recommend=" + recommend);
            }
        }
        catch (Exception error)
        {
            Console.WriteLine(error.Message);
        }
    }
}

技术支持

使用SDK遇到问题时,可以通过以下方式获取技术支持:

  • 提交工单:阿里云提交工单页面。

  • 需求或问题反馈:加入钉钉群(群号:31875811),联系技术支持人员。