根据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';\n");
}
}
}
@Raw(package)
@Raw(modeldes)
class @Model.Name {
@foreach (var proptey in Model.ModelPropties)
{
if (!string.IsNullOrEmpty(proptey.Description))
{
@Raw(string.Concat("///", proptey.Description,"\n"))
}
@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("\n");
if (string.IsNullOrEmpty(modelparams))
{
modelparams += string.Concat("this.", proptey.LowCaseName);
}
else
{
modelparams += string.Concat(",this.", proptey.LowCaseName);
}
}
@Model.Name @("({")@modelparams@("});")
@Raw("\n")
@Model.Name@Raw(".fromJson(Map<String, dynamic> json) {") @Raw("\n")
@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("\n")
@proptey.LowCaseName@Raw("=[];")@Raw("\n")
@Raw("json['")@proptey.Name@Raw("'].forEach((v) {")@Raw("\n")
@if (proptey.SubTypeDes == "baseType")
{
@proptey.LowCaseName@(".add(v);")@Raw("\n")
}
else
{
@proptey.LowCaseName@(".add(")@proptey.SubType@Raw(".fromJson(v));")@Raw("\n")
}
@Raw("});\n")
@Raw(" } else {\n")
@proptey.LowCaseName@Raw("=[];\n")
@Raw("}\n")
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;\n")
}
else
{
@proptey.LowCaseName@("=")@Raw("json['") @proptey.Name@Raw("'];")
}
break;
}
@Raw("\n");
}
}
@Raw("Map<String, dynamic> toJson() { \n")
@Raw("final Map<String, dynamic> data = new Map<String, dynamic>();\n")
@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(";\n")
break;
case "array":
//data['Data'] = this.data.map((v) => v.toJson()).toList();
@Raw("if (this.")@proptey.LowCaseName@Raw(" != null) { \n")
@if (proptey.SubTypeDes == "baseType")
{
@Raw("data['")@proptey.Name@Raw("'] = this.")@proptey.LowCaseName@Raw(".toList();\n")
}
else
{
@Raw("data['")@proptey.Name@Raw("'] = this.")@proptey.LowCaseName@Raw(".map((v) => v.toJson()).toList();\n")
}
@Raw("}\n")
break;//普通对象
default:
if (proptey.TypeDes == "object")
{
@Raw("if (this.")@proptey.LowCaseName@Raw(" != null) { \n")
@Raw("data['")@proptey.Name@Raw("'] = this.")@proptey.LowCaseName@Raw(".toJson();\n")
@Raw("}\n")
}
else
{
@Raw("data['")@proptey.Name@Raw("'] = this.")@proptey.LowCaseName@Raw(";\n")
}
break;
}
}
@Raw("return data;\n")
@Raw("}\n")
}
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的开发人员来说这个应该会比较有用】
根据swagger.json生成flutter model,暂无空安全支持的更多相关文章
- JSON 生成 C# Model
http://www.cnblogs.com/tianqiq/p/4309791.html
- Flutter 使用json_model解析json生成dart文件
一.json_serializable使用步骤 1.集成json_serializable pubspec.yaml 添加以下依赖 dependencies: json_annotation: ^2. ...
- .NetCore2.1 WebAPI 根据swagger.json自动生成客户端代码
前言 上一篇博客中我们可以得知通过Swagger插件可以很方便的提供给接口开发者在线调试,但是实际上Swagger附带的功能还有很多, 比如使用NSwag生成客户端调用代码,进一步解放接口开发者. N ...
- 通过swagger json一键解析为html页面、导出word和excel的解析算法分享
写在前面: 完全通过Spring Boot工程 Java代码,将swagger json 一键解析为html页面.导出word和execel的解析算法,不需要任何网上那些类似于“SwaggerMark ...
- 使用 Swagger 自动生成 ASP.NET Core Web API 的文档、在线帮助测试文档(ASP.NET Core Web API 自动生成文档)
对于开发人员来说,构建一个消费应用程序时去了解各种各样的 API 是一个巨大的挑战.在你的 Web API 项目中使用 Swagger 的 .NET Core 封装 Swashbuckle 可以帮助你 ...
- API生命周期第三阶段:API实施:使用swagger codegen生成可部署工程,择取一个作为mock service
在分享培训了swagger对于API的设计之后,有一些人问我说:你看,现在咱们前端使用web_API做为mock data在进行测试,后端也有mock 测试.然后我们再进行联调,这之中肯定会出现一些偏 ...
- Spring Boot中使用Swagger CodeGen生成REST client
文章目录 什么是Open API规范定义文件呢? 生成Rest Client 在Spring Boot中使用 API Client 配置 使用Maven plugin 在线生成API Spring B ...
- Asp.Net Core 轻松学-利用 Swagger 自动生成接口文档
前言 目前市场上主流的开发模式,几乎清一色的前后端分离方式,作为服务端开发人员,我们有义务提供给各个客户端良好的开发文档,以方便对接,减少沟通时间,提高开发效率:对于开发人员来说,编写接口文档 ...
- .net core 使用swagger自动生成接口文档
前言 swagger是一个api文档自动生动工具,还集成了在线调试. 可以为项目自动生成接口文档, 非常的方便快捷 Swashbuckle.AspNetCore 是一个开源项目,用于生成 ASP.N ...
随机推荐
- Web操作摄像头、高拍仪、指纹仪等设备的功能扩展方案
摘要:信息系统开发中难免会有要操作摄像头.高拍仪.指纹仪等硬件外设,异或诸如获取机器签名.硬件授权保护(加密锁)检测等情况.受限于Web本身运行机制,就不得不使用Active.浏览器插件进行能力扩展了 ...
- kuberadm集群升级
升级kubernetes集群 注意不能跨版本升级 比如1.13.x 要先升级到1.14.x,不能直接升级到1.15.x 举例说明升级到1.15,和1.14有些参数不一样,具体看官网: https:// ...
- Docker学习笔记---通俗易懂
目录 Docker 简介 Docker安装 Docker的基本组成 安装Docker 配置阿里云镜像加速 回顾helloworld流程 工作原理 Docker的常用命令 帮助命令 镜像命令 容器命令 ...
- 技术面试问题汇总第005篇:猎豹移动反病毒工程师part5
这是我当初接受面试的最后两个问题,当时,那位面试官问我对漏洞了解多少时,我说一点都不懂,问我懂不懂系统内核时,我同样只能说不知道.后来他跟我说,面试的考查重点不在于我所掌握的知识的广度,而是深度.这也 ...
- UC-Android逆向工程师 面试题1的分析
1.简介 这个题目是一位吾爱破解的坛友在面试UC的Android逆向工程事时,遇到的题目.此题不难,与阿里移动去年移动安全比赛的题目差不多,题目的验证方式也是查表对比,并且这个表的数据是放在文件中的. ...
- Android内核模块编译执行
Author: GeneBlue 0X01 前言 内核驱动是漏洞的高发区,了解Android驱动代码的编写是分析.利用驱动漏洞的基础.本文以一个"hello"驱动为例,简单介绍内核 ...
- Python多线程_thread和Threading
目录 多线程 _thread模块 使用 _thread模块创建线程 threading 使用 threading模块创建线程 线程同步 在讲多线程之前,我们先看一个单线程的例子: import _th ...
- 第六部分 数据搜索之使用HBASE的API实现条件查询
题目 使用HADOOP的MAPReduce,实现以下功能: (1)基于大数据计算技术的条件查询:使用mapreduce框架,实现类似Hbase六个字段查询的功能 (2)时段流量统计:以hh:mm:ss ...
- PHP 上传文件至阿里云OSS对象存储
简述 1.阿里云开通对象存储服务 OSS 并创建Bucket 2.下载PHP SDK至框架扩展目录,点我下载 3.码上code 阿里云操作 开通对象存储服务 OSS 创建 Bucket 配置Acces ...
- MarkDown写ppt
首先给你的VSCode安装插件 MarkDown语法 例子 --- marp: true paginate: true theme: default class: - lead - invert si ...