add support for 'mvccontroller-crud' and 'apicontroller-crud' (#2929)
* add support for 'mvccontroller-crud' and 'apicontroller-crud' * logging an error on a missing ValidateEfControllerStep.ControllerType value
This commit is contained in:
Родитель
37e46396bc
Коммит
69409fb574
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"Files": [
|
||||
{
|
||||
"FileName": "Program.cs",
|
||||
"Usings": [
|
||||
"Microsoft.EntityFrameworkCore"
|
||||
],
|
||||
"Options": [
|
||||
"EfScenario"
|
||||
],
|
||||
"Methods": {
|
||||
"Global": {
|
||||
"CodeChanges": [
|
||||
{
|
||||
"InsertAfter": "WebApplication.CreateBuilder",
|
||||
"CheckBlock": "builder.Configuration.GetConnectionString",
|
||||
"Block": "\nvar connectionString = builder.Configuration.GetConnectionString(\"$(ConnectionStringName)\") ?? throw new InvalidOperationException(\"Connection string '$(ConnectionStringName)' not found.\")"
|
||||
},
|
||||
{
|
||||
"InsertAfter": "builder.Configuration.GetConnectionString",
|
||||
"CheckBlock": "builder.Services.AddDbContext",
|
||||
"Block": "builder.Services.AddDbContext<$(DbContextName)>(options => options.$(UseDbMethod)(connectionString))\"",
|
||||
"LeadingTrivia": {
|
||||
"Newline": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -53,8 +53,8 @@ internal static class BlazorCrudScaffolderBuilderExtensions
|
|||
PackageConstants.AspNetCorePackages.AspNetCoreDiagnosticsEfCorePackageName
|
||||
};
|
||||
|
||||
if (context.Properties.TryGetValue(nameof(BlazorCrudSettings), out var commandSettingsObj) &&
|
||||
commandSettingsObj is BlazorCrudSettings commandSettings)
|
||||
if (context.Properties.TryGetValue(nameof(CrudSettings), out var commandSettingsObj) &&
|
||||
commandSettingsObj is CrudSettings commandSettings)
|
||||
{
|
||||
step.ProjectPath = commandSettings.Project;
|
||||
step.Prerelease = commandSettings.Prerelease;
|
||||
|
@ -81,10 +81,10 @@ internal static class BlazorCrudScaffolderBuilderExtensions
|
|||
var step = config.Step;
|
||||
var codeModificationFilePath = GlobalToolFileFinder.FindCodeModificationConfigFile("blazorWebCrudChanges.json", System.Reflection.Assembly.GetExecutingAssembly());
|
||||
//get needed properties and cast them as needed
|
||||
config.Context.Properties.TryGetValue(nameof(BlazorCrudSettings), out var blazorCrudSettingsObj);
|
||||
config.Context.Properties.TryGetValue(nameof(CrudSettings), out var blazorCrudSettingsObj);
|
||||
config.Context.Properties.TryGetValue(nameof(BlazorCrudModel), out var blazorCrudModelObj);
|
||||
config.Context.Properties.TryGetValue(Constants.StepConstants.CodeModifierProperties, out var codeModifierPropertiesObj);
|
||||
var blazorCrudSettings = blazorCrudSettingsObj as BlazorCrudSettings;
|
||||
var blazorCrudSettings = blazorCrudSettingsObj as CrudSettings;
|
||||
var codeModifierProperties = codeModifierPropertiesObj as Dictionary<string, string>;
|
||||
var blazorCrudModel = blazorCrudModelObj as BlazorCrudModel;
|
||||
|
||||
|
@ -115,10 +115,10 @@ internal static class BlazorCrudScaffolderBuilderExtensions
|
|||
builder = builder.WithStep<CodeModificationStep>(config =>
|
||||
{
|
||||
var step = config.Step;
|
||||
config.Context.Properties.TryGetValue(nameof(BlazorCrudSettings), out var blazorCrudSettingsObj);
|
||||
config.Context.Properties.TryGetValue(nameof(CrudSettings), out var blazorCrudSettingsObj);
|
||||
config.Context.Properties.TryGetValue(Constants.StepConstants.AdditionalCodeModifier, out var blazorCodeModifierStringObj);
|
||||
config.Context.Properties.TryGetValue(nameof(BlazorCrudModel), out var blazorCrudModelObj);
|
||||
var blazorCrudSettings = blazorCrudSettingsObj as BlazorCrudSettings;
|
||||
var blazorCrudSettings = blazorCrudSettingsObj as CrudSettings;
|
||||
var blazorCrudModel = blazorCrudModelObj as BlazorCrudModel;
|
||||
var blazorCodeModifierString = blazorCodeModifierStringObj as string;
|
||||
if (blazorCrudSettings is not null &&
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
using Microsoft.DotNet.Scaffolding.CodeModification;
|
||||
using Microsoft.DotNet.Scaffolding.Core.Builder;
|
||||
using Microsoft.DotNet.Scaffolding.Core.Steps;
|
||||
using Microsoft.DotNet.Scaffolding.Internal;
|
||||
using Microsoft.DotNet.Scaffolding.TextTemplating;
|
||||
using Microsoft.DotNet.Tools.Scaffold.AspNet.Common;
|
||||
using Microsoft.DotNet.Tools.Scaffold.AspNet.Helpers;
|
||||
using Microsoft.DotNet.Tools.Scaffold.AspNet.Models;
|
||||
using Microsoft.DotNet.Tools.Scaffold.AspNet.ScaffoldSteps.Settings;
|
||||
|
||||
namespace Microsoft.DotNet.Scaffolding.Core.Hosting;
|
||||
|
||||
internal static class EfControllerScaffolderBuilderExtensions
|
||||
{
|
||||
public static IScaffoldBuilder WithEfControllerTextTemplatingStep(this IScaffoldBuilder builder)
|
||||
{
|
||||
return builder.WithStep<TextTemplatingStep>(config =>
|
||||
{
|
||||
var step = config.Step;
|
||||
var context = config.Context;
|
||||
context.Properties.TryGetValue(nameof(EfControllerModel), out var efControllerModelObj);
|
||||
EfControllerModel efControllerModel = efControllerModelObj as EfControllerModel ??
|
||||
throw new InvalidOperationException("missing 'EfControllerModel' in 'ScaffolderContext.Properties'");
|
||||
|
||||
var efControllerTemplateProperty = EfControllerHelper.GetEfControllerTemplatingProperty(efControllerModel);
|
||||
if (efControllerTemplateProperty is not null)
|
||||
{
|
||||
step.TextTemplatingProperties = [efControllerTemplateProperty];
|
||||
step.DisplayName = $"{efControllerModel.ControllerType} controller";
|
||||
}
|
||||
else
|
||||
{
|
||||
step.SkipStep = true;
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static IScaffoldBuilder WithEfControllerAddPackagesStep(this IScaffoldBuilder builder)
|
||||
{
|
||||
return builder.WithStep<AddPackagesStep>(config =>
|
||||
{
|
||||
var step = config.Step;
|
||||
var context = config.Context;
|
||||
var packageList = new List<string>()
|
||||
{
|
||||
PackageConstants.EfConstants.EfToolsPackageName
|
||||
};
|
||||
|
||||
if (context.Properties.TryGetValue(nameof(EfControllerSettings), out var commandSettingsObj) &&
|
||||
commandSettingsObj is EfControllerSettings commandSettings)
|
||||
{
|
||||
step.ProjectPath = commandSettings.Project;
|
||||
step.Prerelease = commandSettings.Prerelease;
|
||||
if (!string.IsNullOrEmpty(commandSettings.DatabaseProvider) &&
|
||||
PackageConstants.EfConstants.EfPackagesDict.TryGetValue(commandSettings.DatabaseProvider, out string? projectPackageName))
|
||||
{
|
||||
packageList.Add(projectPackageName);
|
||||
}
|
||||
|
||||
step.PackageNames = packageList;
|
||||
}
|
||||
else
|
||||
{
|
||||
step.SkipStep = true;
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static IScaffoldBuilder WithEfControllerCodeChangeStep(this IScaffoldBuilder builder)
|
||||
{
|
||||
builder = builder.WithStep<CodeModificationStep>(config =>
|
||||
{
|
||||
var step = config.Step;
|
||||
var codeModificationFilePath = GlobalToolFileFinder.FindCodeModificationConfigFile("efControllerChanges.json", System.Reflection.Assembly.GetExecutingAssembly());
|
||||
//get needed properties and cast them as needed
|
||||
config.Context.Properties.TryGetValue(nameof(EfControllerSettings), out var efControllerSettingsObj);
|
||||
config.Context.Properties.TryGetValue(nameof(EfControllerModel), out var efControllerModelObj);
|
||||
config.Context.Properties.TryGetValue(Internal.Constants.StepConstants.CodeModifierProperties, out var codeModifierPropertiesObj);
|
||||
var efControllerSettings = efControllerSettingsObj as EfControllerSettings;
|
||||
var codeModifierProperties = codeModifierPropertiesObj as Dictionary<string, string>;
|
||||
var efControllerModel = efControllerModelObj as EfControllerModel;
|
||||
|
||||
//initialize CodeModificationStep's properties
|
||||
if (!string.IsNullOrEmpty(codeModificationFilePath) &&
|
||||
efControllerSettings is not null &&
|
||||
codeModifierProperties is not null &&
|
||||
efControllerModel is not null)
|
||||
{
|
||||
step.CodeModifierConfigPath = codeModificationFilePath;
|
||||
foreach (var kvp in codeModifierProperties)
|
||||
{
|
||||
step.CodeModifierProperties.TryAdd(kvp.Key, kvp.Value);
|
||||
}
|
||||
|
||||
step.ProjectPath = efControllerSettings.Project;
|
||||
step.CodeChangeOptions = efControllerModel.ProjectInfo.CodeChangeOptions ?? [];
|
||||
}
|
||||
else
|
||||
{
|
||||
step.SkipStep = true;
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
using Microsoft.DotNet.Scaffolding.TextTemplating;
|
||||
using Microsoft.DotNet.Tools.Scaffold.AspNet.Models;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Scaffold.AspNet.Helpers;
|
||||
|
||||
internal static class EfControllerHelper
|
||||
{
|
||||
internal static TextTemplatingProperty GetEfControllerTemplatingProperty(EfControllerModel efControllerModel)
|
||||
{
|
||||
var allT4Templates = new TemplateFoldersUtilities().GetAllT4Templates(["EfController"]);
|
||||
string? t4TemplatePath = null;
|
||||
if (efControllerModel.ControllerType.Equals("API", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
t4TemplatePath = allT4Templates.FirstOrDefault(x => x.EndsWith("ApiEfController.tt", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
else
|
||||
{
|
||||
t4TemplatePath = allT4Templates.FirstOrDefault(x => x.EndsWith("MvcEfController.tt", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
var templateType = GetCrudControllerType(t4TemplatePath);
|
||||
|
||||
if (string.IsNullOrEmpty(t4TemplatePath) ||
|
||||
templateType is null)
|
||||
{
|
||||
throw new InvalidOperationException($"Could not find '{efControllerModel.ControllerType}' template");
|
||||
}
|
||||
|
||||
return new TextTemplatingProperty
|
||||
{
|
||||
TemplatePath = t4TemplatePath,
|
||||
TemplateType = templateType,
|
||||
TemplateModel = efControllerModel,
|
||||
TemplateModelName = "Model",
|
||||
OutputPath = Path.Combine(efControllerModel.ControllerOutputPath, $"{efControllerModel.ControllerName}.cs")
|
||||
};
|
||||
}
|
||||
|
||||
private static Type? GetCrudControllerType(string? templatePath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(templatePath))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (Path.GetFileName(templatePath))
|
||||
{
|
||||
case "ApiEfController.tt":
|
||||
return typeof(Templates.EfController.ApiEfController);
|
||||
case "MvcEfController.tt":
|
||||
return typeof(Templates.EfController.MvcEfController);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,16 +1,9 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
using Microsoft.DotNet.Tools.Scaffold.AspNet.Common;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Scaffold.AspNet.Models;
|
||||
|
||||
internal class BlazorCrudModel
|
||||
internal class BlazorCrudModel : CrudModel
|
||||
{
|
||||
public required string PageType { get; init; }
|
||||
public required DbContextInfo DbContextInfo { get; init; }
|
||||
public required ModelInfo ModelInfo { get; init; }
|
||||
public required ProjectInfo ProjectInfo { get; init; }
|
||||
|
||||
//used to get correct Input tag to add to BlazorCrud\Create.tt and BlazorCrud\Edit.tt template
|
||||
public string GetInputType(string inputType)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
using Microsoft.DotNet.Tools.Scaffold.AspNet.Common;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Scaffold.AspNet.Models;
|
||||
|
||||
internal class CrudModel
|
||||
{
|
||||
public required string PageType { get; init; }
|
||||
public required DbContextInfo DbContextInfo { get; init; }
|
||||
public required ModelInfo ModelInfo { get; init; }
|
||||
public required ProjectInfo ProjectInfo { get; init; }
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
using Microsoft.DotNet.Tools.Scaffold.AspNet.Common;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Scaffold.AspNet.Models;
|
||||
|
||||
internal class EfControllerModel
|
||||
{
|
||||
public required string ControllerType { get; set; }
|
||||
public required string ControllerName { get; set; }
|
||||
public required string ControllerOutputPath { get; set; }
|
||||
public required DbContextInfo DbContextInfo { get; init; }
|
||||
public required ModelInfo ModelInfo { get; init; }
|
||||
public required ProjectInfo ProjectInfo { get; init; }
|
||||
}
|
|
@ -21,7 +21,7 @@ public static class Program
|
|||
out var projectOption, out var prereleaseOption, out var fileNameOption, out var actionsOption,
|
||||
out var areaNameOption, out var modelNameOption, out var endpointsClassOption, out var databaseProviderOption,
|
||||
out var databaseProviderRequiredOption, out var dataContextClassOption, out var dataContextClassRequiredOption,
|
||||
out var openApiOption, out var pageTypeOption);
|
||||
out var openApiOption, out var pageTypeOption, out var controllerNameOption);
|
||||
|
||||
builder.AddScaffolder("blazor-empty")
|
||||
.WithDisplayName("Razor Component - Empty")
|
||||
|
@ -98,8 +98,54 @@ public static class Program
|
|||
step.CommandName = "mvccontroller";
|
||||
});
|
||||
|
||||
builder.AddScaffolder("apicontroller-crud")
|
||||
.WithDisplayName("API Controller with actions, using Entity Framework (CRUD)")
|
||||
.WithCategory("API")
|
||||
.WithDescription("Create an API controller with REST actions to create, read, update, delete, and list entities")
|
||||
.WithOptions([projectOption, modelNameOption, controllerNameOption, dataContextClassRequiredOption, databaseProviderRequiredOption, prereleaseOption])
|
||||
.WithStep<ValidateEfControllerStep>(config =>
|
||||
{
|
||||
var step = config.Step;
|
||||
var context = config.Context;
|
||||
step.Project = context.GetOptionResult(projectOption);
|
||||
step.Model = context.GetOptionResult(modelNameOption);
|
||||
step.DataContext = context.GetOptionResult(dataContextClassRequiredOption);
|
||||
step.DatabaseProvider = context.GetOptionResult(databaseProviderRequiredOption);
|
||||
step.Prerelease = context.GetOptionResult(prereleaseOption);
|
||||
step.ControllerType = "API";
|
||||
step.ControllerName = context.GetOptionResult(controllerNameOption);
|
||||
})
|
||||
.WithEfControllerAddPackagesStep()
|
||||
.WithDbContextStep()
|
||||
.WithConnectionStringStep()
|
||||
.WithEfControllerTextTemplatingStep()
|
||||
.WithEfControllerCodeChangeStep();
|
||||
|
||||
builder.AddScaffolder("mvccontroller-crud")
|
||||
.WithDisplayName("MVC Controller with views, using Entity Framework (CRUD)")
|
||||
.WithCategory("MVC")
|
||||
.WithDescription("Create a MVC controller with read/write actions and views using Entity Framework")
|
||||
.WithOptions([projectOption, modelNameOption, controllerNameOption, dataContextClassRequiredOption, databaseProviderRequiredOption])
|
||||
.WithStep<ValidateEfControllerStep>(config =>
|
||||
{
|
||||
var step = config.Step;
|
||||
var context = config.Context;
|
||||
step.Project = context.GetOptionResult(projectOption);
|
||||
step.Model = context.GetOptionResult(modelNameOption);
|
||||
step.DataContext = context.GetOptionResult(dataContextClassRequiredOption);
|
||||
step.DatabaseProvider = context.GetOptionResult(databaseProviderRequiredOption);
|
||||
step.Prerelease = context.GetOptionResult(prereleaseOption);
|
||||
step.ControllerType = "MVC";
|
||||
step.ControllerName = context.GetOptionResult(controllerNameOption);
|
||||
})
|
||||
.WithEfControllerAddPackagesStep()
|
||||
.WithDbContextStep()
|
||||
.WithConnectionStringStep()
|
||||
.WithEfControllerTextTemplatingStep()
|
||||
.WithEfControllerCodeChangeStep();
|
||||
|
||||
builder.AddScaffolder("blazor-crud")
|
||||
.WithDisplayName("Razor Components w/ EF (CRUD)")
|
||||
.WithDisplayName("Razor Components with EntityFrameworkCore (CRUD)")
|
||||
.WithCategory("Blazor")
|
||||
.WithDescription("Generates Razor Components using Entity Framework for Create, Delete, Details, Edit and List operations for the given model")
|
||||
.WithOptions([projectOption, modelNameOption, dataContextClassRequiredOption, databaseProviderRequiredOption, pageTypeOption, prereleaseOption])
|
||||
|
@ -177,6 +223,7 @@ public static class Program
|
|||
services.AddTransient<AreaScaffolderStep>();
|
||||
services.AddTransient<DotnetNewScaffolderStep>();
|
||||
services.AddTransient<EmptyControllerScaffolderStep>();
|
||||
services.AddTransient<ValidateEfControllerStep>();
|
||||
}
|
||||
|
||||
static void CreateOptions(
|
||||
|
@ -192,7 +239,8 @@ public static class Program
|
|||
out ScaffolderOption<string> dataContextClassOption,
|
||||
out ScaffolderOption<string> dataContextClassRequiredOption,
|
||||
out ScaffolderOption<bool> openApiOption,
|
||||
out ScaffolderOption<string> pageTypeOption)
|
||||
out ScaffolderOption<string> pageTypeOption,
|
||||
out ScaffolderOption<string> controllerNameOption)
|
||||
{
|
||||
projectOption = new ScaffolderOption<string>
|
||||
{
|
||||
|
@ -229,6 +277,14 @@ public static class Program
|
|||
PickerType = InteractivePickerType.YesNo
|
||||
};
|
||||
|
||||
controllerNameOption = new ScaffolderOption<string>
|
||||
{
|
||||
DisplayName = "Controller Name",
|
||||
CliOption = "--controller",
|
||||
Description = "Name for the controller being created",
|
||||
Required = true
|
||||
};
|
||||
|
||||
areaNameOption = new ScaffolderOption<string>
|
||||
{
|
||||
DisplayName = "Area Name",
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
namespace Microsoft.DotNet.Tools.Scaffold.AspNet.ScaffoldSteps.Settings;
|
||||
|
||||
internal class BlazorCrudSettings : EfWithModelStepSettings
|
||||
internal class CrudSettings : EfWithModelStepSettings
|
||||
{
|
||||
public required string Page { get; set; }
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
namespace Microsoft.DotNet.Tools.Scaffold.AspNet.ScaffoldSteps.Settings;
|
||||
|
||||
internal class EfControllerSettings : EfWithModelStepSettings
|
||||
{
|
||||
public required string ControllerType { get; set; }
|
||||
public required string ControllerName { get; set; }
|
||||
}
|
|
@ -27,7 +27,7 @@ internal class ValidateBlazorCrudStep : ScaffoldStep
|
|||
|
||||
public ValidateBlazorCrudStep(
|
||||
IFileSystem fileSystem,
|
||||
ILogger<ValidateMinimalApiStep> logger)
|
||||
ILogger<ValidateBlazorCrudStep> logger)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
_logger = logger;
|
||||
|
@ -43,7 +43,7 @@ internal class ValidateBlazorCrudStep : ScaffoldStep
|
|||
}
|
||||
else
|
||||
{
|
||||
context.Properties.Add(nameof(BlazorCrudSettings), blazorCrudSettings);
|
||||
context.Properties.Add(nameof(CrudSettings), blazorCrudSettings);
|
||||
}
|
||||
|
||||
//initialize MinimalApiModel
|
||||
|
@ -89,7 +89,7 @@ internal class ValidateBlazorCrudStep : ScaffoldStep
|
|||
return true;
|
||||
}
|
||||
|
||||
private BlazorCrudSettings? ValidateBlazorCrudSettings()
|
||||
private CrudSettings? ValidateBlazorCrudSettings()
|
||||
{
|
||||
if (string.IsNullOrEmpty(Project) || !_fileSystem.FileExists(Project))
|
||||
{
|
||||
|
@ -124,7 +124,7 @@ internal class ValidateBlazorCrudStep : ScaffoldStep
|
|||
DatabaseProvider = PackageConstants.EfConstants.SqlServer;
|
||||
}
|
||||
|
||||
return new BlazorCrudSettings
|
||||
return new CrudSettings
|
||||
{
|
||||
Model = Model,
|
||||
Project = Project,
|
||||
|
@ -135,7 +135,7 @@ internal class ValidateBlazorCrudStep : ScaffoldStep
|
|||
};
|
||||
}
|
||||
|
||||
private async Task<BlazorCrudModel?> GetBlazorCrudModelAsync(BlazorCrudSettings settings)
|
||||
private async Task<BlazorCrudModel?> GetBlazorCrudModelAsync(CrudSettings settings)
|
||||
{
|
||||
var projectInfo = ClassAnalyzers.GetProjectInfo(settings.Project, _logger);
|
||||
if (projectInfo is null || projectInfo.CodeService is null)
|
||||
|
|
|
@ -0,0 +1,205 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
using Microsoft.DotNet.Scaffolding.Core.Scaffolders;
|
||||
using Microsoft.DotNet.Scaffolding.Core.Steps;
|
||||
using Microsoft.DotNet.Scaffolding.Internal.Services;
|
||||
using Microsoft.DotNet.Scaffolding.TextTemplating.DbContext;
|
||||
using Microsoft.DotNet.Tools.Scaffold.AspNet.Common;
|
||||
using Microsoft.DotNet.Tools.Scaffold.AspNet.Helpers;
|
||||
using Microsoft.DotNet.Tools.Scaffold.AspNet.Models;
|
||||
using Microsoft.DotNet.Tools.Scaffold.AspNet.ScaffoldSteps.Settings;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Constants = Microsoft.DotNet.Scaffolding.Internal.Constants;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Scaffold.AspNet.ScaffoldSteps;
|
||||
|
||||
internal class ValidateEfControllerStep : ScaffoldStep
|
||||
{
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly ILogger _logger;
|
||||
public string? Project { get; set; }
|
||||
public bool Prerelease { get; set; }
|
||||
public string? DatabaseProvider { get; set; }
|
||||
public string? DataContext { get; set; }
|
||||
public string? Model { get; set; }
|
||||
public string? ControllerName { get; set; }
|
||||
public string? ControllerType { get; set; }
|
||||
|
||||
public ValidateEfControllerStep(
|
||||
IFileSystem fileSystem,
|
||||
ILogger<ValidateEfControllerStep> logger)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public override async Task<bool> ExecuteAsync(ScaffolderContext context, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var efControllerSettings = ValidateEfControllerSettings();
|
||||
var codeModifierProperties = new Dictionary<string, string>();
|
||||
if (efControllerSettings is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Properties.Add(nameof(EfControllerSettings), efControllerSettings);
|
||||
}
|
||||
|
||||
//initialize CrudControllerModel
|
||||
_logger.LogInformation("Initializing scaffolding model...");
|
||||
var efControllerModel = await GetEfControllerModelAsync(efControllerSettings);
|
||||
if (efControllerModel is null)
|
||||
{
|
||||
_logger.LogError("An error occurred.");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Properties.Add(nameof(EfControllerModel), efControllerModel);
|
||||
}
|
||||
|
||||
//Install packages and add a DbContext (if needed)
|
||||
if (efControllerModel.DbContextInfo.EfScenario)
|
||||
{
|
||||
var dbContextProperties = AspNetDbContextHelper.GetDbContextProperties(efControllerSettings.Project, efControllerModel.DbContextInfo);
|
||||
if (dbContextProperties is not null)
|
||||
{
|
||||
context.Properties.Add(nameof(DbContextProperties), dbContextProperties);
|
||||
}
|
||||
|
||||
var projectBasePath = Path.GetDirectoryName(efControllerSettings.Project);
|
||||
if (!string.IsNullOrEmpty(projectBasePath))
|
||||
{
|
||||
context.Properties.Add(Constants.StepConstants.BaseProjectPath, projectBasePath);
|
||||
}
|
||||
|
||||
codeModifierProperties = AspNetDbContextHelper.GetDbContextCodeModifierProperties(efControllerModel.DbContextInfo);
|
||||
}
|
||||
|
||||
context.Properties.Add(Constants.StepConstants.CodeModifierProperties, codeModifierProperties);
|
||||
return true;
|
||||
}
|
||||
|
||||
private EfControllerSettings? ValidateEfControllerSettings()
|
||||
{
|
||||
if (string.IsNullOrEmpty(Project) || !_fileSystem.FileExists(Project))
|
||||
{
|
||||
_logger.LogError("Missing/Invalid --project option.");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(Model))
|
||||
{
|
||||
_logger.LogError("Missing/Invalid --model option.");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(ControllerName))
|
||||
{
|
||||
_logger.LogError("Missing/Invalid --controller option.");
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
ControllerName = Path.GetFileNameWithoutExtension(ControllerName);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(ControllerType))
|
||||
{
|
||||
_logger.LogError($"Missing/Invalid '{nameof(ValidateEfControllerStep.ControllerType)}' value.");
|
||||
return null;
|
||||
}
|
||||
else if (
|
||||
!string.IsNullOrEmpty(ControllerType) &&
|
||||
!ControllerType.Equals("API", StringComparison.OrdinalIgnoreCase) &&
|
||||
!ControllerType.Equals("MVC", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
//defaulting to API controller
|
||||
ControllerType = "API";
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(DataContext))
|
||||
{
|
||||
_logger.LogError("Missing/Invalid --dataContext option.");
|
||||
return null;
|
||||
}
|
||||
else if (string.IsNullOrEmpty(DatabaseProvider) || !PackageConstants.EfConstants.EfPackagesDict.ContainsKey(DatabaseProvider))
|
||||
{
|
||||
DatabaseProvider = PackageConstants.EfConstants.SqlServer;
|
||||
}
|
||||
|
||||
return new EfControllerSettings
|
||||
{
|
||||
Model = Model,
|
||||
ControllerName = ControllerName,
|
||||
Project = Project,
|
||||
ControllerType = ControllerType,
|
||||
DataContext = DataContext,
|
||||
DatabaseProvider = DatabaseProvider,
|
||||
Prerelease = Prerelease
|
||||
};
|
||||
}
|
||||
|
||||
private async Task<EfControllerModel?> GetEfControllerModelAsync(EfControllerSettings settings)
|
||||
{
|
||||
var projectInfo = ClassAnalyzers.GetProjectInfo(settings.Project, _logger);
|
||||
var projectDirectory = Path.GetDirectoryName(projectInfo.ProjectPath);
|
||||
if (projectInfo is null || projectInfo.CodeService is null || string.IsNullOrEmpty(projectDirectory))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
//find and set --model class properties
|
||||
ModelInfo? modelInfo = null;
|
||||
var allClasses = await projectInfo.CodeService.GetAllClassSymbolsAsync();
|
||||
var modelClassSymbol = allClasses.FirstOrDefault(x => x.Name.Equals(settings.Model, StringComparison.OrdinalIgnoreCase));
|
||||
if (string.IsNullOrEmpty(settings.Model) || modelClassSymbol is null)
|
||||
{
|
||||
_logger.LogError($"Invalid --model '{settings.Model}'");
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
modelInfo = ClassAnalyzers.GetModelClassInfo(modelClassSymbol);
|
||||
}
|
||||
|
||||
var validateModelInfoResult = ClassAnalyzers.ValidateModelForCrudScaffolders(modelInfo, _logger);
|
||||
if (!validateModelInfoResult)
|
||||
{
|
||||
_logger.LogError($"Invalid --model '{settings.Model}'");
|
||||
return null;
|
||||
}
|
||||
|
||||
//find DbContext info or create properties for a new one.
|
||||
var dbContextClassName = settings.DataContext;
|
||||
DbContextInfo dbContextInfo = new();
|
||||
|
||||
if (!string.IsNullOrEmpty(dbContextClassName) && !string.IsNullOrEmpty(settings.DatabaseProvider))
|
||||
{
|
||||
var dbContextClassSymbol = allClasses.FirstOrDefault(x => x.Name.Equals(dbContextClassName, StringComparison.OrdinalIgnoreCase));
|
||||
dbContextInfo = ClassAnalyzers.GetDbContextInfo(settings.Project, dbContextClassSymbol, dbContextClassName, settings.DatabaseProvider, settings.Model);
|
||||
dbContextInfo.EfScenario = true;
|
||||
}
|
||||
|
||||
EfControllerModel scaffoldingModel = new()
|
||||
{
|
||||
ControllerName = settings.ControllerName,
|
||||
ControllerType = settings.ControllerType,
|
||||
ProjectInfo = projectInfo,
|
||||
ModelInfo = modelInfo,
|
||||
DbContextInfo = dbContextInfo,
|
||||
ControllerOutputPath = projectDirectory
|
||||
};
|
||||
|
||||
if (scaffoldingModel.ProjectInfo is not null && scaffoldingModel.ProjectInfo.CodeService is not null)
|
||||
{
|
||||
scaffoldingModel.ProjectInfo.CodeChangeOptions =
|
||||
[
|
||||
scaffoldingModel.DbContextInfo.EfScenario ? "EfScenario" : string.Empty
|
||||
];
|
||||
}
|
||||
|
||||
return scaffoldingModel;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
using Microsoft.DotNet.Scaffolding.TextTemplating;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Scaffold.AspNet.Templates.EfController;
|
||||
|
||||
public partial class ApiEfController : ITextTransformation
|
||||
{
|
||||
}
|
|
@ -0,0 +1,503 @@
|
|||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version: 17.0.0.0
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
// ------------------------------------------------------------------------------
|
||||
namespace Microsoft.DotNet.Tools.Scaffold.AspNet.Templates.EfController
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Class to produce the template output
|
||||
/// </summary>
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")]
|
||||
public partial class ApiEfController : ApiEfControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Create the template output
|
||||
/// </summary>
|
||||
public virtual string TransformText()
|
||||
{
|
||||
|
||||
string modelName = Model.ModelInfo.ModelTypeName;
|
||||
string modelNameUpperVariant = modelName.ToUpperInvariant();
|
||||
string modelNameLowerVariant = modelName.ToLowerInvariant();
|
||||
string pluralModel = Model.ModelInfo.ModelTypePluralName.ToUpperInvariant();
|
||||
string dbContextNamespace = string.IsNullOrEmpty(Model.DbContextInfo.DbContextNamespace) ? string.Empty : Model.DbContextInfo.DbContextNamespace;
|
||||
string dbContextName = Model.DbContextInfo.DbContextClassName;
|
||||
string entitySetName = Model.DbContextInfo.EntitySetVariableName ?? modelName;
|
||||
string modelNamespace = Model.ModelInfo.ModelNamespace;
|
||||
|
||||
this.Write("using Microsoft.AspNetCore.Mvc;\r\nusing Microsoft.EntityFrameworkCore;\r\n");
|
||||
|
||||
if (!string.IsNullOrEmpty(modelNamespace))
|
||||
{
|
||||
|
||||
this.Write("using ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNamespace));
|
||||
this.Write(";\r\n");
|
||||
}
|
||||
|
||||
|
||||
if (!string.IsNullOrEmpty(dbContextNamespace))
|
||||
{
|
||||
|
||||
this.Write("using ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(dbContextNamespace));
|
||||
this.Write(";\r\n");
|
||||
}
|
||||
|
||||
this.Write("\r\n[Route(\"api/[controller]\")]\r\n[ApiController]\r\npublic class ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(Model.ControllerName));
|
||||
this.Write(" : ControllerBase\r\n{\r\n private readonly ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(dbContextName));
|
||||
this.Write(" _context;\r\n\r\n public ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(Model.ControllerName));
|
||||
this.Write("(");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(dbContextName));
|
||||
this.Write(" context)\r\n {\r\n _context = context;\r\n }\r\n\r\n // GET: api/");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelName));
|
||||
this.Write("\r\n [HttpGet]\r\n public async Task<ActionResult<IEnumerable<");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelName));
|
||||
this.Write(">>> Get");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelName));
|
||||
this.Write("()\r\n {\r\n return await _context.");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(entitySetName));
|
||||
this.Write(".ToListAsync();\r\n }\r\n\r\n // GET: api/");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelName));
|
||||
this.Write("/5\r\n [HttpGet(\"{id}\")]\r\n public async Task<ActionResult<");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelName));
|
||||
this.Write(">> Get");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelName));
|
||||
this.Write("(int id)\r\n {\r\n var ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerVariant));
|
||||
this.Write(" = await _context.");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(entitySetName));
|
||||
this.Write(".FindAsync(id);\r\n\r\n if (");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerVariant));
|
||||
this.Write(" == null)\r\n {\r\n return NotFound();\r\n }\r\n\r\n return" +
|
||||
" ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerVariant));
|
||||
this.Write(";\r\n }\r\n\r\n // PUT: api/");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelName));
|
||||
this.Write("/5\r\n // To protect from overposting attacks, see https://go.microsoft.com/fwli" +
|
||||
"nk/?linkid=2123754\r\n [HttpPut(\"{id}\")]\r\n public async Task<IActionResult> " +
|
||||
"Put");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelName));
|
||||
this.Write("(int id, ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelName));
|
||||
this.Write(" ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerVariant));
|
||||
this.Write(")\r\n {\r\n if (id != ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerVariant));
|
||||
this.Write(".ID)\r\n {\r\n return BadRequest();\r\n }\r\n\r\n _context." +
|
||||
"Entry(");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerVariant));
|
||||
this.Write(").State = EntityState.Modified;\r\n\r\n try\r\n {\r\n await _con" +
|
||||
"text.SaveChangesAsync();\r\n }\r\n catch (DbUpdateConcurrencyException" +
|
||||
")\r\n {\r\n if (!");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelName));
|
||||
this.Write("Exists(id))\r\n {\r\n return NotFound();\r\n }\r\n " +
|
||||
" else\r\n {\r\n throw;\r\n }\r\n }\r" +
|
||||
"\n\r\n return NoContent();\r\n }\r\n\r\n // POST: api/");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelName));
|
||||
this.Write("\r\n // To protect from overposting attacks, see https://go.microsoft.com/fwlink" +
|
||||
"/?linkid=2123754\r\n [HttpPost]\r\n public async Task<ActionResult<");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelName));
|
||||
this.Write(">> Post");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelName));
|
||||
this.Write("(");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelName));
|
||||
this.Write(" ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerVariant));
|
||||
this.Write(")\r\n {\r\n _context.");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(entitySetName));
|
||||
this.Write(".Add(");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerVariant));
|
||||
this.Write(");\r\n await _context.SaveChangesAsync();\r\n\r\n return CreatedAtAction(" +
|
||||
"\"Get");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelName));
|
||||
this.Write("\", new { id = ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerVariant));
|
||||
this.Write(".ID }, ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerVariant));
|
||||
this.Write(");\r\n }\r\n\r\n // DELETE: api/");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelName));
|
||||
this.Write("/5\r\n [HttpDelete(\"{id}\")]\r\n public async Task<IActionResult> Delete");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelName));
|
||||
this.Write("(int id)\r\n {\r\n var ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerVariant));
|
||||
this.Write(" = await _context.");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(entitySetName));
|
||||
this.Write(".FindAsync(id);\r\n if (");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerVariant));
|
||||
this.Write(" == null)\r\n {\r\n return NotFound();\r\n }\r\n\r\n _conte" +
|
||||
"xt.");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(entitySetName));
|
||||
this.Write(".Remove(");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerVariant));
|
||||
this.Write(");\r\n await _context.SaveChangesAsync();\r\n\r\n return NoContent();\r\n " +
|
||||
" }\r\n\r\n private bool ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelName));
|
||||
this.Write("Exists(int id)\r\n {\r\n return _context.");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(entitySetName));
|
||||
this.Write(".Any(e => e.ID == id);\r\n }\r\n}\r\n");
|
||||
return this.GenerationEnvironment.ToString();
|
||||
}
|
||||
private global::Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost hostValue;
|
||||
/// <summary>
|
||||
/// The current host for the text templating engine
|
||||
/// </summary>
|
||||
public virtual global::Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost Host
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.hostValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.hostValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
private global::Microsoft.DotNet.Tools.Scaffold.AspNet.Models.EfControllerModel _ModelField;
|
||||
|
||||
/// <summary>
|
||||
/// Access the Model parameter of the template.
|
||||
/// </summary>
|
||||
private global::Microsoft.DotNet.Tools.Scaffold.AspNet.Models.EfControllerModel Model
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._ModelField;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the template
|
||||
/// </summary>
|
||||
public virtual void Initialize()
|
||||
{
|
||||
if ((this.Errors.HasErrors == false))
|
||||
{
|
||||
bool ModelValueAcquired = false;
|
||||
if (this.Session.ContainsKey("Model"))
|
||||
{
|
||||
this._ModelField = ((global::Microsoft.DotNet.Tools.Scaffold.AspNet.Models.EfControllerModel)(this.Session["Model"]));
|
||||
ModelValueAcquired = true;
|
||||
}
|
||||
if ((ModelValueAcquired == false))
|
||||
{
|
||||
string parameterValue = this.Host.ResolveParameterValue("Property", "PropertyDirectiveProcessor", "Model");
|
||||
if ((string.IsNullOrEmpty(parameterValue) == false))
|
||||
{
|
||||
global::System.ComponentModel.TypeConverter tc = global::System.ComponentModel.TypeDescriptor.GetConverter(typeof(global::Microsoft.DotNet.Tools.Scaffold.AspNet.Models.EfControllerModel));
|
||||
if (((tc != null)
|
||||
&& tc.CanConvertFrom(typeof(string))))
|
||||
{
|
||||
this._ModelField = ((global::Microsoft.DotNet.Tools.Scaffold.AspNet.Models.EfControllerModel)(tc.ConvertFrom(parameterValue)));
|
||||
ModelValueAcquired = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Error("The type \'Microsoft.DotNet.Tools.Scaffold.AspNet.Models.EfControllerModel\' of the" +
|
||||
" parameter \'Model\' did not match the type of the data passed to the template.");
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((ModelValueAcquired == false))
|
||||
{
|
||||
object data = global::Microsoft.DotNet.Scaffolding.TextTemplating.CallContext.LogicalGetData("Model");
|
||||
if ((data != null))
|
||||
{
|
||||
this._ModelField = ((global::Microsoft.DotNet.Tools.Scaffold.AspNet.Models.EfControllerModel)(data));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#region Base class
|
||||
/// <summary>
|
||||
/// Base class for this transformation
|
||||
/// </summary>
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")]
|
||||
public class ApiEfControllerBase
|
||||
{
|
||||
#region Fields
|
||||
private global::System.Text.StringBuilder generationEnvironmentField;
|
||||
private global::System.CodeDom.Compiler.CompilerErrorCollection errorsField;
|
||||
private global::System.Collections.Generic.List<int> indentLengthsField;
|
||||
private string currentIndentField = "";
|
||||
private bool endsWithNewline;
|
||||
private global::System.Collections.Generic.IDictionary<string, object> sessionField;
|
||||
#endregion
|
||||
#region Properties
|
||||
/// <summary>
|
||||
/// The string builder that generation-time code is using to assemble generated output
|
||||
/// </summary>
|
||||
public System.Text.StringBuilder GenerationEnvironment
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((this.generationEnvironmentField == null))
|
||||
{
|
||||
this.generationEnvironmentField = new global::System.Text.StringBuilder();
|
||||
}
|
||||
return this.generationEnvironmentField;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.generationEnvironmentField = value;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// The error collection for the generation process
|
||||
/// </summary>
|
||||
public System.CodeDom.Compiler.CompilerErrorCollection Errors
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((this.errorsField == null))
|
||||
{
|
||||
this.errorsField = new global::System.CodeDom.Compiler.CompilerErrorCollection();
|
||||
}
|
||||
return this.errorsField;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// A list of the lengths of each indent that was added with PushIndent
|
||||
/// </summary>
|
||||
private System.Collections.Generic.List<int> indentLengths
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((this.indentLengthsField == null))
|
||||
{
|
||||
this.indentLengthsField = new global::System.Collections.Generic.List<int>();
|
||||
}
|
||||
return this.indentLengthsField;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the current indent we use when adding lines to the output
|
||||
/// </summary>
|
||||
public string CurrentIndent
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentIndentField;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Current transformation session
|
||||
/// </summary>
|
||||
public virtual global::System.Collections.Generic.IDictionary<string, object> Session
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.sessionField;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.sessionField = value;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#region Transform-time helpers
|
||||
/// <summary>
|
||||
/// Write text directly into the generated output
|
||||
/// </summary>
|
||||
public void Write(string textToAppend)
|
||||
{
|
||||
if (string.IsNullOrEmpty(textToAppend))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// If we're starting off, or if the previous text ended with a newline,
|
||||
// we have to append the current indent first.
|
||||
if (((this.GenerationEnvironment.Length == 0)
|
||||
|| this.endsWithNewline))
|
||||
{
|
||||
this.GenerationEnvironment.Append(this.currentIndentField);
|
||||
this.endsWithNewline = false;
|
||||
}
|
||||
// Check if the current text ends with a newline
|
||||
if (textToAppend.EndsWith(global::System.Environment.NewLine, global::System.StringComparison.CurrentCulture))
|
||||
{
|
||||
this.endsWithNewline = true;
|
||||
}
|
||||
// This is an optimization. If the current indent is "", then we don't have to do any
|
||||
// of the more complex stuff further down.
|
||||
if ((this.currentIndentField.Length == 0))
|
||||
{
|
||||
this.GenerationEnvironment.Append(textToAppend);
|
||||
return;
|
||||
}
|
||||
// Everywhere there is a newline in the text, add an indent after it
|
||||
textToAppend = textToAppend.Replace(global::System.Environment.NewLine, (global::System.Environment.NewLine + this.currentIndentField));
|
||||
// If the text ends with a newline, then we should strip off the indent added at the very end
|
||||
// because the appropriate indent will be added when the next time Write() is called
|
||||
if (this.endsWithNewline)
|
||||
{
|
||||
this.GenerationEnvironment.Append(textToAppend, 0, (textToAppend.Length - this.currentIndentField.Length));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.GenerationEnvironment.Append(textToAppend);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Write text directly into the generated output
|
||||
/// </summary>
|
||||
public void WriteLine(string textToAppend)
|
||||
{
|
||||
this.Write(textToAppend);
|
||||
this.GenerationEnvironment.AppendLine();
|
||||
this.endsWithNewline = true;
|
||||
}
|
||||
/// <summary>
|
||||
/// Write formatted text directly into the generated output
|
||||
/// </summary>
|
||||
public void Write(string format, params object[] args)
|
||||
{
|
||||
this.Write(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args));
|
||||
}
|
||||
/// <summary>
|
||||
/// Write formatted text directly into the generated output
|
||||
/// </summary>
|
||||
public void WriteLine(string format, params object[] args)
|
||||
{
|
||||
this.WriteLine(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args));
|
||||
}
|
||||
/// <summary>
|
||||
/// Raise an error
|
||||
/// </summary>
|
||||
public void Error(string message)
|
||||
{
|
||||
System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError();
|
||||
error.ErrorText = message;
|
||||
this.Errors.Add(error);
|
||||
}
|
||||
/// <summary>
|
||||
/// Raise a warning
|
||||
/// </summary>
|
||||
public void Warning(string message)
|
||||
{
|
||||
System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError();
|
||||
error.ErrorText = message;
|
||||
error.IsWarning = true;
|
||||
this.Errors.Add(error);
|
||||
}
|
||||
/// <summary>
|
||||
/// Increase the indent
|
||||
/// </summary>
|
||||
public void PushIndent(string indent)
|
||||
{
|
||||
if ((indent == null))
|
||||
{
|
||||
throw new global::System.ArgumentNullException("indent");
|
||||
}
|
||||
this.currentIndentField = (this.currentIndentField + indent);
|
||||
this.indentLengths.Add(indent.Length);
|
||||
}
|
||||
/// <summary>
|
||||
/// Remove the last indent that was added with PushIndent
|
||||
/// </summary>
|
||||
public string PopIndent()
|
||||
{
|
||||
string returnValue = "";
|
||||
if ((this.indentLengths.Count > 0))
|
||||
{
|
||||
int indentLength = this.indentLengths[(this.indentLengths.Count - 1)];
|
||||
this.indentLengths.RemoveAt((this.indentLengths.Count - 1));
|
||||
if ((indentLength > 0))
|
||||
{
|
||||
returnValue = this.currentIndentField.Substring((this.currentIndentField.Length - indentLength));
|
||||
this.currentIndentField = this.currentIndentField.Remove((this.currentIndentField.Length - indentLength));
|
||||
}
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
/// <summary>
|
||||
/// Remove any indentation
|
||||
/// </summary>
|
||||
public void ClearIndent()
|
||||
{
|
||||
this.indentLengths.Clear();
|
||||
this.currentIndentField = "";
|
||||
}
|
||||
#endregion
|
||||
#region ToString Helpers
|
||||
/// <summary>
|
||||
/// Utility class to produce culture-oriented representation of an object as a string.
|
||||
/// </summary>
|
||||
public class ToStringInstanceHelper
|
||||
{
|
||||
private System.IFormatProvider formatProviderField = global::System.Globalization.CultureInfo.InvariantCulture;
|
||||
/// <summary>
|
||||
/// Gets or sets format provider to be used by ToStringWithCulture method.
|
||||
/// </summary>
|
||||
public System.IFormatProvider FormatProvider
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.formatProviderField ;
|
||||
}
|
||||
set
|
||||
{
|
||||
if ((value != null))
|
||||
{
|
||||
this.formatProviderField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// This is called from the compile/run appdomain to convert objects within an expression block to a string
|
||||
/// </summary>
|
||||
public string ToStringWithCulture(object objectToConvert)
|
||||
{
|
||||
if ((objectToConvert == null))
|
||||
{
|
||||
throw new global::System.ArgumentNullException("objectToConvert");
|
||||
}
|
||||
System.Type t = objectToConvert.GetType();
|
||||
System.Reflection.MethodInfo method = t.GetMethod("ToString", new System.Type[] {
|
||||
typeof(System.IFormatProvider)});
|
||||
if ((method == null))
|
||||
{
|
||||
return objectToConvert.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return ((string)(method.Invoke(objectToConvert, new object[] {
|
||||
this.formatProviderField })));
|
||||
}
|
||||
}
|
||||
}
|
||||
private ToStringInstanceHelper toStringHelperField = new ToStringInstanceHelper();
|
||||
/// <summary>
|
||||
/// Helper to produce culture-oriented representation of an object as a string
|
||||
/// </summary>
|
||||
public ToStringInstanceHelper ToStringHelper
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.toStringHelperField;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
<#@ template hostSpecific="true" linePragmas="false" #>
|
||||
<#@ parameter type="Microsoft.DotNet.Tools.Scaffold.AspNet.Models.EfControllerModel" name="Model" #>
|
||||
<#@ import namespace="System.Collections.Generic" #>
|
||||
<#@ import namespace="System.Text" #>
|
||||
<#@ import namespace="System.Linq" #>
|
||||
<#
|
||||
string modelName = Model.ModelInfo.ModelTypeName;
|
||||
string modelNameUpperVariant = modelName.ToUpperInvariant();
|
||||
string modelNameLowerVariant = modelName.ToLowerInvariant();
|
||||
string pluralModel = Model.ModelInfo.ModelTypePluralName.ToUpperInvariant();
|
||||
string dbContextNamespace = string.IsNullOrEmpty(Model.DbContextInfo.DbContextNamespace) ? string.Empty : Model.DbContextInfo.DbContextNamespace;
|
||||
string dbContextName = Model.DbContextInfo.DbContextClassName;
|
||||
string entitySetName = Model.DbContextInfo.EntitySetVariableName ?? modelName;
|
||||
string modelNamespace = Model.ModelInfo.ModelNamespace;
|
||||
#>
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
<#
|
||||
if (!string.IsNullOrEmpty(modelNamespace))
|
||||
{
|
||||
#>using <#= modelNamespace #>;
|
||||
<# }
|
||||
#>
|
||||
<#
|
||||
if (!string.IsNullOrEmpty(dbContextNamespace))
|
||||
{
|
||||
#>using <#= dbContextNamespace #>;
|
||||
<# }
|
||||
#>
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class <#= Model.ControllerName #> : ControllerBase
|
||||
{
|
||||
private readonly <#= dbContextName #> _context;
|
||||
|
||||
public <#= Model.ControllerName #>(<#= dbContextName #> context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
// GET: api/<#= modelName #>
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<IEnumerable<<#= modelName #>>>> Get<#= modelName #>()
|
||||
{
|
||||
return await _context.<#= entitySetName #>.ToListAsync();
|
||||
}
|
||||
|
||||
// GET: api/<#= modelName #>/5
|
||||
[HttpGet("{id}")]
|
||||
public async Task<ActionResult<<#= modelName #>>> Get<#= modelName #>(int id)
|
||||
{
|
||||
var <#= modelNameLowerVariant #> = await _context.<#= entitySetName #>.FindAsync(id);
|
||||
|
||||
if (<#= modelNameLowerVariant #> == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return <#= modelNameLowerVariant #>;
|
||||
}
|
||||
|
||||
// PUT: api/<#= modelName #>/5
|
||||
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
|
||||
[HttpPut("{id}")]
|
||||
public async Task<IActionResult> Put<#= modelName #>(int id, <#= modelName #> <#= modelNameLowerVariant #>)
|
||||
{
|
||||
if (id != <#= modelNameLowerVariant #>.ID)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
_context.Entry(<#= modelNameLowerVariant #>).State = EntityState.Modified;
|
||||
|
||||
try
|
||||
{
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
catch (DbUpdateConcurrencyException)
|
||||
{
|
||||
if (!<#= modelName #>Exists(id))
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
// POST: api/<#= modelName #>
|
||||
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<<#= modelName #>>> Post<#= modelName #>(<#= modelName #> <#= modelNameLowerVariant #>)
|
||||
{
|
||||
_context.<#= entitySetName #>.Add(<#= modelNameLowerVariant #>);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return CreatedAtAction("Get<#= modelName #>", new { id = <#= modelNameLowerVariant #>.ID }, <#= modelNameLowerVariant #>);
|
||||
}
|
||||
|
||||
// DELETE: api/<#= modelName #>/5
|
||||
[HttpDelete("{id}")]
|
||||
public async Task<IActionResult> Delete<#= modelName #>(int id)
|
||||
{
|
||||
var <#= modelNameLowerVariant #> = await _context.<#= entitySetName #>.FindAsync(id);
|
||||
if (<#= modelNameLowerVariant #> == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
_context.<#= entitySetName #>.Remove(<#= modelNameLowerVariant #>);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
private bool <#= modelName #>Exists(int id)
|
||||
{
|
||||
return _context.<#= entitySetName #>.Any(e => e.ID == id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
using Microsoft.DotNet.Scaffolding.TextTemplating;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Scaffold.AspNet.Templates.EfController;
|
||||
|
||||
public partial class MvcEfController : ITextTransformation
|
||||
{
|
||||
}
|
|
@ -0,0 +1,535 @@
|
|||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version: 17.0.0.0
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
// ------------------------------------------------------------------------------
|
||||
namespace Microsoft.DotNet.Tools.Scaffold.AspNet.Templates.EfController
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Class to produce the template output
|
||||
/// </summary>
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")]
|
||||
public partial class MvcEfController : MvcEfControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Create the template output
|
||||
/// </summary>
|
||||
public virtual string TransformText()
|
||||
{
|
||||
|
||||
string modelName = Model.ModelInfo.ModelTypeName;
|
||||
string modelNameUpperVariant = modelName.ToUpperInvariant();
|
||||
string pluralModel = Model.ModelInfo.ModelTypePluralName.ToUpperInvariant();
|
||||
string modelNameLowerInv = modelName.ToLowerInvariant();
|
||||
string dbContextNamespace = string.IsNullOrEmpty(Model.DbContextInfo.DbContextNamespace) ? string.Empty : Model.DbContextInfo.DbContextNamespace;
|
||||
string dbContextName = Model.DbContextInfo.DbContextClassName;
|
||||
string entitySetName = Model.DbContextInfo.EntitySetVariableName ?? modelName;
|
||||
string modelNamespace = Model.ModelInfo.ModelNamespace;
|
||||
string primaryKeyName = Model.ModelInfo.PrimaryKeyName;
|
||||
string primaryKeyNameLowerCase = primaryKeyName.ToLowerInvariant();
|
||||
string primaryKeyShortTypeName = Model.ModelInfo.PrimaryKeyShortTypeName;
|
||||
string primaryKeyType = Model.ModelInfo.PrimaryKeyTypeName;
|
||||
|
||||
this.Write("\r\nusing Microsoft.AspNetCore.Mvc;\r\nusing Microsoft.EntityFrameworkCore;\r\n");
|
||||
|
||||
if (!string.IsNullOrEmpty(modelNamespace))
|
||||
{
|
||||
|
||||
this.Write("using ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNamespace));
|
||||
this.Write(";\r\n");
|
||||
}
|
||||
|
||||
|
||||
if (!string.IsNullOrEmpty(dbContextNamespace))
|
||||
{
|
||||
|
||||
this.Write("using ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(dbContextNamespace));
|
||||
this.Write(";\r\n");
|
||||
}
|
||||
|
||||
this.Write("\r\npublic class ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(Model.ControllerName));
|
||||
this.Write(" : Controller\r\n{\r\n private readonly ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(dbContextName));
|
||||
this.Write(" _context;\r\n\r\n public ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(Model.ControllerName));
|
||||
this.Write("(");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(dbContextName));
|
||||
this.Write(" context)\r\n {\r\n _context = context;\r\n }\r\n\r\n // GET: ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(pluralModel));
|
||||
this.Write("\r\n public async Task<IActionResult> Index() \r\n {\r\n return View(aw" +
|
||||
"ait _context.");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(entitySetName));
|
||||
this.Write(".ToListAsync());\r\n }\r\n\r\n // GET: ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(pluralModel));
|
||||
this.Write("/Details/5\r\n public async Task<IActionResult> Details(int? id)\r\n {\r\n " +
|
||||
" if (id == null)\r\n {\r\n return NotFound();\r\n }\r\n\r\n " +
|
||||
" var ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerInv));
|
||||
this.Write(" = await _context.");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(entitySetName));
|
||||
this.Write("\r\n .FirstOrDefaultAsync(m => m.ID == id);\r\n if (");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerInv));
|
||||
this.Write(" == null)\r\n {\r\n return NotFound();\r\n }\r\n\r\n return" +
|
||||
" View(");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerInv));
|
||||
this.Write(");\r\n }\r\n\r\n // GET: ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(pluralModel));
|
||||
this.Write("/Create\r\n public IActionResult Create()\r\n {\r\n return View();\r\n }\r" +
|
||||
"\n\r\n // POST: ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(pluralModel));
|
||||
this.Write(@"/Create
|
||||
// To protect from overposting attacks, 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(""ID,Title,ReleaseDate,Genre,Price"")] ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelName));
|
||||
this.Write(" movie)\r\n {\r\n if (ModelState.IsValid)\r\n {\r\n _context." +
|
||||
"Add(");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerInv));
|
||||
this.Write(");\r\n await _context.SaveChangesAsync();\r\n return RedirectTo" +
|
||||
"Action(nameof(Index));\r\n }\r\n return View(");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerInv));
|
||||
this.Write(");\r\n }\r\n\r\n // GET: ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(pluralModel));
|
||||
this.Write("/Edit/5\r\n public async Task<IActionResult> Edit(int? id)\r\n {\r\n if (i" +
|
||||
"d == null)\r\n {\r\n return NotFound();\r\n }\r\n\r\n var " +
|
||||
"");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerInv));
|
||||
this.Write(" = await _context.");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(entitySetName));
|
||||
this.Write(".FindAsync(id);\r\n if (");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerInv));
|
||||
this.Write(" == null)\r\n {\r\n return NotFound();\r\n }\r\n return V" +
|
||||
"iew(");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerInv));
|
||||
this.Write(");\r\n }\r\n\r\n // POST: ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(pluralModel));
|
||||
this.Write(@"/Edit/5
|
||||
// To protect from overposting attacks, 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(int id, [Bind(""ID,Title,ReleaseDate,Genre,Price"")] ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelName));
|
||||
this.Write(" movie)\r\n {\r\n if (id != ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerInv));
|
||||
this.Write(".ID)\r\n {\r\n return NotFound();\r\n }\r\n\r\n if (ModelSt" +
|
||||
"ate.IsValid)\r\n {\r\n try\r\n {\r\n _contex" +
|
||||
"t.Update(");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerInv));
|
||||
this.Write(");\r\n await _context.SaveChangesAsync();\r\n }\r\n " +
|
||||
" catch (DbUpdateConcurrencyException)\r\n {\r\n if (!");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameUpperVariant));
|
||||
this.Write("Exists(");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerInv));
|
||||
this.Write(@".ID))
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
return View(");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerInv));
|
||||
this.Write(");\r\n }\r\n\r\n // GET: ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(pluralModel));
|
||||
this.Write("/Delete/5\r\n public async Task<IActionResult> Delete(int? id)\r\n {\r\n i" +
|
||||
"f (id == null)\r\n {\r\n return NotFound();\r\n }\r\n\r\n " +
|
||||
"var ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerInv));
|
||||
this.Write(" = await _context.");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(entitySetName));
|
||||
this.Write("\r\n .FirstOrDefaultAsync(m => m.ID == id);\r\n if (");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerInv));
|
||||
this.Write(" == null)\r\n {\r\n return NotFound();\r\n }\r\n\r\n return" +
|
||||
" View(");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerInv));
|
||||
this.Write(");\r\n }\r\n\r\n // POST: ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(pluralModel));
|
||||
this.Write("/Delete/5\r\n [HttpPost, ActionName(\"Delete\")]\r\n [ValidateAntiForgeryToken]\r\n" +
|
||||
" public async Task<IActionResult> DeleteConfirmed(int id)\r\n {\r\n var" +
|
||||
" ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerInv));
|
||||
this.Write(" = await _context.");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(entitySetName));
|
||||
this.Write(".FindAsync(id);\r\n if (");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerInv));
|
||||
this.Write(" != null)\r\n {\r\n _context.");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(entitySetName));
|
||||
this.Write(".Remove(");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameLowerInv));
|
||||
this.Write(");\r\n }\r\n\r\n await _context.SaveChangesAsync();\r\n return Redir" +
|
||||
"ectToAction(nameof(Index));\r\n }\r\n\r\n private bool ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(modelNameUpperVariant));
|
||||
this.Write("Exists(int id)\r\n {\r\n return _context.");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(entitySetName));
|
||||
this.Write(".Any(e => e.ID == id);\r\n }\r\n}\r\n");
|
||||
return this.GenerationEnvironment.ToString();
|
||||
}
|
||||
private global::Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost hostValue;
|
||||
/// <summary>
|
||||
/// The current host for the text templating engine
|
||||
/// </summary>
|
||||
public virtual global::Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost Host
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.hostValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.hostValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
private global::Microsoft.DotNet.Tools.Scaffold.AspNet.Models.EfControllerModel _ModelField;
|
||||
|
||||
/// <summary>
|
||||
/// Access the Model parameter of the template.
|
||||
/// </summary>
|
||||
private global::Microsoft.DotNet.Tools.Scaffold.AspNet.Models.EfControllerModel Model
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._ModelField;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the template
|
||||
/// </summary>
|
||||
public virtual void Initialize()
|
||||
{
|
||||
if ((this.Errors.HasErrors == false))
|
||||
{
|
||||
bool ModelValueAcquired = false;
|
||||
if (this.Session.ContainsKey("Model"))
|
||||
{
|
||||
this._ModelField = ((global::Microsoft.DotNet.Tools.Scaffold.AspNet.Models.EfControllerModel)(this.Session["Model"]));
|
||||
ModelValueAcquired = true;
|
||||
}
|
||||
if ((ModelValueAcquired == false))
|
||||
{
|
||||
string parameterValue = this.Host.ResolveParameterValue("Property", "PropertyDirectiveProcessor", "Model");
|
||||
if ((string.IsNullOrEmpty(parameterValue) == false))
|
||||
{
|
||||
global::System.ComponentModel.TypeConverter tc = global::System.ComponentModel.TypeDescriptor.GetConverter(typeof(global::Microsoft.DotNet.Tools.Scaffold.AspNet.Models.EfControllerModel));
|
||||
if (((tc != null)
|
||||
&& tc.CanConvertFrom(typeof(string))))
|
||||
{
|
||||
this._ModelField = ((global::Microsoft.DotNet.Tools.Scaffold.AspNet.Models.EfControllerModel)(tc.ConvertFrom(parameterValue)));
|
||||
ModelValueAcquired = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Error("The type \'Microsoft.DotNet.Tools.Scaffold.AspNet.Models.EfControllerModel\' of the" +
|
||||
" parameter \'Model\' did not match the type of the data passed to the template.");
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((ModelValueAcquired == false))
|
||||
{
|
||||
object data = global::Microsoft.DotNet.Scaffolding.TextTemplating.CallContext.LogicalGetData("Model");
|
||||
if ((data != null))
|
||||
{
|
||||
this._ModelField = ((global::Microsoft.DotNet.Tools.Scaffold.AspNet.Models.EfControllerModel)(data));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#region Base class
|
||||
/// <summary>
|
||||
/// Base class for this transformation
|
||||
/// </summary>
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")]
|
||||
public class MvcEfControllerBase
|
||||
{
|
||||
#region Fields
|
||||
private global::System.Text.StringBuilder generationEnvironmentField;
|
||||
private global::System.CodeDom.Compiler.CompilerErrorCollection errorsField;
|
||||
private global::System.Collections.Generic.List<int> indentLengthsField;
|
||||
private string currentIndentField = "";
|
||||
private bool endsWithNewline;
|
||||
private global::System.Collections.Generic.IDictionary<string, object> sessionField;
|
||||
#endregion
|
||||
#region Properties
|
||||
/// <summary>
|
||||
/// The string builder that generation-time code is using to assemble generated output
|
||||
/// </summary>
|
||||
public System.Text.StringBuilder GenerationEnvironment
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((this.generationEnvironmentField == null))
|
||||
{
|
||||
this.generationEnvironmentField = new global::System.Text.StringBuilder();
|
||||
}
|
||||
return this.generationEnvironmentField;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.generationEnvironmentField = value;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// The error collection for the generation process
|
||||
/// </summary>
|
||||
public System.CodeDom.Compiler.CompilerErrorCollection Errors
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((this.errorsField == null))
|
||||
{
|
||||
this.errorsField = new global::System.CodeDom.Compiler.CompilerErrorCollection();
|
||||
}
|
||||
return this.errorsField;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// A list of the lengths of each indent that was added with PushIndent
|
||||
/// </summary>
|
||||
private System.Collections.Generic.List<int> indentLengths
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((this.indentLengthsField == null))
|
||||
{
|
||||
this.indentLengthsField = new global::System.Collections.Generic.List<int>();
|
||||
}
|
||||
return this.indentLengthsField;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the current indent we use when adding lines to the output
|
||||
/// </summary>
|
||||
public string CurrentIndent
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentIndentField;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Current transformation session
|
||||
/// </summary>
|
||||
public virtual global::System.Collections.Generic.IDictionary<string, object> Session
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.sessionField;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.sessionField = value;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#region Transform-time helpers
|
||||
/// <summary>
|
||||
/// Write text directly into the generated output
|
||||
/// </summary>
|
||||
public void Write(string textToAppend)
|
||||
{
|
||||
if (string.IsNullOrEmpty(textToAppend))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// If we're starting off, or if the previous text ended with a newline,
|
||||
// we have to append the current indent first.
|
||||
if (((this.GenerationEnvironment.Length == 0)
|
||||
|| this.endsWithNewline))
|
||||
{
|
||||
this.GenerationEnvironment.Append(this.currentIndentField);
|
||||
this.endsWithNewline = false;
|
||||
}
|
||||
// Check if the current text ends with a newline
|
||||
if (textToAppend.EndsWith(global::System.Environment.NewLine, global::System.StringComparison.CurrentCulture))
|
||||
{
|
||||
this.endsWithNewline = true;
|
||||
}
|
||||
// This is an optimization. If the current indent is "", then we don't have to do any
|
||||
// of the more complex stuff further down.
|
||||
if ((this.currentIndentField.Length == 0))
|
||||
{
|
||||
this.GenerationEnvironment.Append(textToAppend);
|
||||
return;
|
||||
}
|
||||
// Everywhere there is a newline in the text, add an indent after it
|
||||
textToAppend = textToAppend.Replace(global::System.Environment.NewLine, (global::System.Environment.NewLine + this.currentIndentField));
|
||||
// If the text ends with a newline, then we should strip off the indent added at the very end
|
||||
// because the appropriate indent will be added when the next time Write() is called
|
||||
if (this.endsWithNewline)
|
||||
{
|
||||
this.GenerationEnvironment.Append(textToAppend, 0, (textToAppend.Length - this.currentIndentField.Length));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.GenerationEnvironment.Append(textToAppend);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Write text directly into the generated output
|
||||
/// </summary>
|
||||
public void WriteLine(string textToAppend)
|
||||
{
|
||||
this.Write(textToAppend);
|
||||
this.GenerationEnvironment.AppendLine();
|
||||
this.endsWithNewline = true;
|
||||
}
|
||||
/// <summary>
|
||||
/// Write formatted text directly into the generated output
|
||||
/// </summary>
|
||||
public void Write(string format, params object[] args)
|
||||
{
|
||||
this.Write(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args));
|
||||
}
|
||||
/// <summary>
|
||||
/// Write formatted text directly into the generated output
|
||||
/// </summary>
|
||||
public void WriteLine(string format, params object[] args)
|
||||
{
|
||||
this.WriteLine(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args));
|
||||
}
|
||||
/// <summary>
|
||||
/// Raise an error
|
||||
/// </summary>
|
||||
public void Error(string message)
|
||||
{
|
||||
System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError();
|
||||
error.ErrorText = message;
|
||||
this.Errors.Add(error);
|
||||
}
|
||||
/// <summary>
|
||||
/// Raise a warning
|
||||
/// </summary>
|
||||
public void Warning(string message)
|
||||
{
|
||||
System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError();
|
||||
error.ErrorText = message;
|
||||
error.IsWarning = true;
|
||||
this.Errors.Add(error);
|
||||
}
|
||||
/// <summary>
|
||||
/// Increase the indent
|
||||
/// </summary>
|
||||
public void PushIndent(string indent)
|
||||
{
|
||||
if ((indent == null))
|
||||
{
|
||||
throw new global::System.ArgumentNullException("indent");
|
||||
}
|
||||
this.currentIndentField = (this.currentIndentField + indent);
|
||||
this.indentLengths.Add(indent.Length);
|
||||
}
|
||||
/// <summary>
|
||||
/// Remove the last indent that was added with PushIndent
|
||||
/// </summary>
|
||||
public string PopIndent()
|
||||
{
|
||||
string returnValue = "";
|
||||
if ((this.indentLengths.Count > 0))
|
||||
{
|
||||
int indentLength = this.indentLengths[(this.indentLengths.Count - 1)];
|
||||
this.indentLengths.RemoveAt((this.indentLengths.Count - 1));
|
||||
if ((indentLength > 0))
|
||||
{
|
||||
returnValue = this.currentIndentField.Substring((this.currentIndentField.Length - indentLength));
|
||||
this.currentIndentField = this.currentIndentField.Remove((this.currentIndentField.Length - indentLength));
|
||||
}
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
/// <summary>
|
||||
/// Remove any indentation
|
||||
/// </summary>
|
||||
public void ClearIndent()
|
||||
{
|
||||
this.indentLengths.Clear();
|
||||
this.currentIndentField = "";
|
||||
}
|
||||
#endregion
|
||||
#region ToString Helpers
|
||||
/// <summary>
|
||||
/// Utility class to produce culture-oriented representation of an object as a string.
|
||||
/// </summary>
|
||||
public class ToStringInstanceHelper
|
||||
{
|
||||
private System.IFormatProvider formatProviderField = global::System.Globalization.CultureInfo.InvariantCulture;
|
||||
/// <summary>
|
||||
/// Gets or sets format provider to be used by ToStringWithCulture method.
|
||||
/// </summary>
|
||||
public System.IFormatProvider FormatProvider
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.formatProviderField ;
|
||||
}
|
||||
set
|
||||
{
|
||||
if ((value != null))
|
||||
{
|
||||
this.formatProviderField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// This is called from the compile/run appdomain to convert objects within an expression block to a string
|
||||
/// </summary>
|
||||
public string ToStringWithCulture(object objectToConvert)
|
||||
{
|
||||
if ((objectToConvert == null))
|
||||
{
|
||||
throw new global::System.ArgumentNullException("objectToConvert");
|
||||
}
|
||||
System.Type t = objectToConvert.GetType();
|
||||
System.Reflection.MethodInfo method = t.GetMethod("ToString", new System.Type[] {
|
||||
typeof(System.IFormatProvider)});
|
||||
if ((method == null))
|
||||
{
|
||||
return objectToConvert.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return ((string)(method.Invoke(objectToConvert, new object[] {
|
||||
this.formatProviderField })));
|
||||
}
|
||||
}
|
||||
}
|
||||
private ToStringInstanceHelper toStringHelperField = new ToStringInstanceHelper();
|
||||
/// <summary>
|
||||
/// Helper to produce culture-oriented representation of an object as a string
|
||||
/// </summary>
|
||||
public ToStringInstanceHelper ToStringHelper
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.toStringHelperField;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
}
|
|
@ -0,0 +1,179 @@
|
|||
<#@ template hostSpecific="true" linePragmas="false" #>
|
||||
<#@ parameter type="Microsoft.DotNet.Tools.Scaffold.AspNet.Models.EfControllerModel" name="Model" #>
|
||||
<#@ import namespace="System.Collections.Generic" #>
|
||||
<#@ import namespace="System.Text" #>
|
||||
<#@ import namespace="System.Linq" #>
|
||||
<#
|
||||
string modelName = Model.ModelInfo.ModelTypeName;
|
||||
string modelNameUpperVariant = modelName.ToUpperInvariant();
|
||||
string pluralModel = Model.ModelInfo.ModelTypePluralName.ToUpperInvariant();
|
||||
string modelNameLowerInv = modelName.ToLowerInvariant();
|
||||
string dbContextNamespace = string.IsNullOrEmpty(Model.DbContextInfo.DbContextNamespace) ? string.Empty : Model.DbContextInfo.DbContextNamespace;
|
||||
string dbContextName = Model.DbContextInfo.DbContextClassName;
|
||||
string entitySetName = Model.DbContextInfo.EntitySetVariableName ?? modelName;
|
||||
string modelNamespace = Model.ModelInfo.ModelNamespace;
|
||||
string primaryKeyName = Model.ModelInfo.PrimaryKeyName;
|
||||
string primaryKeyNameLowerCase = primaryKeyName.ToLowerInvariant();
|
||||
string primaryKeyShortTypeName = Model.ModelInfo.PrimaryKeyShortTypeName;
|
||||
string primaryKeyType = Model.ModelInfo.PrimaryKeyTypeName;
|
||||
#>
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
<#
|
||||
if (!string.IsNullOrEmpty(modelNamespace))
|
||||
{
|
||||
#>using <#= modelNamespace #>;
|
||||
<# }
|
||||
#>
|
||||
<#
|
||||
if (!string.IsNullOrEmpty(dbContextNamespace))
|
||||
{
|
||||
#>using <#= dbContextNamespace #>;
|
||||
<# }
|
||||
#>
|
||||
|
||||
public class <#= Model.ControllerName #> : Controller
|
||||
{
|
||||
private readonly <#= dbContextName #> _context;
|
||||
|
||||
public <#= Model.ControllerName #>(<#= dbContextName #> context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
// GET: <#= pluralModel #>
|
||||
public async Task<IActionResult> Index()
|
||||
{
|
||||
return View(await _context.<#= entitySetName #>.ToListAsync());
|
||||
}
|
||||
|
||||
// GET: <#= pluralModel #>/Details/5
|
||||
public async Task<IActionResult> Details(int? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var <#= modelNameLowerInv #> = await _context.<#= entitySetName #>
|
||||
.FirstOrDefaultAsync(m => m.ID == id);
|
||||
if (<#= modelNameLowerInv #> == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return View(<#= modelNameLowerInv #>);
|
||||
}
|
||||
|
||||
// GET: <#= pluralModel #>/Create
|
||||
public IActionResult Create()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
// POST: <#= pluralModel #>/Create
|
||||
// To protect from overposting attacks, 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("ID,Title,ReleaseDate,Genre,Price")] <#= modelName #> movie)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
_context.Add(<#= modelNameLowerInv #>);
|
||||
await _context.SaveChangesAsync();
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
return View(<#= modelNameLowerInv #>);
|
||||
}
|
||||
|
||||
// GET: <#= pluralModel #>/Edit/5
|
||||
public async Task<IActionResult> Edit(int? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var <#= modelNameLowerInv #> = await _context.<#= entitySetName #>.FindAsync(id);
|
||||
if (<#= modelNameLowerInv #> == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
return View(<#= modelNameLowerInv #>);
|
||||
}
|
||||
|
||||
// POST: <#= pluralModel #>/Edit/5
|
||||
// To protect from overposting attacks, 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(int id, [Bind("ID,Title,ReleaseDate,Genre,Price")] <#= modelName #> movie)
|
||||
{
|
||||
if (id != <#= modelNameLowerInv #>.ID)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
try
|
||||
{
|
||||
_context.Update(<#= modelNameLowerInv #>);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
catch (DbUpdateConcurrencyException)
|
||||
{
|
||||
if (!<#= modelNameUpperVariant #>Exists(<#= modelNameLowerInv #>.ID))
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
return View(<#= modelNameLowerInv #>);
|
||||
}
|
||||
|
||||
// GET: <#= pluralModel #>/Delete/5
|
||||
public async Task<IActionResult> Delete(int? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var <#= modelNameLowerInv #> = await _context.<#= entitySetName #>
|
||||
.FirstOrDefaultAsync(m => m.ID == id);
|
||||
if (<#= modelNameLowerInv #> == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return View(<#= modelNameLowerInv #>);
|
||||
}
|
||||
|
||||
// POST: <#= pluralModel #>/Delete/5
|
||||
[HttpPost, ActionName("Delete")]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> DeleteConfirmed(int id)
|
||||
{
|
||||
var <#= modelNameLowerInv #> = await _context.<#= entitySetName #>.FindAsync(id);
|
||||
if (<#= modelNameLowerInv #> != null)
|
||||
{
|
||||
_context.<#= entitySetName #>.Remove(<#= modelNameLowerInv #>);
|
||||
}
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
|
||||
private bool <#= modelNameUpperVariant #>Exists(int id)
|
||||
{
|
||||
return _context.<#= entitySetName #>.Any(e => e.ID == id);
|
||||
}
|
||||
}
|
|
@ -24,10 +24,14 @@
|
|||
<None Pack="true" Include="$(RepoRoot)src\dotnet-scaffolding\dotnet-scaffold-aspnet\Templates\*\*.tt" PackagePath="Templates\" />
|
||||
<None Pack="true" Include="$(RepoRoot)src\dotnet-scaffolding\Microsoft.DotNet.Scaffolding.TextTemplating\DbContext\*.tt" PackagePath="Templates\DbContext\" />
|
||||
<None Pack="true" Include="CodeModificationConfigs\*.json" PackagePath="CodeModificationConfigs\" />
|
||||
<None Pack="true" Include="README.md" PackagePath="\"/>
|
||||
<None Pack="true" Include="README.md" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Templates\EfController\ApiEfController.tt">
|
||||
<Generator>TextTemplatingFilePreprocessor</Generator>
|
||||
<LastGenOutput>ApiEfController.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Update="Templates\BlazorCrud\Create.tt">
|
||||
<LastGenOutput>Create.cs</LastGenOutput>
|
||||
<Generator>TextTemplatingFilePreprocessor</Generator>
|
||||
|
@ -55,6 +59,11 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Templates\EfController\ApiEfController.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>ApiEfController.tt</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Templates\BlazorCrud\Create.cs">
|
||||
<DependentUpon>Create.tt</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
|
@ -90,6 +99,11 @@
|
|||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>MinimalApiEf.tt</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Templates\EfController\MvcEfController.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>MvcEfController.tt</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -97,6 +111,9 @@
|
|||
<Generator>TextTemplatingFilePreprocessor</Generator>
|
||||
<LastGenOutput>MinimalApiEf.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Update="Templates\EfController\MvcEfController.tt">
|
||||
<Generator>TextTemplatingFilePreprocessor</Generator>
|
||||
<LastGenOutput>MvcEfController.cs</LastGenOutput>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
Загрузка…
Ссылка в новой задаче