• 根据swagger.json生成flutter model,暂无空安全支持


    一般的服务端类型都有泛型支持,对于flutter来说虽然也支持泛型,但是在序列化这里却始终存在问题,flutter不允许用反射,对于flutter项目的开发来说除了画页面,可能最烦人的就是跟服务端打交道的时候对对象创建以及序列化,虽然目前网上也有通过json to dart之类的在线工具根据json生成model,但一个项目中那么多类,都这么做一遍太费劲,在有上下级类的情况下需要手动去一个个的调整,烦人,于是写了一个小工具通过 swagger.json 生成flutter model。

    1,首先在C#中 我们知道可以的可以生成代码的有razor模板和T4模板,我是基于.net 5开发的于是就顺其自然的使用了当下流行的razor模板来生成代码

    在代码引入类库RazorEngine.NetCore

     var config = new TemplateServiceConfiguration();
    config.Language = Language.CSharp; // CSharp.NET as template language.
    config.AllowMissingPropertiesOnDynamic = true;
    config.CachingProvider = new DefaultCachingProvider(t => { });
    config.EncodedStringFactory = new HtmlEncodedStringFactory(); // Html encoding.
    config.Debug = false;
    var service = RazorEngineService.Create(config);
    var enummodel= File.ReadAllText("fluttermodel.cshtml");
    var  result = Engine.Razor.RunCompile(enummodel, "fluttermodel", null, modelsinfo[i]);
    
    

    result 就是根据模板生成的最终代码,代码量非常少,代码生成中最主要的地方在于传入template的model,model中需要定义一个dart类中需要用到的所有信息,

    2 template fluttermodel.cshtml

    @using flutter_model_genrate_swagger;
    @using System.Linq;
    @using System.Text;
    @{
        var modeldes = "";
        if (!string.IsNullOrEmpty(Model.Description))
        {
            modeldes = string.Concat("///", Model.Description);
        }
        var modelparams = "";//参数
    
        var package = "";
        if (Model.Package != null && Model.Package.Count > 0)
        {
            foreach (var pk in Model.Package)
            {
                package += string.Concat("import '", pk, ".dart';
    ");
            }
        }
    }
    
    
    @Raw(package)
    @Raw(modeldes)
    class @Model.Name {
    @foreach (var proptey in Model.ModelPropties)
    {
        if (!string.IsNullOrEmpty(proptey.Description))
        { 
            @Raw(string.Concat("///", proptey.Description,"
    "))   
        }
        @switch (proptey.Type)
        {
            case "array":
                @{
                    string type = string.Concat("List<", @proptey.SubType, ">");
                }
                @Raw(type) @proptey.LowCaseName@(";")
                break;
            case "integer":
                @("int ") @proptey.LowCaseName@(";")
                break;
            case "string":
                @("String ") @proptey.LowCaseName@(";")
                break;
            case "boolean":
                @("bool ") @proptey.LowCaseName@(";")
                break;
            case "number":
                if (proptey.Format == "double")
                {
                    @("double ") @proptey.LowCaseName@(";")
                }
                else
                {
                    @Raw("///类型不确定")
                    @("double ") @proptey.LowCaseName@(";")
                }
                break;
            default:
                @Raw(proptey.Type + " ")@proptey.LowCaseName@(";")
                break;
        }
        @Raw("
    ");
        if (string.IsNullOrEmpty(modelparams))
        {
            modelparams += string.Concat("this.", proptey.LowCaseName);
        }
        else
        {
            modelparams += string.Concat(",this.", proptey.LowCaseName);
        }
    }
    @Model.Name @("({")@modelparams@("});")
    @Raw("
    ")
    @Model.Name@Raw(".fromJson(Map<String, dynamic> json) {") @Raw("
    ")
    @foreach (var proptey in Model.ModelPropties)
    {
        @switch (proptey.Type)
        {
            case "array":
                @{
                    string type = string.Concat("List<", @proptey.SubType, ">");
                }
                @Raw("if (json['")@proptey.Name@Raw("'] != null) {")@Raw("
    ")
                @proptey.LowCaseName@Raw("=[];")@Raw("
    ")
                @Raw("json['")@proptey.Name@Raw("'].forEach((v) {")@Raw("
    ")
                @if (proptey.SubTypeDes == "baseType")
                {
                    @proptey.LowCaseName@(".add(v);")@Raw("
    ")
                }
                else
                {
                    @proptey.LowCaseName@(".add(")@proptey.SubType@Raw(".fromJson(v));")@Raw("
    ")
                }
                @Raw("});
    ")
                @Raw(" } else {
    ")
                @proptey.LowCaseName@Raw("=[];
    ")
                @Raw("}
    ")
                break;
            case "integer":
            case "string":
            case "boolean":
            case "number":
                @proptey.LowCaseName@("=")@Raw("json['") @proptey.Name@Raw("'];")
                break;
            default:
                //判断类型的
                if (proptey.TypeDes == "object")
                {
                    @proptey.LowCaseName@Raw("=json['")@proptey.Name@Raw("']!=null? ")@proptey.Type@Raw(".fromJson(json['")@proptey.Name@Raw("']) : null;
    ")
                }
                else
                {
                    @proptey.LowCaseName@("=")@Raw("json['") @proptey.Name@Raw("'];")
                }
                break;
        }
        @Raw("
    ");
    }
    }
    @Raw("Map<String, dynamic> toJson() { 
    ")
    @Raw("final Map<String, dynamic> data = new Map<String, dynamic>();
    ")
    @foreach (var proptey in Model.ModelPropties)
    {
        switch (proptey.Type)
        {
            case "integer":
            case "string":
            case "boolean":
            case "number":
                @Raw("data['")@proptey.Name@Raw("'] = this.")@proptey.LowCaseName@Raw(";
    ")
                break;
            case "array":
                //data['Data'] = this.data.map((v) => v.toJson()).toList();
                @Raw("if (this.")@proptey.LowCaseName@Raw(" != null) { 
    ")
    
                @if (proptey.SubTypeDes == "baseType")
                {
                    @Raw("data['")@proptey.Name@Raw("'] = this.")@proptey.LowCaseName@Raw(".toList();
    ")
                }
                else
                {
                    @Raw("data['")@proptey.Name@Raw("'] = this.")@proptey.LowCaseName@Raw(".map((v) => v.toJson()).toList();
    ")
                }
                @Raw("}
    ")
    
                break;//普通对象
            default:
                if (proptey.TypeDes == "object")
                {
    
                    @Raw("if (this.")@proptey.LowCaseName@Raw(" != null) { 
    ")
                    @Raw("data['")@proptey.Name@Raw("'] = this.")@proptey.LowCaseName@Raw(".toJson();
    ")
                    @Raw("}
    ")
                }
                else
                {
                    @Raw("data['")@proptey.Name@Raw("'] = this.")@proptey.LowCaseName@Raw(";
    ")
                }
                break;
        }
    }
    @Raw("return data;
    ")
    @Raw("}
    ")
    
    }
    

    3 传入template的类定义

    public enum ModelInfoType
        { 
            Obj,
            Enum
        }
        public class ModelInfo
        {
            public ModelInfo() {
                ModelPropties = new List<ModelPropty>();
            }
            public ModelInfoType Type { get; set; }
            public string Name { get; set; }
            public string Description { get; set; }
            public List<ModelPropty> ModelPropties { get; set; }
    
            public string LowCaseName
            {
                get
                {
                    if (string.IsNullOrEmpty(Name) || Name.Length < 2)
                    {
                        return Name;
                    }
                    else
                    { 
                        return Name.Substring(0, 1).ToLower() + Name.Substring(1);
                    }
                }
            }
            public List<string> Package
            {
                get
                {
                    if (this.ModelPropties.Count == 0)
                    {
                        return null;
                    }
                    else
                    {
                        var result = new List<string>();
                        foreach (var item in ModelPropties)
                        {
                            if (item.Type == "array")//包含arry
                            {
                                if (string.IsNullOrEmpty(item.SubType))
                                {
                                    if (!ServiceAgent.BaseTypes.Contains(item.Type))
                                    {
                                        result.Add(item.Type.Substring(0, 1).ToLower() + item.Type.Substring(1));
                                    }
                                   
                                }
                                else
                                {
                                    if (!ServiceAgent.BaseTypes.Contains(item.SubType.ToLower()))
                                    {
                                        result.Add(item.SubType.Substring(0, 1).ToLower() + item.SubType.Substring(1));
                                    }
                                }
                            }
                            else if (!ServiceAgent.BaseTypes.Contains(item.Type))//基础类型外
                            {
                                result.Add(item.Type.Substring(0, 1).ToLower() + item.Type.Substring(1));
                            }
                        }
                        return result;
                    }
                }
            }
    
    
        }
    
        public class ModelPropty
        { 
            public string Name { get; set; }
            /// <summary>
            /// List<....> | 具体类型
            /// </summary>
            public string Type { get; set; }
            /// <summary>
            /// 如果是arry,这里是arry的子类,
            /// </summary>
            public string SubType { get; set; }
            /// <summary>
            /// 子类描述
            /// </summary>
            public string SubTypeDes { get; set; }
            /// <summary>
            /// 类型描述
            /// </summary>
            public string TypeDes { get; set; }
            public string Format { get; set; }
    
            public string Description { get; set; }
    
            public string LowCaseName
            {
                get
                {
                    if (string.IsNullOrEmpty(Name)|| Name.Length<2)
                    {
                        return Name;
                    }
                    else
                    {
                        return Name.Substring(0, 1).ToLower() + Name.Substring(1);
                    }
                }
            }
        }
    
    

    4 接下去的事情就简单了,把swagger.json下载到本地,用system.text.json解析拿到swagger.json中的所有model,挨个生成

    5 最后调用flutter format {文件夹位置} 将所有生成的model类格式化一遍,如果这里发生错误,手动执行以下命令就大功告成了。

    6 最后附上项目地址: https://gitee.com/zzf_1/flutter-model-genrate-swagger

    release版本下载地址:https://gitee.com/zzf_1/flutter-model-genrate-swagger/tags 【release版本稍微有点大,但是release版本不需要.net环境,对于专职flutter的开发人员来说这个应该会比较有用】

  • 相关阅读:
    form表单提交target属性使用
    window.showModalDialog
    mybaits中date类型显示时分秒(orcle数据库)
    mybatis中in查询
    偷懒的inline-block解决方法
    10. python单元测试(一)
    9. Request & 爬虫
    8. 类与对象
    7. python异常处理&异常基类学习
    6. IO及文件操作
  • 原文地址:https://www.cnblogs.com/zzfstudy/p/14841359.html
Copyright © 2020-2023  润新知