Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为代理创建C#模型类';s ASP.NET Web API使用T4_C#_Asp.net Mvc_Api_Wcf - Fatal编程技术网

为代理创建C#模型类';s ASP.NET Web API使用T4

为代理创建C#模型类';s ASP.NET Web API使用T4,c#,asp.net-mvc,api,wcf,C#,Asp.net Mvc,Api,Wcf,我有一个包装API端点的WEB API代理库项目。此库将发送给需要与此Web API项目通信的C#客户端。 我需要一个生成WebAPI响应模型的T4脚本,以避免将WebAPI响应对象类型手动复制到代理库项目中。您可以使用以下T4脚本。 它管理IList、IDictionary、null类型和标量类型 假设ASP.NET Web API返回了此响应模型类: 运行T4脚本(在代理项目中定义),您将获得以下定义: 在代理项目中定义此T4脚本: <#@ template debug="true

我有一个包装API端点的WEB API代理库项目。此库将发送给需要与此Web API项目通信的C#客户端。
我需要一个生成WebAPI响应模型的T4脚本,以避免将WebAPI响应对象类型手动复制到代理库项目中。

您可以使用以下T4脚本。 它管理IList、IDictionary、null类型和标量类型

假设ASP.NET Web API返回了此响应模型类:

运行T4脚本(在代理项目中定义),您将获得以下定义:

在代理项目中定义此T4脚本:

<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ output encoding="utf-8" extension=".cs"#>
<#@ assembly name="$(SolutionDir)xxx.Dis.Services.Endpoints\\bin\\Debug\\xxx.Dis.Services.Endpoints.dll" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="xxx.Dis.Services.Endpoints" #>
<#  WriteLine("// ----------------------------------------------------------------------------------------------------------------");
    WriteLine("// <auto-generated>");
    WriteLine("// This code is automatically generated by tool on " + DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss") + ".");
    WriteLine("// Values retrieved from project xxx.Dis.Services.Endpoints");
    WriteLine("//");
    WriteLine("// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated."); 
    WriteLine("// </auto-generated>");
    WriteLine("// ----------------------------------------------------------------------------------------------------------------");
    WriteLine("using System;");
    WriteLine("using System.Collections.Generic;");
    WriteLine("using System.Linq;");
    WriteLine("using System.Text;");
    WriteLine("");
    WriteLine("namespace xxx.Dis.Services.Api.ViewModels");    
    WriteLine("{");
    PushIndent("    ");

    // WebAPI's Enum generation
    var enumList = from type in typeof(xxx.Dis.Services.Endpoints.ViewModels.Base.BaseViewModel).Assembly.GetTypes() where type.IsEnum select type;
    foreach (var type in enumList) 
    {
        WriteLine("public enum " + type.Name);
        WriteLine("{");
        PushIndent("    ");
        foreach (var field in type.GetFields()) 
        {
            if (field.Name.Equals("value__")) continue;
            WriteLine(field.Name + " = " + field.GetRawConstantValue() + ",");
        }

        ClearIndent();
        PushIndent("    ");
        WriteLine("}");
        WriteLine("");
    }

    WriteLine("");

    // WebAPI's response Models generation, filtering for all response model implementing a specific base class (in this case named BaseResponseViewModel)
    var modelList = from type in typeof(xxx.Dis.Services.Endpoints.ViewModels.Base.BaseViewModel).Assembly.GetTypes() where typeof(xxx.Dis.Services.Endpoints.ViewModels.Base.BaseResponseViewModel).IsAssignableFrom(type) select type;
    foreach (var type in modelList)     
    {
        WriteLine("public class " + type.Name);
        WriteLine("{");
        PushIndent("    ");

        foreach (var propertyInfo in type.GetProperties())
        {
            string propertyTypeString;
            var propertyType = propertyInfo.PropertyType;

            if (IsList(propertyType))
            {
                propertyTypeString = PrintList(propertyType);
            }
            else if (IsDictionary(propertyType))
            {
                propertyTypeString = PrintDictionary(propertyType);
            }
            else
            {
                propertyTypeString = PrintScalar(propertyType);
            }

            WriteLine("    public " + propertyTypeString + " " + propertyInfo.Name + " { get; set; }");
        }

        ClearIndent();
        PushIndent("    ");
        WriteLine("}");
    }

    ClearIndent();
    WriteLine("}");
#>

<#+
    public static string PrintScalar(Type type)
    {
        if (type.IsGenericType)
        {
            var genericDefionitionName = type.GetGenericTypeDefinition().Name;
            if (!string.IsNullOrEmpty(genericDefionitionName) && genericDefionitionName.Contains("Nullable"))
            {
                var propertyType = type.GetGenericArguments()[0];
                return propertyType.Name + "?";
            }
        }

        return type.Name;
    }

    public static string PrintList(Type type)
    {
        var argumentType = type.GetGenericArguments()[0];

        if (argumentType.IsGenericType && IsNullable(argumentType) == false)
        {               
            if (IsList(argumentType))
            {
                return "IEnumerable<" + PrintList(argumentType) + ">";
            }

            if (IsDictionary(argumentType))
            {
                return "IEnumerable<" + PrintDictionary(argumentType) + ">";
            }
        }

        if (IsNullable(argumentType))
        {
            return "IEnumerable<" + argumentType.GenericTypeArguments[0].Name + "?>";
        }

        return "IEnumerable<" + argumentType.Name + ">";
    }

    public static string PrintDictionary(Type type)
    {
        var argumentsTypes = type.GetGenericArguments();

        // First argument must be not nullable
        if (argumentsTypes[0].IsGenericType || IsNullable(argumentsTypes[0])) throw new NotSupportedException("First argument of IDictionary must be not nullable.");
        var key = argumentsTypes[0].Name;

        if (!argumentsTypes[1].IsGenericType) return "IDictionary<" + key + ", " + argumentsTypes[1].Name + ">";
        if (IsNullable(argumentsTypes[1])) return "IDictionary<" + key + ", " + argumentsTypes[1].GenericTypeArguments[0].Name + "?>";

        var innerArgumentType = argumentsTypes[1];
        if (IsList(innerArgumentType))
        {
            return "IDictionary<" + key + ", " + PrintList(innerArgumentType) + ">";
        }

        if (IsDictionary(innerArgumentType))
        {
            return "IDictionary<" + key + ", " + PrintDictionary(innerArgumentType) + ">";
        }

        return IsNullable(innerArgumentType) 
            ? "IDictionary<" + key + ", " + innerArgumentType.GenericTypeArguments[0].Name + "?>" 
            : "IDictionary<" + key + ", " + innerArgumentType.Name + ">";
    }

    public static bool IsNullable(Type t)
    {
        var result = t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>);
        return result;
    }

    public static bool IsList(Type t)
    {
        var result = t.IsGenericType && (t.GetGenericTypeDefinition().IsAssignableFrom(typeof(IList<>)) || t.GetGenericTypeDefinition().IsAssignableFrom(typeof(List<>)));
        return result;
    }

    public static bool IsDictionary(Type t)
    {
        var result = t.IsGenericType && (t.GetGenericTypeDefinition().IsAssignableFrom(typeof(IDictionary<,>)) || t.GetGenericTypeDefinition().IsAssignableFrom(typeof(Dictionary<,>)));
        return result;
    }
#>

享受吧

在SDLC期间可能比T4模板更方便,开销更小

虽然程序员通常使用WebApiClientGen使用jQuery或Angular2+生成TypeScript客户端API代码,但该项目还提供了POCO2TS.exe,这是一个从POCO类生成TypsScript接口的命令行程序。您可以使用Poco2ts.exe或Poco2ts组件将代码生成与构建管道集成