Added controller scaffolding. There is no more user need for copy/paste to complete the scaffolding process.
This commit is contained in:
Родитель
e72d5bd539
Коммит
a1e59fec0f
|
@ -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>
|
@:<body>
|
||||||
// PushIndent(" ");
|
// 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">
|
@: <kendo-grid name="@(ControllerName())Grid" height="550" on-change="handleChange" selectable="true">
|
||||||
@:<columns>
|
@:<columns>
|
||||||
// Template for columns
|
// Template for columns
|
||||||
|
|
Загрузка…
Ссылка в новой задаче