当前位置:首页 > 安卓源码 > 技术博客 >

在C#中为ASP.NET Web API和支持桌面,通用Windows,Android和iOS的.NET Core Web API生成强类型客户端API

时间:2019-06-06 16:34 来源:互联网 作者:源码搜藏 浏览: 收藏 挑错 推荐 打印

强类型客户端API生成器 在C#和TypeScript中为jQuery和Angular 2+生成强类型客户端API。 该工具包旨在最大限度地减少重复性任务,简化后端开发与前端开发之间的协调,并通过减少工作量,工作量和压力来提高开发团队的工作效率和产品质量。 这个开源项目提供

强类型客户端API生成器在C#和TypeScript中为jQuery和Angular 2+生成强类型客户端API。该工具包旨在最大限度地减少重复性任务,简化后端开发与前端开发之间的协调,并通过减少工作量,工作量和压力来提高开发团队的工作效率和产品质量。

这个开源项目提供以下产品:

  1. 用于C#中的强类型客户端API的代码生成器,支持桌面,通用Windows,Android和iOS。
  2. 用于jQuery和Angular 2的TypeScript中强类型客户端API的代码生成器
  3. TypeScript CodeDOMTypeScript的CodeDOM组件,派生自.NET Framework的CodeDOM。
  4. POCO2TS.exe,一个从POCO类生成TypeScript接口的命令行程序。
  5. Fonlow.Poco2Ts,一个从POCO类生成TypeScript接口的组件

本文重点介绍如何生成C#Client API库。对于TypeScript中的客户端API库,请查看其他文章如果您正在开发.NET Core应用程序,您可能有兴趣检查“ 为ASP.NET Core Web API生成C#客户端API ”。

主要特点

  1. 生成的客户端API代码直接从Web API控制器方法,.NET基元类型和POCO类映射。这类似于WCF中提供的svcutil.exe
  2. 控制器方法和POCO类的Doc注释被复制到客户端代码中。

主要优点

  1. WebApiClientGen 在RAD或敏捷软件开发期间,与ASP.NET Web API无缝集成,只需很少的步骤/开销即可在Web API和客户端API之间进行设置,维护和同步。
  2. 支持所有.NET基元类型,包括十进制。
  3. 支持DataTimeDataTimeOffsetArrayTuple,动态对象,DictionaryKeyValuePair
  4. 强类型生成代码需要进行设计时类型检查和编译时类型检查。
  5. 提供高级抽象,使应用程序开发人员免受RESTful实践与传统HTTP客户端调用的琐碎技术细节的影响。
  6. 丰富的元信息(包括文档注释)使IDE智能感知更有帮助,因此应用程序开发人员不太需要阅读单独的API文档。

SDLC

在C#中为ASP.NET Web API和支持桌面,通用Windows,Android和iOS的.NET Core Web API生成强类型客户端API

基本上,您可以制作Web API代码,包括API控制器和数据模型,然后执行CreateClientApi.ps1而已。WebApiClientGenCreateClientApi.ps1将为您完成剩下的工作。

团队合作

本节介绍团队合作的一些基本方案。不同公司和团队的情况和背景可能会有所不同,因此您应相应地调整您的团队实践。 

您的团队有一个后端开发人员Brenda在Web API上工作,还有一个前端开发人员Frank在前端工作。每台开发机器都具有正确设置的集成测试环境,因此大多数CI工作可以在没有团队CI服务器的情况下在每台开发机器上完成。Trunk base开发是默认的分支实践。

1个存储库包括后端代码和前端代码

  1. Brenda编写了一些新的Web API代码并进行构建。
  2. Brenda执行CreateClientApi.ps1以生成客户端代码。
  3. Brenda编写并运行一些针对Web API的基本集成测试用例。
  4. Brenda将更改提交/推送到主开发分支或主干。
  5. Frank更新/提取更改,构建并运行测试用例。
  6. Frank基于新的Web API和客户端API开发了新的前端功能。

1个后端存储库和1个前端存储库

Brenda调整了CodeGen.json,它将生成的代码定向到前端存储库的工作文件夹中的客户端API文件夹。

  1. Brenda编写了一些新的Web API代码并进行构建。
  2. Brenda执行CreateClientApi.ps1以生成客户端代码。
  3. Brenda编写并运行一些针对Web API的基本集成测试用例。
  4. Brenda将更改提交/推送到主开发分支或两个存储库的主干。
  5. Frank使用存储库,构建和运行测试用例来更新/提取更改。
  6. Frank基于新的Web API和客户端API开发了新的前端功能。

背景

如果您曾使用WCF开发基于SOAP的Web服务,则可能喜欢使用SvcUtil.exe或Visual Studio IDE的服务引用生成的客户端API代码转移到Web API时,我觉得自己已经回到了石器时代,因为我不得不花费大量时间在设计时检查数据类型和函数原型,这会耗费太多宝贵的脑力而在计算时应该做这样的检查。

我已经开发了一些RESTful Web服务之上IHttpHandlerIHttpModule2010年回来了,这也没必要强类型的数据,但像证件任意数据和溪流。但是,我一直在开发更多需要高抽象和语义数据类型的Web项目。

我看到ASP.NET Web API确实通过类支持高抽象和强类型函数原型ApiController,ASP.NET MVC框架可选地提供了很好地生成的描述API函数的帮助页面但是,在开发Web API之后,我必须手工制作一些非常原始和重复的客户端代码来使用Web服务。如果Web API是由其他人开发的,我将不得不阅读在线帮助页面。

我怀念WCF过去的美好时光。:)应减少客户端编程的开销。

因此,我搜索并尝试找到一些解决方案,可以让我从制作原始和重复的代码中解放出来,这样我就可以专注于在客户端构建业务逻辑。这是一个帮助开发客户端程序的开源项目列表:

  1. WADL
  2. RAML与.NET
  3. WebApiProxy
  4. Swashbuckle  基于Swagger
  5. AutoRest
  6. 的OData

虽然这些解决方案可以生成强类型的客户端代码并在某种程度上减少重复性任务,但我发现它们都没有能够为我提供我所期望的所有流畅和高效的编程体验:

  1. 强类型客户端数据模型映射到服务的数据模型。
  2. 强类型函数原型映射到派生类的函数ApiController
  3. 批发风格的代码生成类似于WCF的方式,因此在SDLC期间的开销最小
  4. 采用数据注释的樱桃采摘数据模型使用流行的属性,如DataContractAttributeJsonObjectAttribute等。
  5. 在设计时和编译时键入检查。
  6. Intellisense用于客户端数据模型,函数原型和文档注释。

这里谈到WebApiClientGen

推定

  1. 您正在开发ASP.NET Web API 2.x应用程序,并将使用C#作为主要编程语言开发在Windows桌面,通用Windows,Android或iOS上运行的应用程序。
  2. 您和其他开发人员更喜欢在服务器端和客户端通过强类型函数进行高抽象。
  3. Web API和实体框架代码优先使用POCO类,您可能不希望将所有数据类和成员发布到客户端程序。

为了跟进这种开发客户端程序的新方法,最好有一个ASP.NET Web API项目或包含Web API的MVC项目。您可以使用现有项目,也可以创建演示项目。

使用代码

步骤0:将NuGet包WebApiClientGen安装到Web MVC / API项目

安装还将安装依赖的NuGet包Fonlow.TypeScriptCodeDOMFonlow.Poco2Ts项目引用。

NuGet包将2个TS文件添加到项目的〜/ Scripts / ClientApi文件夹中,一个是HttpClient.ts,另一个是WebApiClientAuto.ts,每次执行CodeGen时都会替换它们。

此外,用于触发CodeGen的CodeGenController.cs被添加到项目的Controllers文件夹中。
CodeGenController只在调试版本开发过程中应该是可用的,因为客户端API应该只有一次的Web API的每个版本生成。

#if DEBUG  //This controller is not needed in production release,
    // since the client API should be generated during development of the Web Api.
...

namespace Fonlow.WebApiClientGen
{
    [System.Web.Http.Description.ApiExplorerSettings(IgnoreApi = true)]//this controller is a
            //dev backdoor during development, no need to be visible in ApiExplorer.
    public class CodeGenController : ApiController
    {
        /// <summary>
        /// Trigger the API to generate WebApiClientAuto.cs for an established client API project.
        /// POST to  http://localhost:10965/api/CodeGen with json object CodeGenParameters
        /// </summary>
        /// <param name="parameters"></param>
        /// <returns>OK if OK</returns>
        [HttpPost]
        public string TriggerCodeGen(CodeGenParameters parameters)
        {
...
        }
    }

备注

CodeGenController安装在YourMvcOrWebApiProject / Controllers中,即使MVC项目的脚手架具有派生类的文件夹API ApiController

第1步:创建.NET客户端API项目

确保引用以下包:

  1. Microsoft ASP.NET Web API 2.2客户端库
  2. Newtonsoft Json.NET。
  3. System.Runtime.Serialization
  4. System.ServiceModel
  5. System.ComponentModel.DataAnnotations

如此截图所示:

在C#中为ASP.NET Web API和支持桌面,通用Windows,Android和iOS的.NET Core Web API生成强类型客户端API

第2步:准备JSON配置数据

您的Web API项目可能具有POCO类和API函数,如下所示:

namespace DemoWebApi.DemoData
{
    public sealed class Constants
    {
        public const string DataNamespace = "http://fonlow.com/DemoData/2014/02";
    }

    [DataContract(Namespace = Constants.DataNamespace)]
    public enum AddressType
    {
        [EnumMember]
        Postal,
        [EnumMember]
        Residential,
    };

    [DataContract(Namespace = Constants.DataNamespace)]
    public enum Days
    {
        [EnumMember]
        Sat = 1,
        [EnumMember]
        Sun,
        [EnumMember]
        Mon,
        [EnumMember]
        Tue,
        [EnumMember]
        Wed,
        [EnumMember]
        Thu,
        [EnumMember]
        Fri
    };

    [DataContract(Namespace = Constants.DataNamespace)]
    public class Address
    {
        [DataMember]
        public Guid Id { get; set; }

        public Entity Entity { get; set; }

        /// <summary>
        /// Foreign key to Entity
        /// </summary>
        public Guid EntityId { get; set; }

        [DataMember]
        public string Street1 { get; set; }

        [DataMember]
        public string Street2 { get; set; }

        [DataMember]
        public string City { get; set; }

        [DataMember]
        public string State { get; set; }

        [DataMember]
        public string PostalCode { get; set; }

        [DataMember]
        public string Country { get; set; }

        [DataMember]
        public AddressType Type { get; set; }

        [DataMember]
        public DemoWebApi.DemoData.Another.MyPoint Location;
    }

    [DataContract(Namespace = Constants.DataNamespace)]
    public class Entity
    {
        public Entity()
        {
            Addresses = new List<Address>();
        }

        [DataMember]
        public Guid Id { get; set; }

        
        [DataMember(IsRequired =true)]//MVC and Web API does not care
        [System.ComponentModel.DataAnnotations.Required]//MVC and Web API care about only this
        public string Name { get; set; }

        [DataMember]
        public IList<Address> Addresses { get; set; }

        public override string ToString()
        {
            return Name;
        }
    }

    [DataContract(Namespace = Constants.DataNamespace)]
    public class Person : Entity
    {
        [DataMember]
        public string Surname { get; set; }
        [DataMember]
        public string GivenName { get; set; }
        [DataMember]
        public DateTime? BirthDate { get; set; }

        public override string ToString()
        {
            return Surname + ", " + GivenName;
        }

    }

    [DataContract(Namespace = Constants.DataNamespace)]
    public class Company : Entity
    {
        [DataMember]
        public string BusinessNumber { get; set; }

        [DataMember]
        public string BusinessNumberType { get; set; }

        [DataMember]
        public string[][] TextMatrix
        { get; set; }

        [DataMember]
        public int[][] Int2DJagged;

        [DataMember]
        public int[,] Int2D;

        [DataMember]
        public IEnumerable<string> Lines;
    }

...
...

namespace DemoWebApi.Controllers
{
    [RoutePrefix("api/SuperDemo")]
    public class EntitiesController : ApiController
    {
        /// <summary>
        /// Get a person
        /// </summary>
        /// <param name="id">unique id of that guy</param>
        /// <returns>person in db</returns>
        [HttpGet]
        public Person GetPerson(long id)
        {
            return new Person()
            {
                Surname = "Huang",
                GivenName = "Z",
                Name = "Z Huang",
                BirthDate = DateTime.Now.AddYears(-20),
            };
        }

        [HttpPost]
        public long CreatePerson(Person p)
        {
            Debug.WriteLine("CreatePerson: " + p.Name);

            if (p.Name == "Exception")
                throw new InvalidOperationException("It is exception");

            Debug.WriteLine("Create " + p);
            return 1000;
        }

        [HttpPut]
        public void UpdatePerson(Person person)
        {
            Debug.WriteLine("Update " + person);
        }

        [HttpPut]
        [Route("link")]
        public bool LinkPerson(long id, string relationship, [FromBody] Person person)
        {
            return person != null && !String.IsNullOrEmpty(relationship);
        }

        [HttpDelete]
        public void Delete(long id)
        {
            Debug.WriteLine("Delete " + id);
        }

        [Route("Company")]
        [HttpGet]
        public Company GetCompany(long id)
        {

v1.9.0中的JSON配置数据如下所示:

{
    "ApiSelections": {
        "ExcludedControllerNames": [
            "DemoWebApi.Controllers.Account"
        ],

        "DataModelAssemblyNames": [
            "DemoWebApi.DemoData",
            "DemoWebApi"
        ],
        "CherryPickingMethods": 1
    },

    "ClientApiOutputs": {
        "ClientLibraryProjectFolderName": "DemoWebApi.ClientApi",
        "GenerateBothAsyncAndSync": true,

    }
}

配置数据示例使用v1.8.0,此处提供了早期版本

建议将JSON配置数据保存到像这样的文件中

如果您在Web API项目中定义了所有POCO类,则应将Web API项目的程序集名称放在“ DataModelAssemblyNames” 数组中如果您有一些专用的数据模型程序集可以很好地分离关注点,那么您应该将相应的程序集名称放入数组中。您可以选择生成TypeScript客户端API代码或C#客户端API代码,或两者。

CodeGen根据“ CherryPickingMethods” 在POCO类中生成C#客户端代理类,在下面的doc注释中对此进行了描述:

/// <summary>
/// Flagged options for cherry picking in various development processes.
/// </summary>
[Flags]
public enum CherryPickingMethods
{
    /// <summary>
    /// Include all public classes, properties and properties.
    /// </summary>
    All = 0,

    /// <summary>
    /// Include all public classes decorated by DataContractAttribute,
    /// and public properties or fields decorated by DataMemberAttribute.
    /// And use DataMemberAttribute.IsRequired
    /// </summary>
    DataContract =1,

    /// <summary>
    /// Include all public classes decorated by JsonObjectAttribute,
    /// and public properties or fields decorated by JsonPropertyAttribute.
    /// And use JsonPropertyAttribute.Required
    /// </summary>
    NewtonsoftJson = 2,

    /// <summary>
    /// Include all public classes decorated by SerializableAttribute,
    /// and all public properties or fields
    /// but excluding those decorated by NonSerializedAttribute.
    /// And use System.ComponentModel.DataAnnotations.RequiredAttribute.
    /// </summary>
    Serializable = 4,

    /// <summary>
    /// Include all public classes, properties and properties.
    /// And use System.ComponentModel.DataAnnotations.RequiredAttribute.
    /// </summary>
    AspNet = 8,
}

默认选项是DataContract选择加入。您可以使用任何方法或组合方法。

第3步:运行Web API项目的DEBUG构建

步骤4:POST JSON配置数据以触发客户端API代码的生成

在IIS Express上的IDE中运行Web项目。

然后使用CurlPoster或任何您喜欢的客户端工具POST到http:// localhost:10965 / api / CodeGen,with content-type=application/json

提示

基本上,您只需要一步就可以生成客户端API,因为您不需要每次都安装NuGet包。

编写一些批处理脚本来启动Web API和POST JSON配置数据应该不难。我实际上已经起草了一个供您参考:CreateClientApi.ps1,它在IIS Express上启动Web(API)项目,然后POST JSON配置文件所以基本上,大多数情况下,为了不断更新/同步Web API和客户端API,您只需要通过运行Powershell脚本来完成第3步。这减少了持续集成的大量开销。

此序列图说明了开发周期:

在C#中为ASP.NET Web API和支持桌面,通用Windows,Android和iOS的.NET Core Web API生成强类型客户端API

发布客户端API库

完成这些步骤后,现在您已在C#中生成客户端API,类似于此示例:

namespace DemoWebApi.DemoData.Client
{    
    public enum AddressType
    {        
        Postal,        
        Residential,
    }
    
    public enum Days
    {        
        Sat = 1,        
        Sun = 2,        
        Mon = 3,        
        Tue = 4,        
        Wed = 5,        
        Thu = 6,        
        Fri = 7,
    }
    
    public class Address : object
    {        
        private System.Guid _Id;        
        private string _Street1;        
        private string _Street2;        
        private string _City;        
        private string _State;        
        private string _PostalCode;        
        private string _Country;        
        private DemoWebApi.DemoData.Client.AddressType _Type;        
        private DemoWebApi.DemoData.Another.Client.MyPoint _Location;        
        public System.Guid Id
        {
            get
            {
                return _Id;
            }
            set
            {
                _Id = value;
            }
        }
        
        public string Street1
        {
            get
            {
                return _Street1;
            }
            set
            {
                _Street1 = value;
            }
        }
        
        public string Street2
        {
            get
            {
                return _Street2;
            }
            set
            {
                _Street2 = value;
            }
        }
        
        public string City
        {
            get
            {
                return _City;
            }
            set
            {
                _City = value;
            }
        }
        
        public string State
        {
            get
            {
                return _State;
            }
            set
            {
                _State = value;
            }
        }
        
        public string PostalCode
        {
            get
            {
                return _PostalCode;
            }
            set
            {
                _PostalCode = value;
            }
        }
        
        public string Country
        {
            get
            {
                return _Country;
            }
            set
            {
                _Country = value;
            }
        }
        
        public DemoWebApi.DemoData.Client.AddressType Type
        {
            get
            {
                return _Type;
            }
            set
            {
                _Type = value;
            }
        }
        
        public DemoWebApi.DemoData.Another.Client.MyPoint Location
        {
            get
            {
                return _Location;
            }
            set
            {
                _Location = value;
            }
        }
    }
    
    public class Entity : object
    {
        
        private System.Guid _Id;
        
        private string _Name;
        
        private DemoWebApi.DemoData.Client.Address[] _Addresses;
        
        public System.Guid Id
        {
            get
            {
                return _Id;
            }
            set
            {
                _Id = value;
            }
        }
        
        [System.ComponentModel.DataAnnotations.RequiredAttribute()]
        public string Name
        {
            get
            {
                return _Name;
            }
            set
            {
                _Name = value;
            }
        }
        
        public DemoWebApi.DemoData.Client.Address[] Addresses
        {
            get
            {
                return _Addresses;
            }
            set
            {
                _Addresses = value;
            }
        }
    }
    
    public class Person : DemoWebApi.DemoData.Client.Entity
    {
        
        private string _Surname;
        
        private string _GivenName;
        
        private System.Nullable<System.DateTime> _BirthDate;
        
        public string Surname
        {
            get
            {
                return _Surname;
            }
            set
            {
                _Surname = value;
            }
        }
        
        public string GivenName
        {
            get
            {
                return _GivenName;
            }
            set
            {
                _GivenName = value;
            }
        }
        
        public System.Nullable<System.DateTime> BirthDate
        {
            get
            {
                return _BirthDate;
            }
            set
            {
                _BirthDate = value;
            }
        }
    }
    
    public class Company : DemoWebApi.DemoData.Client.Entity
    {
        
        private string _BusinessNumber;
        
        private string _BusinessNumberType;
        
        private string[][] _TextMatrix;
        
        private int[][] _Int2DJagged;
        
        private int[,] _Int2D;
        
        private string[] _Lines;
        
        public string BusinessNumber
        {
            get
            {
                return _BusinessNumber;
            }
            set
            {
                _BusinessNumber = value;
            }
        }
        
        public string BusinessNumberType
        {
            get
            {
                return _BusinessNumberType;
            }
            set
            {
                _BusinessNumberType = value;
            }
        }
        
        public string[][] TextMatrix
        {
            get
            {
                return _TextMatrix;
            }
            set
            {
                _TextMatrix = value;
            }
        }
        
        public int[][] Int2DJagged
        {
            get
            {
                return _Int2DJagged;
            }
            set
            {
                _Int2DJagged = value;
            }
        }
        
        public int[,] Int2D
        {
            get
            {
                return _Int2D;
            }
            set
            {
                _Int2D = value;
            }
        }
        
        public string[] Lines
        {
            get
            {
                return _Lines;
            }
            set
            {
                _Lines = value;
            }
        }
    }
    
    public class MyPeopleDic : object
    {
        
        private System.Collections.Generic.Dictionary<string, DemoWebApi.DemoData.Client.Person> _Dic;
        
        private System.Collections.Generic.Dictionary<string, string> _AnotherDic;
        
        private System.Collections.Generic.Dictionary<int, string> _IntDic;
        
        public System.Collections.Generic.Dictionary<string, DemoWebApi.DemoData.Client.Person> Dic
        {
            get
            {
                return _Dic;
            }
            set
            {
                _Dic = value;
            }
        }
        
        public System.Collections.Generic.Dictionary<string, string> AnotherDic
        {
            get
            {
                return _AnotherDic;
            }
            set
            {
                _AnotherDic = value;
            }
        }
        
        public System.Collections.Generic.Dictionary<int, string> IntDic
        {
            get
            {
                return _IntDic;
            }
            set
            {
                _IntDic = value;
            }
        }
    }
}
namespace DemoWebApi.DemoData.Another.Client
{    
    public struct MyPoint
    {
        
        public double X;
        
        public double Y;
    }
}

    public partial class Entities
    {
        
        private System.Net.Http.HttpClient client;
        
        private System.Uri baseUri;
        
        public Entities(System.Net.Http.HttpClient client, System.Uri baseUri)
        {
            if (client == null)
                throw new ArgumentNullException("client", "Null HttpClient.");

            if (baseUri == null)
                throw new ArgumentNullException("baseUri", "Null baseUri");

            this.client = client;
            this.baseUri = baseUri;
        }
        
        /// <summary>
        ///
        /// PUT api/SuperDemo/link?id={id}&relationship={relationship}
        /// </summary>
        public async Task<bool> LinkPersonAsync
             (long id, string relationship, DemoWebApi.DemoData.Client.Person person)
        {
            var requestUri = this.baseUri + "api/SuperDemo/link?id="+id+"&relationship="+relationship;
            using (var requestWriter = new System.IO.StringWriter())
            {
            var requestSerializer = JsonSerializer.Create();
            requestSerializer.Serialize(requestWriter, person);
            var content = new StringContent(requestWriter.ToString(), 
                          System.Text.Encoding.UTF8, "application/json");
            var responseMessage = await client.PutAsync(requestUri, content);
            responseMessage.EnsureSuccessStatusCode();
            var stream = await responseMessage.Content.ReadAsStreamAsync();
            using (JsonReader jsonReader = new JsonTextReader(new System.IO.StreamReader(stream)))
            {
            var serializer = new JsonSerializer();
            return System.Boolean.Parse(jsonReader.ReadAsString());
            }
            }
        }
        
        /// <summary>
        ///
        /// PUT api/SuperDemo/link?id={id}&relationship={relationship}
        /// </summary>
        public bool LinkPerson(long id, string relationship, DemoWebApi.DemoData.Client.Person person)
        {
            var requestUri = this.baseUri + "api/SuperDemo/link?id="+id+"&relationship="+relationship;
            using (var requestWriter = new System.IO.StringWriter())
            {
            var requestSerializer = JsonSerializer.Create();
            requestSerializer.Serialize(requestWriter, person);
            var content = new StringContent(requestWriter.ToString(), 
                          System.Text.Encoding.UTF8, "application/json");
            var responseMessage = this.client.PutAsync(requestUri, content).Result;
            responseMessage.EnsureSuccessStatusCode();
            var stream = responseMessage.Content.ReadAsStreamAsync().Result;
            using (JsonReader jsonReader = new JsonTextReader(new System.IO.StreamReader(stream)))
            {
            var serializer = new JsonSerializer();
            return System.Boolean.Parse(jsonReader.ReadAsString());
            }
            }
        }
        
        /// <summary>
        ///
        /// GET api/SuperDemo/Company?id={id}
        /// </summary>
        public async Task<DemoWebApi.DemoData.Client.Company> GetCompanyAsync(long id)
        {
            var requestUri = this.baseUri + "api/SuperDemo/Company?id="+id;
            var responseMessage = await client.GetAsync(Uri.EscapeUriString(requestUri));
            responseMessage.EnsureSuccessStatusCode();
            var stream = await responseMessage.Content.ReadAsStreamAsync();
            using (JsonReader jsonReader = new JsonTextReader(new System.IO.StreamReader(stream)))
            {
            var serializer = new JsonSerializer();
            return serializer.Deserialize<DemoWebApi.DemoData.Client.Company>(jsonReader);
            }
        }
        
        /// <summary>
        ///
        /// GET api/SuperDemo/Company?id={id}
        /// </summary>
        public DemoWebApi.DemoData.Client.Company GetCompany(long id)
        {
            var requestUri = this.baseUri + "api/SuperDemo/Company?id="+id;
            var responseMessage = this.client.GetAsync(Uri.EscapeUriString(requestUri)).Result;
            responseMessage.EnsureSuccessStatusCode();
            var stream = responseMessage.Content.ReadAsStreamAsync().Result;
            using (JsonReader jsonReader = new JsonTextReader(new System.IO.StreamReader(stream)))
            {
            var serializer = new JsonSerializer();
            return serializer.Deserialize<DemoWebApi.DemoData.Client.Company>(jsonReader);
            }
        }        

如果您希望某些外部开发人员使用您的Web API,您可以发布针对各种平台的C#客户端API代码或编译库以及ASP.NET MVC框架生成的帮助页面。

使用生成的API代码

这是一个简单的例子:

var httpclient = new system.net.http.httpclient();
var api = new demowebapi.controllers.client.entities(httpclient, baseuri);
person person = new person()
{
    name = "some one",
    surname = "one",
    givenname = "some",
    birthdate = datetime.now.addyears(-20),
    addresses = new address[]{new address(){
        city="brisbane",
        state="qld",
        street1="somewhere",
        street2="over the rainbow",
        postalcode="4000",
        country="australia",
        type= addresstype.postal,
        location = new demowebapi.demodata.another.client.mypoint() {x=4, y=9 },
    }},
};

var id = api.createperson(person);

在像Visual Studio这样的正常文本编辑器中编写客户端代码时,您可能会获得良好的智能感知,因此您很少需要阅读Web API帮助页面。

在C#中为ASP.NET Web API和支持桌面,通用Windows,Android和iOS的.NET Core Web API生成强类型客户端API

在C#中为ASP.NET Web API和支持桌面,通用Windows,Android和iOS的.NET Core Web API生成强类型客户端API

在C#中为ASP.NET Web API和支持桌面,通用Windows,Android和iOS的.NET Core Web API生成强类型客户端API

支持通用Windows应用程序,Android应用程序和iOS应用程序

对于通用Windows应用程序,您可以创建如下的客户端API库:

在C#中为ASP.NET Web API和支持桌面,通用Windows,Android和iOS的.NET Core Web API生成强类型客户端API

对于Android应用,您可能有一个这样的客户端API项目Mono.Android

在C#中为ASP.NET Web API和支持桌面,通用Windows,Android和iOS的.NET Core Web API生成强类型客户端API

对于iOS应用程序,您可以使用以下命令创建这样的客户端API项目Xamarin.iOS

在C#中为ASP.NET Web API和支持桌面,通用Windows,Android和iOS的.NET Core Web API生成强类型客户端API

提示

如果要为具有相同代码库的各种平台提供已编译的库,则可以创建一个符号链接,以指定DemoWebApi.ClientApi文件夹中生成的WebApiClientAuto.cs文件

在C#中为ASP.NET Web API和支持桌面,通用Windows,Android和iOS的.NET Core Web API生成强类型客户端API

如屏幕截图所示,单击“ 添加为链接 ”,您将在项目中创建指向cs文件的符号链接DemoWebApi.iOSClientApi或者,您可以使用Shared Project,或者更好的是.NET Standard项目。

福利摘要

  1. 与ASP.NET Web API无缝集成,只需极少的步骤/开销即可在Web API和客户端API之间进行设置,维护和同步
  2. 支持所有内置类型,包括十进制
  3. 支持DataTimeDataTimeOffsetArrayTuple,动态对象,DictionaryKeyValuePair
  4. 强类型生成的代码需要进行设计时类型检查和编译时类型检查
  5. 高抽象
  6. 智能感知
在C#中为ASP.NET Web API和支持桌面,通用Windows,Android和iOS的.NET Core Web API生成强类型客户端API 转载https://www.codesocang.com/appboke/40316.html

技术博客阅读排行

最新文章