Added controller scaffolding. There is no more user need for copy/paste to complete the scaffolding process.

This commit is contained in:
Ed Charbeneau 2019-02-18 12:54:14 -05:00
Родитель e72d5bd539
Коммит a1e59fec0f
2 изменённых файлов: 282 добавлений и 12 удалений

Просмотреть файл

@ -0,0 +1,282 @@
@inherits Microsoft.VisualStudio.Web.CodeGeneration.Templating.RazorTemplateBase
@using System.Collections.Generic;
@using System.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;
@{
foreach (var namespaceName in Model.RequiredNamespaces)
{
@:using @namespaceName;
}
}
namespace @Model.ControllerNamespace
{
@{
string routePrefix;
if (String.IsNullOrEmpty(Model.AreaName))
{
routePrefix = Model.ControllerRootName;
}
else
{
routePrefix = Model.AreaName + "/" + Model.ControllerRootName;
}
var modelProperties = new List<string>();
foreach (var property in Model.ModelMetadata.Properties)
{
if (property.Scaffold)
{
modelProperties.Add(property.PropertyName);
}
}
var bindString = string.Join(",", modelProperties);
var contextTypeName = Model.ContextTypeName;
var entitySetName = Model.ModelMetadata.EntitySetName;
var entitySetVar = Model.EntitySetVariable ??
(String.IsNullOrEmpty(entitySetName)
? entitySetName
: (entitySetName.Substring(0, length: 1).ToLowerInvariant() + entitySetName.Substring(1)));
var primaryKeyName = Model.ModelMetadata.PrimaryKeys[0].PropertyName;
var primaryKeyShortTypeName = Model.ModelMetadata.PrimaryKeys[0].ShortTypeName;
var primaryKeyType = Model.ModelMetadata.PrimaryKeys[0].TypeName;
var primaryKeyNullableTypeName = GetNullableTypeName(primaryKeyType, primaryKeyShortTypeName);
var lambdaVar = Model.ModelVariable[0];
var relatedProperties = new Dictionary<string, dynamic>();
foreach (var nav in Model.ModelMetadata.Navigations)
{
relatedProperties.Add(nav.AssociationPropertyName, nav);
}
var inlineIncludes = "";
foreach (var property in relatedProperties.Values)
{
inlineIncludes += string.Format("{0} .Include({1} => {1}.{2})", Environment.NewLine, lambdaVar, property.AssociationPropertyName);
}
if (!string.IsNullOrEmpty(Model.AreaName))
{
@:@string.Format("[Area(\"{0}\")]", Model.AreaName)
}
}
public class @Model.ControllerName : Controller
{
private readonly @Model.ContextTypeName _context;
public @(Model.ControllerName)(@Model.ContextTypeName context)
{
_context = context;
}
// GET: @routePrefix
// A simple View is returned
// The Grid will asyc call the @(routePrefix)_Read action on page load
@{
@:public IActionResult Index() => View();
@:public async Task<IActionResult> @(routePrefix)_Read([DataSourceRequest]DataSourceRequest request)
@:{
var includeExpressions = "";
includeExpressions = String.Join("", relatedProperties
.Values
.Select(property => String.Format(".Include({0} => {0}.{1})", lambdaVar, property.AssociationPropertyName)));
if (!String.IsNullOrEmpty(includeExpressions))
{
@:var @entitySetVar = _context.@entitySetName@includeExpressions;
@:return Json(await @(entitySetVar).ToDataSourceResultAsync(request));
}
else
{
@:return Json(await _context.@(entitySetName).ToDataSourceResultAsync(request));
}
} }
// GET: @routePrefix/Details/5
public async Task<IActionResult> Details(@primaryKeyNullableTypeName id)
{
if (id == null)
{
return NotFound();
}
var @Model.ModelVariable = await _context.@(entitySetName)@inlineIncludes
.FirstOrDefaultAsync(m => m.@primaryKeyName == id);
if (@Model.ModelVariable == null)
{
return NotFound();
}
return View(@Model.ModelVariable);
}
// GET: @routePrefix/Create
public IActionResult Create()
{
@{
foreach (var property in relatedProperties.Values)
{
@:ViewData["@(property.ForeignKeyPropertyNames[0])"] = new SelectList(_context.@property.EntitySetName, "@property.PrimaryKeyNames[0]", "@property.DisplayPropertyName");
}
} return View();
}
// POST: @routePrefix/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("@bindString")] @Model.ModelTypeName @Model.ModelVariable)
{
if (ModelState.IsValid)
{
@{
if (!string.IsNullOrEmpty(primaryKeyType) && IsGuid(primaryKeyType))
{
@:@(Model.ModelVariable).@primaryKeyName = Guid.NewGuid();
}
@:_context.Add(@Model.ModelVariable);
@:await _context.SaveChangesAsync();
} return RedirectToAction(nameof(Index));
}
@{
foreach (var property in relatedProperties.Values)
{
@:ViewData["@(property.ForeignKeyPropertyNames[0])"] = new SelectList(_context.@property.EntitySetName, "@property.PrimaryKeyNames[0]", "@property.DisplayPropertyName", @(Model.ModelVariable).@property.ForeignKeyPropertyNames[0]);
}
}
return View(@Model.ModelVariable);
}
// GET: @routePrefix/Edit/5
public async Task<IActionResult> Edit(@primaryKeyNullableTypeName id)
{
if (id == null)
{
return NotFound();
}
var @Model.ModelVariable = await _context.@(entitySetName).FindAsync(id);
if (@Model.ModelVariable == null)
{
return NotFound();
}
@{
foreach (var property in relatedProperties.Values)
{
@:ViewData["@(property.ForeignKeyPropertyNames[0])"] = new SelectList(_context.@property.EntitySetName, "@property.PrimaryKeyNames[0]", "@property.DisplayPropertyName", @(Model.ModelVariable).@property.ForeignKeyPropertyNames[0]);
}
}
return View(@Model.ModelVariable);
}
// POST: @routePrefix/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(@primaryKeyShortTypeName id, [Bind("@bindString")] @Model.ModelTypeName @Model.ModelVariable)
{
if (id != @Model.ModelVariable.@primaryKeyName)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(@Model.ModelVariable);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!@(Model.ModelTypeName)Exists(@Model.ModelVariable.@primaryKeyName))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
@{
foreach (var property in relatedProperties.Values)
{
@:ViewData["@(property.ForeignKeyPropertyNames[0])"] = new SelectList(_context.@property.EntitySetName, "@property.PrimaryKeyNames[0]", "@property.DisplayPropertyName", @(Model.ModelVariable).@property.ForeignKeyPropertyNames[0]);
}
}
return View(@Model.ModelVariable);
}
// GET: @routePrefix/Delete/5
public async Task<IActionResult> Delete(@primaryKeyNullableTypeName id)
{
if (id == null)
{
return NotFound();
}
var @Model.ModelVariable = await _context.@(entitySetName)@inlineIncludes
.FirstOrDefaultAsync(m => m.@primaryKeyName == id);
if (@Model.ModelVariable == null)
{
return NotFound();
}
return View(@Model.ModelVariable);
}
// POST: @routePrefix/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(@primaryKeyShortTypeName id)
{
var @Model.ModelVariable = await _context.@(entitySetName).FindAsync(id);
_context.@(entitySetName).Remove(@Model.ModelVariable);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
private bool @(Model.ModelTypeName)Exists(@primaryKeyShortTypeName id)
{
return _context.@(entitySetName).Any(e => e.@primaryKeyName == id);
}
}
}
@functions
{
// This function converts the primary key short type name to its nullable equivalent when possible. This is required to make
// sure that an HTTP 400 error is thrown when the user tries to access the edit, delete, or details action with null values.
string GetNullableTypeName(string typeName, string shortTypeName)
{
// The exceptions are caught because if for any reason the type is user defined, then the short type name will be used.
// In that case the user will receive a server error if null is passed to the edit, delete, or details actions.
Type primaryKeyType = null;
try
{
primaryKeyType = Type.GetType(typeName);
}
catch
{
}
if (primaryKeyType != null && (!Microsoft.VisualStudio.Web.CodeGeneration.Templating.TypeUtilities.IsNullable(primaryKeyType) || IsGuid(typeName)))
{
return shortTypeName + "?";
}
return shortTypeName;
}
bool IsGuid(string typeName) {
return String.Equals("System.Guid", typeName, StringComparison.OrdinalIgnoreCase);
}
}

Просмотреть файл

@ -49,18 +49,6 @@
@:<body>
// PushIndent(" ");
}
@: @@*
@: // The following code enables the grid's datasource.
@: // Copy the code below to your controller.
@: // Controller Code
@: // GET: @ControllerName()
@: public IActionResult @(Model.ViewName)() => View();
@: public async Task<IActionResult> @(ControllerName())_Read([DataSourceRequest]DataSourceRequest request)
@: {
@: return Json(await _context.@(ControllerName()).ToDataSourceResultAsync(request));
@: }
@: // End of Controller Code
@: *@@
@: <kendo-grid name="@(ControllerName())Grid" height="550" on-change="handleChange" selectable="true">
@:<columns>
// Template for columns