使用 ASP.NET Core 的自定义代码生成器





5.00/5 (16投票s)
在本文中,我们将概述并使用我们的数据库表列生成基本级别的代码,这将有助于开发。
引言
这个示例背后的主要想法是轻松生成常见类型的代码。
单页应用程序使用 ASP.NET Core 和 AngularJS 构建。 这是执行环境,API 服务在 .NET Core 中生成代码。 在前端,我使用了 AngularJS。
内容聚焦
- 连接到数据库服务器
- 获取所有数据库列表,然后
- 通过选择特定表来获取所有表列
- 选择列,然后
- 生成代码,就是这样
让我们深入研究代码,首先让我们从后端工作开始。 我们使用连接字符串连接我们的数据库服务器。
让我们处理后端,连接到数据库
让我们创建一个 API 控制器来完成所有操作。 在我们的控制器类中,让我们放置一个连接字符串以连接我们的数据库。
private string conString = "server=DESKTOP-80DEJMQ; uid=sa; pwd=sa@12345;";
获取所有数据库
让我们创建一个方法来从数据库服务器获取所有数据库列表。 以下是获取所有数据库的 SQL 查询。
SELECT name from sys.databases WHERE name NOT IN ('master', 'tempdb', 'model', 'msdb') _
ORDER BY create_date
这是 Get
方法,用于列出服务器中的所有数据库。
// api/Codegen/GetDatabaseList
[HttpGet, Route("GetDatabaseList"), Produces("application/json")]
public List<vmDatabase> GetDatabaseList()
{
List<vmDatabase> data = new List<vmDatabase>();
using (SqlConnection con = new SqlConnection(conString))
{
int count = 0; con.Open();
using (SqlCommand cmd = new SqlCommand("SELECT name from sys.databases _
WHERE name NOT IN ('master', 'tempdb', 'model', 'msdb') ORDER BY create_date", con))
{
using (IDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
count++;
data.Add(new vmDatabase()
{
DatabaseId = count,
DatabaseName = dr[0].ToString()
});
}
}
}
}
return data.ToList();
}
获取所有表列
在这里,我们从选定的数据库中获取所有表。
// api/Codegen/GetDatabaseTableList
[HttpPost, Route("GetDatabaseTableList"), Produces("application/json")]
public List<vmTable> GetDatabaseTableList([FromBody]vmParam model)
{
List<vmTable> data = new List<vmTable>();
string conString_ = conString + " Database=" + model.DatabaseName + ";";
using (SqlConnection con = new SqlConnection(conString_))
{
int count = 0; con.Open();
DataTable schema = con.GetSchema("Tables");
foreach (DataRow row in schema.Rows)
{
count++;
data.Add(new vmTable()
{
TableId = count,
TableName = row[2].ToString()
});
}
}
return data.ToList();
}
选择列
以下是获取所有表列的 SQL 查询。
SELECT COLUMN_NAME, DATA_TYPE, ISNULL(CHARACTER_MAXIMUM_LENGTH,0), _
IS_NULLABLE, TABLE_SCHEMA FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '" + _
model.TableName + "' ORDER BY ORDINAL_POSITION
这是 Get
方法,用于列出服务器中所有选定的表列。
// api/Codegen/GetDatabaseTableColumnList
[HttpPost, Route("GetDatabaseTableColumnList"), Produces("application/json")]
public List<vmColumn> GetDatabaseTableColumnList([FromBody]vmParam model)
{
List<vmColumn> data = new List<vmColumn>();
string conString_ = conString + " Database=" + model.DatabaseName + ";";
using (SqlConnection con = new SqlConnection(conString_))
{
int count = 0; con.Open();
using (SqlCommand cmd = new SqlCommand("SELECT COLUMN_NAME, DATA_TYPE, _
ISNULL(CHARACTER_MAXIMUM_LENGTH,0), IS_NULLABLE, _
TABLE_SCHEMA FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '" + _
model.TableName + "' ORDER BY ORDINAL_POSITION", con))
{
using (IDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
count++;
data.Add(new vmColumn()
{
ColumnId = count,
ColumnName = dr[0].ToString(),
DataType = dr[1].ToString(),
MaxLength = dr[2].ToString(),
IsNullable = dr[3].ToString(),
Tablename = model.TableName.ToString(),
TableSchema = dr[4].ToString()
});
}
}
}
}
return data.ToList();
}
现在让我们概述一下服务器代码,该代码基于我们的数据库列生成生成的代码。
[EnableCors("AllowCors"), Produces("application/json"), Route("api/Codegen")]
public class CodegenController : Controller
{
private readonly IHostingEnvironment _hostingEnvironment;
private string conString = "server=DESKTOP-80DEJMQ; uid=sa; pwd=sa@12345;";
public CodegenController(IHostingEnvironment hostingEnvironment)
{
_hostingEnvironment = hostingEnvironment;
}
#region ++++++ Database +++++++
// api/Codegen/GetDatabaseList
[HttpGet, Route("GetDatabaseList"), Produces("application/json")]
public List<vmDatabase> GetDatabaseList()
{
List<vmDatabase> data = new List<vmDatabase>();
using (SqlConnection con = new SqlConnection(conString))
{
int count = 0; con.Open();
using (SqlCommand cmd = new SqlCommand("SELECT name from sys.databases _
WHERE name NOT IN ('master', 'tempdb', 'model', 'msdb') ORDER BY create_date", con))
{
using (IDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
count++;
data.Add(new vmDatabase()
{
DatabaseId = count,
DatabaseName = dr[0].ToString()
});
}
}
}
}
return data.ToList();
}
// api/Codegen/v
[HttpPost, Route("GetDatabaseTableList"), Produces("application/json")]
public List<vmTable> GetDatabaseTableList([FromBody]vmParam model)
{
List<vmTable> data = new List<vmTable>();
string conString_ = conString + " Database=" + model.DatabaseName + ";";
using (SqlConnection con = new SqlConnection(conString_))
{
int count = 0; con.Open();
DataTable schema = con.GetSchema("Tables");
foreach (DataRow row in schema.Rows)
{
count++;
data.Add(new vmTable()
{
TableId = count,
TableName = row[2].ToString()
});
}
}
return data.ToList();
}
// api/Codegen/GetDatabaseTableColumnList
[HttpPost, Route("GetDatabaseTableColumnList"), Produces("application/json")]
public List<vmColumn> GetDatabaseTableColumnList([FromBody]vmParam model)
{
List<vmColumn> data = new List<vmColumn>();
string conString_ = conString + " Database=" + model.DatabaseName + ";";
using (SqlConnection con = new SqlConnection(conString_))
{
int count = 0; con.Open();
using (SqlCommand cmd = new SqlCommand("SELECT COLUMN_NAME, DATA_TYPE, _
ISNULL(CHARACTER_MAXIMUM_LENGTH,0), IS_NULLABLE, _
TABLE_SCHEMA FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '" + _
model.TableName + "' ORDER BY ORDINAL_POSITION", con))
{
using (IDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
count++;
data.Add(new vmColumn()
{
ColumnId = count,
ColumnName = dr[0].ToString(),
DataType = dr[1].ToString(),
MaxLength = dr[2].ToString(),
IsNullable = dr[3].ToString(),
Tablename = model.TableName.ToString(),
TableSchema = dr[4].ToString()
});
}
}
}
}
return data.ToList();
}
#endregion
#region +++++ CodeGeneration +++++
// api/Codegen/GenerateCode
[HttpPost, Route("GenerateCode"), Produces("application/json")]
public IActionResult GenerateCode([FromBody]object[] data)
{
List<string> spCollection = new List<string>();
try
{
string webRootPath = _hostingEnvironment.WebRootPath; //From wwwroot
string contentRootPath = _hostingEnvironment.ContentRootPath; //From Others
var tblColumns = JsonConvert.DeserializeObject<List<vmColumn>>(data[0].ToString());
string fileContentSet = string.Empty; string fileContentGet = string.Empty;
string fileContentPut = string.Empty; string fileContentDelete = string.Empty;
string fileContentVm = string.Empty; string fileContentView = string.Empty;
string fileContentNg = string.Empty; string fileContentAPIGet = string.Empty;
string fileContentAPIGetById = string.Empty;
//SP
fileContentSet = SpGenerator.GenerateSetSP(tblColumns, webRootPath);
fileContentGet = SpGenerator.GenerateGetSP(tblColumns, webRootPath);
fileContentPut = SpGenerator.GeneratePutSP(tblColumns, webRootPath);
fileContentDelete = SpGenerator.GenerateDeleteSP(tblColumns, webRootPath);
spCollection.Add(fileContentSet);
spCollection.Add(fileContentGet);
spCollection.Add(fileContentPut);
spCollection.Add(fileContentDelete);
//VM
fileContentVm = VmGenerator.GenerateVm(tblColumns, webRootPath);
spCollection.Add(fileContentVm);
//VU
fileContentView = ViewGenerator.GenerateForm(tblColumns, webRootPath);
spCollection.Add(fileContentView);
//NG
fileContentNg = NgGenerator.GenerateNgController(tblColumns, webRootPath);
spCollection.Add(fileContentNg);
//API
fileContentAPIGet = APIGenerator.GenerateAPIGet(tblColumns, webRootPath);
spCollection.Add(fileContentAPIGet);
}
catch (Exception ex)
{
ex.ToString();
}
return Json(new
{
spCollection
});
}
#endregion
}
在我们的代码生成机制中,.txt 模板用于表示真实的结构。 在下面的文件夹中,我们拥有所有格式化的模板,以在生成的代码中呈现真实的结构。
让我们展开生成器。 这是我们通过此应用程序生成的列表。
- API 控制器
- ViewModel
- 存储过程
- AngularJS 控制器
- HTML-Form
API-Generator
下面的代码方法将使用格式化的文本文件生成 API 控制器。
public static dynamic GenerateAPIGet(List<vmColumn> tblColumns, string contentRootPath)
{
TextInfo textInfo = new CultureInfo("en-US", false).TextInfo;
StringBuilder builderPrm = new StringBuilder();
StringBuilder builderSub = new StringBuilder();
builderPrm.Clear(); builderSub.Clear();
string fileContent = string.Empty; string queryPrm = string.Empty; string submitPrm = string.Empty;
string tableName = tblColumns[0].Tablename; string tableSchema = tblColumns[0].TableSchema;
string path = @"" + contentRootPath + "\\template\\WebAPI\\APIController.txt";
// API Controller
string routePrefix = "api/" + textInfo.ToTitleCase
(Conversion.RemoveSpecialCharacters(tableName.ToString()));
string apiController = textInfo.ToTitleCase
(Conversion.RemoveSpecialCharacters(tableName.ToString())) + "Controller";
string collectionName = "List<" + tableName.ToString() + ">";
string listObj = tableName.ToString() + "s";
string getDbMethod = "_ctx." + tableName.ToString() + ".ToListAsync()";
string entity = tableName.ToString();
string urlApiGet = "api/" + textInfo.ToTitleCase
(Conversion.RemoveSpecialCharacters(tableName.ToString())) + "/GetAll";
string urlApiGetByID = "api/" + textInfo.ToTitleCase
(Conversion.RemoveSpecialCharacters(tableName.ToString())) + "/GetByID/5";
string urlApiPost = "api/" + textInfo.ToTitleCase
(Conversion.RemoveSpecialCharacters(tableName.ToString())) + "/Save";
string urlApiPut = "api/" + textInfo.ToTitleCase
(Conversion.RemoveSpecialCharacters(tableName.ToString())) + "/UpdateByID/5";
string urlApiDeleteByID = "api/" + textInfo.ToTitleCase
(Conversion.RemoveSpecialCharacters(tableName.ToString())) + "/DeleteByID/5";
//Enity Fields
foreach (var item in tblColumns)
{
//parameter
builderPrm.AppendLine();
builderPrm.Append("entityUpdate." + item.ColumnName + " = model." + item.ColumnName + ";");
}
submitPrm = builderPrm.AppendLine().ToString();
using (StreamReader sr = new StreamReader(path, Encoding.UTF8))
{
fileContent = sr.ReadToEnd()
.Replace("#RoutePrefix", routePrefix.ToString())
.Replace("#APiController", apiController.ToString())
.Replace("#Collection", collectionName.ToString())
.Replace("#ListObj", listObj.ToString())
.Replace("#DbMethod", getDbMethod.ToString())
.Replace("#Entity", entity.ToString())
.Replace("#UrlApiGet", urlApiGet.ToString())
.Replace("#UrlGetByID", urlApiGetByID.ToString())
.Replace("#UrlPostByID", urlApiPost.ToString())
.Replace("#UrlApiPut", urlApiPut.ToString())
.Replace("#ColUpdate", submitPrm.ToString())
.Replace("#UrlDeleteByID", urlApiDeleteByID.ToString());
}
return fileContent.ToString();
}
API 控制器格式
在本部分中,我们像这样读取文本直到末行,然后使用 C# 动态替换这些 #tag
属性。 这是用于其他代码生成的主要技巧。
[Route("#RoutePrefix"), Produces("application/json")]
public class #APiController : Controller
{
private dbContext _ctx = null;
public #APiController(dbContext context)
{
_ctx = context;
}
// GET: #UrlApiGet
[HttpGet, Route("GetAll")]
public async Task<object> GetAll()
{
#Collection #ListObj = null;
try
{
using (_ctx)
{
#ListObj = await #DbMethod;
}
}
catch (Exception ex)
{
ex.ToString();
}
return #ListObj;
}
// GET #UrlGetByID
[HttpGet, Route("GetByID/{id}")]
public async Task<#Entity> GetByID(int id)
{
#Entity obj = null;
try
{
using (_ctx)
{
obj = await _ctx.#Entity.FirstOrDefaultAsync(x => x.Id == id);
}
}
catch (Exception ex)
{
ex.ToString();
}
return obj;
}
// POST #UrlPostByID
[HttpPost, Route("Save")]
public async Task<object> Save([FromBody]#Entity model)
{
object result = null; string message = "";
if (model == null)
{
return BadRequest();
}
using (_ctx)
{
using (var _ctxTransaction = _ctx.Database.BeginTransaction())
{
try
{
_ctx.#Entity.Add(model);
await _ctx.SaveChangesAsync();
_ctxTransaction.Commit();
message = "Ok";
}
catch (Exception e)
{
_ctxTransaction.Rollback();
e.ToString();
message = "Error";
}
result = new
{
message
};
}
}
return result;
}
// PUT #UrlApiPut
[HttpPut, Route("UpdateByID/{id}")]
public async Task<object> UpdateByID(int id, [FromBody]#Entity model)
{
object result = null; string message = string.Empty;
if (model == null)
{
return BadRequest();
}
using (_ctx)
{
using (var _ctxTransaction = _ctx.Database.BeginTransaction())
{
try
{
var entityUpdate = _ctx.#Entity.FirstOrDefault(x => x.Id == id);
if (entityUpdate != null)
{
#ColUpdate
await _ctx.SaveChangesAsync();
}
_ctxTransaction.Commit();
message = "Ok";
}
catch (Exception e)
{
_ctxTransaction.Rollback(); e.ToString();
message = "Error";
}
result = new
{
message
};
}
}
return result;
}
// DELETE #UrlDeleteByID
[HttpDelete, Route("DeleteByID/{id}")]
public async Task<object> DeleteByID(int id)
{
object result = null; string message = "";
using (_ctx)
{
using (var _ctxTransaction = _ctx.Database.BeginTransaction())
{
try
{
var idToRemove = _ctx.#Entity.SingleOrDefault(x => x.Id == id);
if (idToRemove != null)
{
_ctx.#Entity.Remove(idToRemove);
await _ctx.SaveChangesAsync();
}
_ctxTransaction.Commit();
message = "Ok";
}
catch (Exception e)
{
_ctxTransaction.Rollback();
e.ToString();
message = "Error";
}
result = new
{
message
};
}
}
return result;
}
}
ViewModel-Generator
对于特定的数据模型,我们需要生成一些视图模型。 下面的方法将生成这些数据模型。
public static dynamic GenerateVm(List<vmColumn> tblColumns, string contentRootPath)
{
StringBuilder builderPrm = new StringBuilder();
StringBuilder builderBody = new StringBuilder();
builderPrm.Clear(); builderBody.Clear();
string fileContent = string.Empty; string queryPrm = string.Empty;
string tableName = tblColumns[0].Tablename; string tableSchema = tblColumns[0].TableSchema;
string path = @"" + contentRootPath + "\\template\\ViewModel\\vmModel.txt";
string className = "vm" + tableName.ToString();
foreach (var item in tblColumns)
{
//parameter
builderPrm.AppendLine();
builderPrm.Append(" public " + TypeMap.GetClrType(item.DataType) + " " +
item.ColumnName + " { get; set; }");
}
queryPrm = builderPrm.AppendLine().ToString();
using (StreamReader sr = new StreamReader(path, Encoding.UTF8))
{
fileContent = sr.ReadToEnd().Replace("#ClassName",
className.ToString()).Replace("#Properties", queryPrm.ToString());
}
return fileContent.ToString();
}
Stored Procedure-Generator
Insert-SP
这是插入操作的最小标签 sp 生成查询模板,在应用程序中,我们需要使用我们自己的附加逻辑来修改这些模板。
//CREATE
public static dynamic GenerateSetSP(List<vmColumn> tblColumns, string contentRootPath)
{
StringBuilder builderPrm = new StringBuilder();
StringBuilder builderBody = new StringBuilder();
builderPrm.Clear(); builderBody.Clear();
string path = @"" + contentRootPath + "\\template\\StoredProcedure\\InsertSP.txt";
string fileContent = string.Empty; string fileld = string.Empty;
string fileldPrm = string.Empty; string queryPrm = string.Empty;
string tableName = tblColumns[0].Tablename; string tableSchema = tblColumns[0].TableSchema;
string spName = ("[" + tableSchema + "].[Set_" + tableName + "]").ToString();
foreach (var item in tblColumns)
{
fileld = fileld + item.ColumnName + ",";
fileldPrm = fileldPrm + "@" + item.ColumnName + ",";
//parameter
builderPrm.AppendLine();
if ((item.DataType.ToString() == "nvarchar") || (item.DataType.ToString() == "varchar"))
builderPrm.Append(" @" + item.ColumnName + " " +
item.DataType + "(" + item.MaxLength + "),");
else
builderPrm.Append(" @" + item.ColumnName + " " + item.DataType + ",");
}
queryPrm = builderPrm.Remove((builderPrm.Length - 1), 1).AppendLine().ToString();
//queryPrm = builderPrm.ToString().TrimEnd(',');
//Body
builderBody.Append("INSERT INTO [" + tableSchema + "].[" + tableName + "](");
builderBody.Append(fileld.TrimEnd(',') + ") ");
//builderBody.AppendLine();
builderBody.Append("VALUES (" + fileldPrm.TrimEnd(',') + ")");
using (StreamReader sr = new StreamReader(path, Encoding.UTF8))
{
fileContent = sr.ReadToEnd().Replace("#Name", spName.ToString()).Replace
("#Param", queryPrm.ToString()).Replace("#Body", builderBody.ToString());
}
return fileContent.ToString();
}
Get-SP
这是获取操作的最小标签 sp 生成查询模板,在应用程序中,我们需要使用我们自己的附加逻辑来修改这些模板。
//READ
public static dynamic GenerateGetSP(List<vmColumn> tblColumns, string contentRootPath)
{
StringBuilder builderPrm = new StringBuilder();
StringBuilder builderBody = new StringBuilder();
builderPrm.Clear(); builderBody.Clear();
string path = @"" + contentRootPath + "\\template\\StoredProcedure\\ReadSP.txt";
string fileContent = string.Empty; string fileld = string.Empty;
string fileldPrm = string.Empty; string queryPrm = string.Empty;
string tableName = tblColumns[0].Tablename; string tableSchema = tblColumns[0].TableSchema;
string spName = ("[" + tableSchema + "].[Get_" + tableName + "]").ToString();
foreach (var item in tblColumns)
{
fileld = fileld + item.ColumnName + ",";
fileldPrm = fileldPrm + "@" + item.ColumnName + ",";
}
//Body
builderBody.Append("SELECT " + fileldPrm.TrimEnd(',') +
" FROM [" + tableSchema + "].[" + tableName + "]");
using (StreamReader sr = new StreamReader(path, Encoding.UTF8))
{
fileContent = sr.ReadToEnd().Replace("#Name", spName.ToString()).Replace
("#Body", builderBody.ToString()).Replace("#OrdPrm", fileldPrm.TrimEnd(',').ToString());
}
return fileContent.ToString();
}
Update-SP
这是更新操作的最小标签 sp 生成查询模板,在应用程序中,我们需要使用我们自己的附加逻辑来修改这些模板。
//UPDATE
public static dynamic GeneratePutSP(List<vmColumn> tblColumns, string contentRootPath)
{
StringBuilder builderPrm = new StringBuilder();
StringBuilder builderBody = new StringBuilder();
builderPrm.Clear(); builderBody.Clear();
string path = @"" + contentRootPath + "\\template\\StoredProcedure\\UpdateSP.txt";
string fileContent = string.Empty; string fileld = string.Empty;
string fileldPrm = string.Empty; string queryPrm = string.Empty;
string tableName = tblColumns[0].Tablename; string tableSchema = tblColumns[0].TableSchema;
string spName = ("[" + tableSchema + "].[Get_" + tableName + "]").ToString();
foreach (var item in tblColumns)
{
fileld = fileld + item.ColumnName + ",";
fileldPrm = fileldPrm + item.ColumnName + " = @" + item.ColumnName + ",";
//parameter
builderPrm.AppendLine();
if ((item.DataType.ToString() == "nvarchar") || (item.DataType.ToString() == "varchar"))
builderPrm.Append(" @" + item.ColumnName + " " +
item.DataType + "(" + item.MaxLength + "),");
else
builderPrm.Append(" @" + item.ColumnName + " " + item.DataType + ",");
}
queryPrm = builderPrm.Remove((builderPrm.Length - 1), 1).AppendLine().ToString();
//Body
builderBody.Append("UPDATE [" + tableSchema + "].[" + tableName + "]
SET " + fileldPrm.TrimEnd(',') + " WHERE [CONDITIONS]");
using (StreamReader sr = new StreamReader(path, Encoding.UTF8))
{
fileContent = sr.ReadToEnd().Replace("#Name", spName.ToString()).Replace
("#Param", queryPrm.ToString()).Replace
("#Body", builderBody.ToString()).Replace("#OrdPrm", fileldPrm.ToString());
}
return fileContent.ToString();
}
Delete-SP
这是删除操作的最小标签 sp 生成查询模板,在应用程序中,我们需要使用我们自己的附加逻辑来修改这些模板。
//DELETE
public static dynamic GenerateDeleteSP(List<vmColumn> tblColumns, string contentRootPath)
{
StringBuilder builderPrm = new StringBuilder();
StringBuilder builderBody = new StringBuilder();
builderPrm.Clear(); builderBody.Clear();
string path = @"" + contentRootPath + "\\template\\StoredProcedure\\DeleteSP.txt";
string fileContent = string.Empty; string fileld = string.Empty;
string fileldPrm = string.Empty; string queryPrm = string.Empty;
string tableName = tblColumns[0].Tablename; string tableSchema = tblColumns[0].TableSchema;
string spName = ("[" + tableSchema + "].[Delete_" + tableName + "]").ToString();
foreach (var item in tblColumns)
{
fileld = fileld + item.ColumnName + ",";
fileldPrm = fileldPrm + "@" + item.ColumnName + ",";
//parameter
builderPrm.AppendLine();
if ((item.DataType.ToString() == "nvarchar") || (item.DataType.ToString() == "varchar"))
builderPrm.Append(" @" + item.ColumnName + " " +
item.DataType + "(" + item.MaxLength + "),");
else
builderPrm.Append(" @" + item.ColumnName + " " + item.DataType + ",");
}
queryPrm = builderPrm.Remove((builderPrm.Length - 1), 1).AppendLine().ToString();
//Body
builderBody.Append("DELETE FROM [" + tableSchema + "].[" + tableName + "] WHERE [CONDITIONS]");
using (StreamReader sr = new StreamReader(path, Encoding.UTF8))
{
fileContent = sr.ReadToEnd().Replace("#Name", spName.ToString()).Replace
("#Param", queryPrm.ToString()).Replace("#Body",
builderBody.ToString()).Replace("#OrdPrm", fileldPrm.ToString());
}
return fileContent.ToString();
}
让我们处理前端, AngularJ Controller-Generator
在我们的前端,我们还使用了与生成 API 控制器相同的机制。
public static dynamic GenerateNgController(List<vmColumn> tblColumns, string contentRootPath)
{
TextInfo textInfo = new CultureInfo("en-US", false).TextInfo;
StringBuilder builderPrm = new StringBuilder();
StringBuilder builderSub = new StringBuilder();
builderPrm.Clear(); builderSub.Clear();
string fileContent = string.Empty; string queryPrm = string.Empty; string submitPrm = string.Empty;
string tableName = tblColumns[0].Tablename; string tableSchema = tblColumns[0].TableSchema;
string path = @"" + contentRootPath + "\\template\\AngularJS\\Controller.txt";
//Controller Name
string ctrlName = textInfo.ToTitleCase(Conversion.RemoveSpecialCharacters
(tableName.ToString())) + "Controller";
string serviceInjected = "'$scope', '$http'"; string srvParam = "$scope, $http";
string urlApiGet = "'/api/" + textInfo.ToTitleCase
(Conversion.RemoveSpecialCharacters(tableName.ToString())) + "/GetAll'";
string url_GetByID = "'/api/" + textInfo.ToTitleCase
(Conversion.RemoveSpecialCharacters(tableName.ToString())) +
"/GetByID/'+ parseInt(model.id)";
string url_Post = "'/api/" + textInfo.ToTitleCase
(Conversion.RemoveSpecialCharacters(tableName.ToString())) + "/Save'";
string url_Put = "'/api/" + textInfo.ToTitleCase
(Conversion.RemoveSpecialCharacters(tableName.ToString())) +
"/UpdateByID/'+ parseInt(model.id)";
string url_Delete = "'/api/" + textInfo.ToTitleCase
(Conversion.RemoveSpecialCharacters(tableName.ToString())) +
"/DeleteByID/'+ parseInt(model.id)";
using (StreamReader sr = new StreamReader(path, Encoding.UTF8))
{
fileContent = sr.ReadToEnd()
.Replace("#ControllerName", ctrlName.ToString())
.Replace("#ServiceInjected", serviceInjected.ToString())
.Replace("#SrvParam", srvParam.ToString())
.Replace("#UrlGet", urlApiGet.ToString())
.Replace("#Url_GetByID", url_GetByID.ToString())
.Replace("#Url_Post", url_Post.ToString())
.Replace("#Url_Put", url_Put.ToString())
.Replace("#Url_Delete", url_Delete.ToString());
}
return fileContent.ToString();
}
HTML-Generator (Form)
使用以下方法,我们生成了嵌入了 angular
标签的 HTML 表单。
public static dynamic GenerateForm(List<vmColumn> tblColumns, string contentRootPath)
{
TextInfo textInfo = new CultureInfo("en-US", false).TextInfo;
StringBuilder builderPrm = new StringBuilder();
StringBuilder builderSub = new StringBuilder();
builderPrm.Clear(); builderSub.Clear();
string fileContent = string.Empty; string queryPrm = string.Empty; string submitPrm = string.Empty;
string tableName = tblColumns[0].Tablename; string tableSchema = tblColumns[0].TableSchema;
string path = @"" + contentRootPath + "\\template\\HtmlForm\\Form.txt";
//Form Name
string frmName = "name='frm" + tableName.ToString() + "' novalidate";
//Form Fields
foreach (var item in tblColumns)
{
//parameter
builderPrm.AppendLine();
builderPrm.Append(" <div class='form-group'>");
builderPrm.AppendLine();
if (item.ColumnName.Contains("email") || item.ColumnName.Contains("Email"))
{
builderPrm.Append(" <label for='" + item.ColumnName + "' class='control-label'>" +
textInfo.ToTitleCase(Conversion.RemoveSpecialCharacters(item.ColumnName))
+ "</label>");
builderPrm.AppendLine();
builderPrm.Append(" <input type='email' class='form-control' ng-model='vmfrm." +
item.ColumnName + "' name='" + item.ColumnName + "' required />");
}
else if (item.ColumnName.Contains("password") || item.ColumnName.Contains("Password"))
{
builderPrm.Append(" <label for='" + item.ColumnName + "' class='control-label'>" +
textInfo.ToTitleCase(Conversion.RemoveSpecialCharacters
(item.ColumnName)) + "</label>");
builderPrm.AppendLine();
builderPrm.Append(" <input type='password' class='form-control' ng-model='vmfrm." +
item.ColumnName + "' name='" + item.ColumnName + "' required />");
}
else
{
builderPrm.Append(" <label for='" + item.ColumnName + "' class='control-label'>" +
textInfo.ToTitleCase(Conversion.RemoveSpecialCharacters
(item.ColumnName)) + "</label>");
builderPrm.AppendLine();
builderPrm.Append(" <input type='text' class='form-control' ng-model='vmfrm." +
item.ColumnName + "' name='" + item.ColumnName + "' required />");
}
builderPrm.AppendLine();
builderPrm.Append(" </div>");
}
queryPrm = builderPrm.AppendLine().ToString();
//Form Submit
builderSub.Append(" <div class='form-group'>");
builderSub.AppendLine();
builderSub.Append(" <input type='submit' name='reset' value='Reset' ng-click='Reset()' />");
builderSub.AppendLine();
builderSub.Append(" <input type='submit' name='update' value='Update' ng-click='Update()' />");
builderSub.AppendLine();
builderSub.Append(" <input type='submit' name='submit' value='Save' ng-click='Save()' />");
builderSub.AppendLine();
builderSub.Append(" </div>");
submitPrm = builderSub.AppendLine().ToString();
using (StreamReader sr = new StreamReader(path, Encoding.UTF8))
{
fileContent = sr.ReadToEnd().Replace("#frmName", frmName.ToString()).Replace
("#frmGroup", queryPrm.ToString()).Replace("#frmSubmit", submitPrm.ToString());
}
return fileContent.ToString();
}
生成的代码
我们使用了多个选项卡来表示所有生成的代码。 以下是我们的 HTML 部分,它展示了我们如何呈现生成的代码。
<div class="tab-struct custom-tab-2 mt-0">
<ul role="tablist" class="nav nav-tabs" id="myTabs_15">
<li class="active" role="presentation">
<a data-toggle="tab" id="views_tab_1" role="tab" href="#views" aria-expanded="false">
HTML Views</a>
</li>
<li role="presentation" class="">
<a data-toggle="tab" id="angular_tab_1" role="tab" href="#angular" aria-expanded="false">
AngularJS</a>
</li>
<li role="presentation" class="">
<a data-toggle="tab" id="csharp_tab_1" role="tab" href="#csharp" aria-expanded="false">
WebAPI</a>
</li>
<li role="presentation" class="">
<a data-toggle="tab" id="model_tab_1" role="tab" href="#model" aria-expanded="false">
Model</a>
</li>
<li class="" role="presentation">
<a aria-expanded="true" data-toggle="tab" role="tab" id="sql_tab_1" href="#sql">SQL</a>
</li>
</ul>
<div class="tab-content" id="myTabContent_15">
<div id="views" class="tab-pane fade active in" role="tabpanel"
style="max-height:450px; overflow-y: auto;">
<pre class="pa-10" lang="html"><xmp id="genCodeVu"></xmp></pre>
</div>
<div id="angular" class="tab-pane fade" role="tabpanel"
style="max-height:450px; overflow-y: auto;">
<pre class="pa-10" lang="sql"><xmp id="genCodeAngular"></xmp></pre>
</div>
<div id="csharp" class="tab-pane fade" role="tabpanel"
style="max-height:450px; overflow-y: auto;">
<pre class="pa-10" lang="sql"><xmp id="genCodeAPI"></xmp></pre>
</div>
<div id="model" class="tab-pane fade" role="tabpanel"
style="max-height:450px; overflow-y: auto;">
<pre class="pa-10" lang="cs"><xmp id="genCodeVm"></xmp></pre>
</div>
<div id="sql" class="tab-pane fade" role="tabpanel"
style="max-height:450px; overflow-y: auto;">
<pre class="pa-10" lang="sql"><xmp id="genCodeSql"></xmp></pre>
</div>
</div>
</div>
我们使用了预格式化和 HTML 示例 Element
标签在 HTML 中呈现生成的代码。
<pre lang="sql"><xmp id="genCodeAPI"></xmp></pre>
这是代码生成前端函数,它与 API 交互,然后获取生成的content,该content通过在 HTML 页面中编写 DOM 来表示。
$scope.generate = function () {
$('.nav-tabs a[href="#views"]').tab('show');
var rowGen = [];
var elementIDSql = 'genCodeSql';
var elementIDVm = 'genCodeVm';
var elementIDVu = 'genCodeVu';
var elementIDNg = 'genCodeAngular';
var elementIDApi = 'genCodeAPI';
if ($scope.collist.length > 0) {
var models = "[" + JSON.stringify($scope.collist) + "]";
$http({
method: 'POST',
url: '/api/Codegen/GenerateCode',
data: models,
dataType: "json",
contentType: 'application/json; charset=utf-8'
}).then(function (response) {
$('#genCodeSql').text(''); $('#genCodeVm').text('');
$('#genCodeVu').text(''); $('#genCodeAngular').text(''); $('#genCodeAPI').text('');
rowGen = response.data.spCollection;
if (rowGen.length > 0) {
for (var i = 0; i < rowGen.length; i++) {
//SP
if (i == 0)
document.getElementById(elementIDSql).innerHTML +=
"--+++++++++ SET SP +++++++ \r\n" + rowGen[i] + "\r\n";
else if (i == 1)
document.getElementById(elementIDSql).innerHTML +=
"--+++++++++ GET SP +++++++++ \r\n" + rowGen[i] + "\r\n";
else if (i == 2)
document.getElementById(elementIDSql).innerHTML +=
"--+++++++++ PUT SP +++++++++ \r\n" + rowGen[i] + "\r\n";
else if (i == 3)
document.getElementById(elementIDSql).innerHTML +=
"--+++++++++ DELETE SP +++++++++ \r\n" + rowGen[i] + "\r\n";
//VM
else if (i == 4)
document.getElementById(elementIDVm).innerHTML +=
"// +++++++++ MODEL PROPERTIES +++++++++ \r\n" + rowGen[i] + "\r\n";
//VIEW
else if (i == 5)
document.getElementById(elementIDVu).innerHTML +=
"<!-- +++++++++ HTML FORM +++++++++ --> \r\n" + rowGen[i] + "\r\n";
//ANGULAR
else if (i == 6)
document.getElementById(elementIDNg).innerHTML +=
"// +++++++++ AngularJS Controller +++++++++ \r\n" + rowGen[i] + "\r\n";
//API
else if (i == 7)
document.getElementById(elementIDApi).innerHTML +=
"// +++++++++ API Controller +++++++++ \r\n" + rowGen[i] + "\r\n";
else
document.getElementById(elementIDSql).innerHTML += " Error !!";
};
};
}, function (error) {
console.log(error);
});
}
else {
rowGen = []; $('#genCodeSql').text(''); $('#genCodeVm').text('');
console.log("Please Choose a Column!!");
};
};
输出
您可以在下面的屏幕中看到最终输出
源代码
我将完整的源代码上传到下载/克隆 @github,希望这会有所帮助。 🙂