diff --git a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Models/BlazorCrudModel.cs b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Models/BlazorCrudModel.cs index f378584589..9ad21e561a 100644 --- a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Models/BlazorCrudModel.cs +++ b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Models/BlazorCrudModel.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.CodeAnalysis; + namespace Microsoft.DotNet.Tools.Scaffold.AspNet.Models; /// @@ -20,9 +22,15 @@ internal class BlazorCrudModel : CrudModel /// Used in BlazorCrud Create/Edit templates. /// /// The .NET type name (e.g., "string", "int"). + /// Whether the type is an enum. /// The Blazor input component type (e.g., "InputText"). - public string GetInputType(string inputType) + public string GetInputType(string inputType, bool isEnum = false) { + if (isEnum) + { + return "InputSelect"; + } + if (string.IsNullOrEmpty(inputType)) { return "InputText"; @@ -58,6 +66,24 @@ public string GetInputType(string inputType) } } + /// + /// Determines whether a Roslyn type symbol represents an enum or nullable enum. + /// + public bool IsEnumType(ITypeSymbol typeSymbol) + { + return typeSymbol.TypeKind == TypeKind.Enum || IsNullableEnumType(typeSymbol); + } + + /// + /// Determines whether a Roslyn type symbol represents a nullable enum. + /// + public bool IsNullableEnumType(ITypeSymbol typeSymbol) + { + return typeSymbol is INamedTypeSymbol namedType && + namedType.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T && + namedType.TypeArguments[0].TypeKind == TypeKind.Enum; + } + //used to get correct form class to add to BlazorCrud\Create.tt and BlazorCrud\Edit.tt template /// /// Gets the correct CSS class for a Blazor input component based on the .NET type name. diff --git a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net10.0/BlazorCrud/Create.cs b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net10.0/BlazorCrud/Create.cs index e96481fcfa..f19d7986e7 100644 --- a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net10.0/BlazorCrud/Create.cs +++ b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net10.0/BlazorCrud/Create.cs @@ -68,7 +68,9 @@ public virtual string TransformText() string modelPropertyName = property.Name; string modelPropertyNameLowercase = modelPropertyName.ToLowerInvariant(); string propertyShortTypeName = property.Type.ToDisplayString().Replace("?", string.Empty); - var inputTypeName = Model.GetInputType(propertyShortTypeName); + var isEnum = Model.IsEnumType(property.Type); + var isNullableEnum = Model.IsNullableEnumType(property.Type); + var inputTypeName = Model.GetInputType(propertyShortTypeName, isEnum); var inputClass = Model.GetInputClassType(propertyShortTypeName); var ariaRequiredAttributeHtml = property.HasRequiredAttribute() ? "aria-required=\"true\"" : string.Empty; var divWhitespace = new string(' ', 16); @@ -80,7 +82,36 @@ public virtual string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); this.Write("\" class=\"form-label\">"); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); - this.Write(": \r\n <"); + this.Write(": \r\n"); + + if (isEnum) { + + this.Write(" <"); + this.Write(this.ToStringHelper.ToStringWithCulture(inputTypeName)); + this.Write(" id=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); + this.Write("\" @bind-Value=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(modelName)); + this.Write("."); + this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); + this.Write("\" class=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(inputClass)); + this.Write("\" "); + this.Write(this.ToStringHelper.ToStringWithCulture(ariaRequiredAttributeHtml)); + this.Write(">\r\n"); + if (isNullableEnum) { + + this.Write(" \r\n"); + } + + this.Write(" @foreach (var value in Enum.GetValues<"); + this.Write(this.ToStringHelper.ToStringWithCulture(propertyShortTypeName)); + this.Write(">())\r\n {\r\n \r\n }\r\n \r\n"); + } else { + + this.Write(" <"); this.Write(this.ToStringHelper.ToStringWithCulture(inputTypeName)); this.Write(" id=\""); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); @@ -92,7 +123,10 @@ public virtual string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(inputClass)); this.Write("\" "); this.Write(this.ToStringHelper.ToStringWithCulture(ariaRequiredAttributeHtml)); - this.Write("/> \r\n "); + this.Write("/> \r\n"); + } + + this.Write(" "); this.Write(this.ToStringHelper.ToStringWithCulture(modelName)); this.Write("."); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); diff --git a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net10.0/BlazorCrud/Create.tt b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net10.0/BlazorCrud/Create.tt index daca0c2ef8..15f16e9cc5 100644 --- a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net10.0/BlazorCrud/Create.tt +++ b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net10.0/BlazorCrud/Create.tt @@ -44,7 +44,9 @@ string modelPropertyName = property.Name; string modelPropertyNameLowercase = modelPropertyName.ToLowerInvariant(); string propertyShortTypeName = property.Type.ToDisplayString().Replace("?", string.Empty); - var inputTypeName = Model.GetInputType(propertyShortTypeName); + var isEnum = Model.IsEnumType(property.Type); + var isNullableEnum = Model.IsNullableEnumType(property.Type); + var inputTypeName = Model.GetInputType(propertyShortTypeName, isEnum); var inputClass = Model.GetInputClassType(propertyShortTypeName); var ariaRequiredAttributeHtml = property.HasRequiredAttribute() ? "aria-required=\"true\"" : string.Empty; var divWhitespace = new string(' ', 16); @@ -52,7 +54,19 @@ #>
<#= requiredSpanAttributeHtml #> +<# if (isEnum) { #> + <<#= inputTypeName #> id="<#= modelPropertyNameLowercase #>" @bind-Value="<#= modelName #>.<#= modelPropertyName #>" class="<#= inputClass #>" <#= ariaRequiredAttributeHtml #>> +<# if (isNullableEnum) { #> + +<# } #> + @foreach (var value in Enum.GetValues<<#= propertyShortTypeName #>>()) + { + + } + > +<# } else { #> <<#= inputTypeName #> id="<#= modelPropertyNameLowercase #>" @bind-Value="<#= modelName #>.<#= modelPropertyName #>" class="<#= inputClass #>" <#= ariaRequiredAttributeHtml #>/> +<# } #>
<# } #> diff --git a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net10.0/BlazorCrud/Edit.cs b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net10.0/BlazorCrud/Edit.cs index 2e4de87701..52c0fbacb7 100644 --- a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net10.0/BlazorCrud/Edit.cs +++ b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net10.0/BlazorCrud/Edit.cs @@ -83,7 +83,9 @@ public virtual string TransformText() string modelPropertyName = property.Name; string modelPropertyNameLowercase = modelPropertyName.ToLowerInvariant(); string propertyShortTypeName = property.Type.ToDisplayString().Replace("?", string.Empty); - var inputTypeName = Model.GetInputType(propertyShortTypeName); + var isEnum = Model.IsEnumType(property.Type); + var isNullableEnum = Model.IsNullableEnumType(property.Type); + var inputTypeName = Model.GetInputType(propertyShortTypeName, isEnum); var inputClass = Model.GetInputClassType(propertyShortTypeName); var ariaRequiredAttributeHtml = property.HasRequiredAttribute() ? "aria-required=\"true\"" : string.Empty; var divWhitespace = new string(' ', 16); @@ -95,7 +97,36 @@ public virtual string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); this.Write("\" class=\"form-label\">"); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); - this.Write(":\r\n <"); + this.Write(":\r\n"); + + if (isEnum) { + + this.Write(" <"); + this.Write(this.ToStringHelper.ToStringWithCulture(inputTypeName)); + this.Write(" id=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); + this.Write("\" @bind-Value=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(modelName)); + this.Write("."); + this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); + this.Write("\" class=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(inputClass)); + this.Write("\" "); + this.Write(this.ToStringHelper.ToStringWithCulture(ariaRequiredAttributeHtml)); + this.Write(">\r\n"); + if (isNullableEnum) { + + this.Write(" \r\n"); + } + + this.Write(" @foreach (var value in Enum.GetValues<"); + this.Write(this.ToStringHelper.ToStringWithCulture(propertyShortTypeName)); + this.Write(">())\r\n {\r\n \r\n }\r\n \r\n"); + } else { + + this.Write(" <"); this.Write(this.ToStringHelper.ToStringWithCulture(inputTypeName)); this.Write(" id=\""); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); @@ -107,7 +138,10 @@ public virtual string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(inputClass)); this.Write("\" "); this.Write(this.ToStringHelper.ToStringWithCulture(ariaRequiredAttributeHtml)); - this.Write("/>\r\n "); + this.Write("/>\r\n"); + } + + this.Write(" "); this.Write(this.ToStringHelper.ToStringWithCulture(modelName)); this.Write("."); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); diff --git a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net10.0/BlazorCrud/Edit.tt b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net10.0/BlazorCrud/Edit.tt index 8f34085c76..6afe5dbfa4 100644 --- a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net10.0/BlazorCrud/Edit.tt +++ b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net10.0/BlazorCrud/Edit.tt @@ -55,7 +55,9 @@ else string modelPropertyName = property.Name; string modelPropertyNameLowercase = modelPropertyName.ToLowerInvariant(); string propertyShortTypeName = property.Type.ToDisplayString().Replace("?", string.Empty); - var inputTypeName = Model.GetInputType(propertyShortTypeName); + var isEnum = Model.IsEnumType(property.Type); + var isNullableEnum = Model.IsNullableEnumType(property.Type); + var inputTypeName = Model.GetInputType(propertyShortTypeName, isEnum); var inputClass = Model.GetInputClassType(propertyShortTypeName); var ariaRequiredAttributeHtml = property.HasRequiredAttribute() ? "aria-required=\"true\"" : string.Empty; var divWhitespace = new string(' ', 16); @@ -63,7 +65,19 @@ else #>
<#= requiredSpanAttributeHtml #> +<# if (isEnum) { #> + <<#= inputTypeName #> id="<#= modelPropertyNameLowercase #>" @bind-Value="<#= modelName #>.<#= modelPropertyName #>" class="<#= inputClass #>" <#= ariaRequiredAttributeHtml #>> +<# if (isNullableEnum) { #> + +<# } #> + @foreach (var value in Enum.GetValues<<#= propertyShortTypeName #>>()) + { + + } + > +<# } else { #> <<#= inputTypeName #> id="<#= modelPropertyNameLowercase #>" @bind-Value="<#= modelName #>.<#= modelPropertyName #>" class="<#= inputClass #>" <#= ariaRequiredAttributeHtml #>/> +<# } #>
<# } #> diff --git a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net11.0/BlazorCrud/Create.cs b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net11.0/BlazorCrud/Create.cs index 1a308c3ec1..1c8e8dbe75 100644 --- a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net11.0/BlazorCrud/Create.cs +++ b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net11.0/BlazorCrud/Create.cs @@ -68,7 +68,9 @@ public virtual string TransformText() string modelPropertyName = property.Name; string modelPropertyNameLowercase = modelPropertyName.ToLowerInvariant(); string propertyShortTypeName = property.Type.ToDisplayString().Replace("?", string.Empty); - var inputTypeName = Model.GetInputType(propertyShortTypeName); + var isEnum = Model.IsEnumType(property.Type); + var isNullableEnum = Model.IsNullableEnumType(property.Type); + var inputTypeName = Model.GetInputType(propertyShortTypeName, isEnum); var inputClass = Model.GetInputClassType(propertyShortTypeName); var ariaRequiredAttributeHtml = property.HasRequiredAttribute() ? "aria-required=\"true\"" : string.Empty; var divWhitespace = new string(' ', 16); @@ -80,7 +82,9 @@ public virtual string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); this.Write("\" class=\"form-label\">"); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); - this.Write(": \r\n <"); + this.Write(": \r\n"); + if (isEnum) { + this.Write(" <"); this.Write(this.ToStringHelper.ToStringWithCulture(inputTypeName)); this.Write(" id=\""); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); @@ -92,7 +96,32 @@ public virtual string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(inputClass)); this.Write("\" "); this.Write(this.ToStringHelper.ToStringWithCulture(ariaRequiredAttributeHtml)); - this.Write("/> \r\n "); + this.Write(">\r\n"); + if (isNullableEnum) { + this.Write(" \r\n"); + } + this.Write(" @foreach (var value in Enum.GetValues<"); + this.Write(this.ToStringHelper.ToStringWithCulture(propertyShortTypeName)); + this.Write(">())\r\n {\r\n \r\n }\r\n \r\n"); + } else { + this.Write(" <"); + this.Write(this.ToStringHelper.ToStringWithCulture(inputTypeName)); + this.Write(" id=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); + this.Write("\" @bind-Value=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(modelName)); + this.Write("."); + this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); + this.Write("\" class=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(inputClass)); + this.Write("\" "); + this.Write(this.ToStringHelper.ToStringWithCulture(ariaRequiredAttributeHtml)); + this.Write("/> \r\n"); + } + this.Write(" "); this.Write(this.ToStringHelper.ToStringWithCulture(modelName)); this.Write("."); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); diff --git a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net11.0/BlazorCrud/Create.tt b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net11.0/BlazorCrud/Create.tt index daca0c2ef8..15f16e9cc5 100644 --- a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net11.0/BlazorCrud/Create.tt +++ b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net11.0/BlazorCrud/Create.tt @@ -44,7 +44,9 @@ string modelPropertyName = property.Name; string modelPropertyNameLowercase = modelPropertyName.ToLowerInvariant(); string propertyShortTypeName = property.Type.ToDisplayString().Replace("?", string.Empty); - var inputTypeName = Model.GetInputType(propertyShortTypeName); + var isEnum = Model.IsEnumType(property.Type); + var isNullableEnum = Model.IsNullableEnumType(property.Type); + var inputTypeName = Model.GetInputType(propertyShortTypeName, isEnum); var inputClass = Model.GetInputClassType(propertyShortTypeName); var ariaRequiredAttributeHtml = property.HasRequiredAttribute() ? "aria-required=\"true\"" : string.Empty; var divWhitespace = new string(' ', 16); @@ -52,7 +54,19 @@ #>
<#= requiredSpanAttributeHtml #> +<# if (isEnum) { #> + <<#= inputTypeName #> id="<#= modelPropertyNameLowercase #>" @bind-Value="<#= modelName #>.<#= modelPropertyName #>" class="<#= inputClass #>" <#= ariaRequiredAttributeHtml #>> +<# if (isNullableEnum) { #> + +<# } #> + @foreach (var value in Enum.GetValues<<#= propertyShortTypeName #>>()) + { + + } + > +<# } else { #> <<#= inputTypeName #> id="<#= modelPropertyNameLowercase #>" @bind-Value="<#= modelName #>.<#= modelPropertyName #>" class="<#= inputClass #>" <#= ariaRequiredAttributeHtml #>/> +<# } #>
<# } #> diff --git a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net11.0/BlazorCrud/Edit.cs b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net11.0/BlazorCrud/Edit.cs index aa5a341b07..bcc0de22d8 100644 --- a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net11.0/BlazorCrud/Edit.cs +++ b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net11.0/BlazorCrud/Edit.cs @@ -83,7 +83,9 @@ public virtual string TransformText() string modelPropertyName = property.Name; string modelPropertyNameLowercase = modelPropertyName.ToLowerInvariant(); string propertyShortTypeName = property.Type.ToDisplayString().Replace("?", string.Empty); - var inputTypeName = Model.GetInputType(propertyShortTypeName); + var isEnum = Model.IsEnumType(property.Type); + var isNullableEnum = Model.IsNullableEnumType(property.Type); + var inputTypeName = Model.GetInputType(propertyShortTypeName, isEnum); var inputClass = Model.GetInputClassType(propertyShortTypeName); var ariaRequiredAttributeHtml = property.HasRequiredAttribute() ? "aria-required=\"true\"" : string.Empty; var divWhitespace = new string(' ', 16); @@ -95,7 +97,36 @@ public virtual string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); this.Write("\" class=\"form-label\">"); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); - this.Write(":\r\n <"); + this.Write(":\r\n"); + + if (isEnum) { + + this.Write(" <"); + this.Write(this.ToStringHelper.ToStringWithCulture(inputTypeName)); + this.Write(" id=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); + this.Write("\" @bind-Value=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(modelName)); + this.Write("."); + this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); + this.Write("\" class=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(inputClass)); + this.Write("\" "); + this.Write(this.ToStringHelper.ToStringWithCulture(ariaRequiredAttributeHtml)); + this.Write(">\r\n"); + if (isNullableEnum) { + + this.Write(" \r\n"); + } + + this.Write(" @foreach (var value in Enum.GetValues<"); + this.Write(this.ToStringHelper.ToStringWithCulture(propertyShortTypeName)); + this.Write(">())\r\n {\r\n \r\n }\r\n \r\n"); + } else { + + this.Write(" <"); this.Write(this.ToStringHelper.ToStringWithCulture(inputTypeName)); this.Write(" id=\""); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); @@ -107,7 +138,10 @@ public virtual string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(inputClass)); this.Write("\" "); this.Write(this.ToStringHelper.ToStringWithCulture(ariaRequiredAttributeHtml)); - this.Write("/>\r\n "); + this.Write("/>\r\n"); + } + + this.Write(" "); this.Write(this.ToStringHelper.ToStringWithCulture(modelName)); this.Write("."); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); diff --git a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net11.0/BlazorCrud/Edit.tt b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net11.0/BlazorCrud/Edit.tt index 8f34085c76..6afe5dbfa4 100644 --- a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net11.0/BlazorCrud/Edit.tt +++ b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net11.0/BlazorCrud/Edit.tt @@ -55,7 +55,9 @@ else string modelPropertyName = property.Name; string modelPropertyNameLowercase = modelPropertyName.ToLowerInvariant(); string propertyShortTypeName = property.Type.ToDisplayString().Replace("?", string.Empty); - var inputTypeName = Model.GetInputType(propertyShortTypeName); + var isEnum = Model.IsEnumType(property.Type); + var isNullableEnum = Model.IsNullableEnumType(property.Type); + var inputTypeName = Model.GetInputType(propertyShortTypeName, isEnum); var inputClass = Model.GetInputClassType(propertyShortTypeName); var ariaRequiredAttributeHtml = property.HasRequiredAttribute() ? "aria-required=\"true\"" : string.Empty; var divWhitespace = new string(' ', 16); @@ -63,7 +65,19 @@ else #>
<#= requiredSpanAttributeHtml #> +<# if (isEnum) { #> + <<#= inputTypeName #> id="<#= modelPropertyNameLowercase #>" @bind-Value="<#= modelName #>.<#= modelPropertyName #>" class="<#= inputClass #>" <#= ariaRequiredAttributeHtml #>> +<# if (isNullableEnum) { #> + +<# } #> + @foreach (var value in Enum.GetValues<<#= propertyShortTypeName #>>()) + { + + } + > +<# } else { #> <<#= inputTypeName #> id="<#= modelPropertyNameLowercase #>" @bind-Value="<#= modelName #>.<#= modelPropertyName #>" class="<#= inputClass #>" <#= ariaRequiredAttributeHtml #>/> +<# } #>
<# } #> diff --git a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net8.0/BlazorCrud/Create.cs b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net8.0/BlazorCrud/Create.cs index 369cd4ce14..c87c1b68a9 100644 --- a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net8.0/BlazorCrud/Create.cs +++ b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net8.0/BlazorCrud/Create.cs @@ -67,7 +67,9 @@ public virtual string TransformText() string modelPropertyName = property.Name; string modelPropertyNameLowercase = modelPropertyName.ToLowerInvariant(); string propertyShortTypeName = property.Type.ToDisplayString().Replace("?", string.Empty); - var inputTypeName = Model.GetInputType(propertyShortTypeName); + var isEnum = Model.IsEnumType(property.Type); + var isNullableEnum = Model.IsNullableEnumType(property.Type); + var inputTypeName = Model.GetInputType(propertyShortTypeName, isEnum); var inputClass = Model.GetInputClassType(propertyShortTypeName); var ariaRequiredAttributeHtml = property.HasRequiredAttribute() ? "aria-required=\"true\"" : string.Empty; var divWhitespace = new string(' ', 16); @@ -79,7 +81,31 @@ public virtual string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); this.Write("\" class=\"form-label\">"); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); - this.Write(": \r\n <"); + this.Write(": \r\n"); + if (isEnum) { + this.Write(" <"); + this.Write(this.ToStringHelper.ToStringWithCulture(inputTypeName)); + this.Write(" id=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); + this.Write("\" @bind-Value=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(modelName)); + this.Write("."); + this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); + this.Write("\" class=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(inputClass)); + this.Write("\" "); + this.Write(this.ToStringHelper.ToStringWithCulture(ariaRequiredAttributeHtml)); + this.Write(">\r\n"); + if (isNullableEnum) { + this.Write(" \r\n"); + } + this.Write(" @foreach (var value in Enum.GetValues<"); + this.Write(this.ToStringHelper.ToStringWithCulture(propertyShortTypeName)); + this.Write(">())\r\n {\r\n \r\n }\r\n \r\n"); + } else { + this.Write(" <"); this.Write(this.ToStringHelper.ToStringWithCulture(inputTypeName)); this.Write(" id=\""); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); @@ -91,7 +117,9 @@ public virtual string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(inputClass)); this.Write("\" "); this.Write(this.ToStringHelper.ToStringWithCulture(ariaRequiredAttributeHtml)); - this.Write("/> \r\n "); + this.Write("/> \r\n"); + } + this.Write(" "); this.Write(this.ToStringHelper.ToStringWithCulture(modelName)); this.Write("."); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); diff --git a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net8.0/BlazorCrud/Create.tt b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net8.0/BlazorCrud/Create.tt index 15e83d6fe5..c5d427b563 100644 --- a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net8.0/BlazorCrud/Create.tt +++ b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net8.0/BlazorCrud/Create.tt @@ -3,16 +3,18 @@ <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Linq" #> +<#@ import namespace="Microsoft.DotNet.Tools.Scaffold.AspNet.Extensions" #> <# - string modelName = Model.ModelType.Name; - string pluralModel = Model.ModelType.PluralName; + string modelName = Model.ModelInfo.ModelTypeName; + string pluralModel = Model.ModelInfo.ModelTypePluralName; string modelNameLowerInv = modelName.ToLowerInvariant(); string pluralModelLowerInv = pluralModel.ToLowerInvariant(); - string dbContextNamespace = string.IsNullOrEmpty(Model.DbContextNamespace) ? string.Empty : Model.DbContextNamespace; - string dbContextFullName = string.IsNullOrEmpty(dbContextNamespace) ? Model.ContextTypeName : $"{dbContextNamespace}.{Model.ContextTypeName}"; + string dbContextNamespace = string.IsNullOrEmpty(Model.DbContextInfo.DbContextNamespace) ? string.Empty : Model.DbContextInfo.DbContextNamespace; + string dbContextFullName = string.IsNullOrEmpty(dbContextNamespace) ? Model.DbContextInfo.DbContextClassName : $"{dbContextNamespace}.{Model.DbContextInfo.DbContextClassName}"; string dbContextFactory = $"IDbContextFactory<{dbContextFullName}> DbFactory"; - string modelNamespace = Model.Namespace ?? Model.ModelType.Namespace; - var entityProperties = Model.ModelMetadata.Properties.Where(x => !x.IsPrimaryKey).ToList(); + string modelNamespace = Model.ModelInfo.ModelNamespace; + var entityProperties = Model.ModelInfo.ModelProperties + .Where(x => !x.Name.Equals(Model.ModelInfo.PrimaryKeyName, StringComparison.OrdinalIgnoreCase)).ToList(); #> @page "/<#= pluralModelLowerInv #>/create" @using Microsoft.EntityFrameworkCore @@ -39,18 +41,32 @@ <# foreach (var property in entityProperties) { - string modelPropertyName = property.PropertyName; + string modelPropertyName = property.Name; string modelPropertyNameLowercase = modelPropertyName.ToLowerInvariant(); - string propertyShortTypeName = property.ShortTypeName.Replace("?", string.Empty); - var inputTypeName = Model.GetInputType(propertyShortTypeName); + string propertyShortTypeName = property.Type.ToDisplayString().Replace("?", string.Empty); + var isEnum = Model.IsEnumType(property.Type); + var isNullableEnum = Model.IsNullableEnumType(property.Type); + var inputTypeName = Model.GetInputType(propertyShortTypeName, isEnum); var inputClass = Model.GetInputClassType(propertyShortTypeName); - var ariaRequiredAttributeHtml = property.IsRequired ? "aria-required=\"true\"" : string.Empty; + var ariaRequiredAttributeHtml = property.HasRequiredAttribute() ? "aria-required=\"true\"" : string.Empty; var divWhitespace = new string(' ', 16); - var requiredSpanAttributeHtml = property.IsRequired ? $"\r\n{divWhitespace}*" : string.Empty; + var requiredSpanAttributeHtml = property.HasRequiredAttribute() ? $"\r\n{divWhitespace}*" : string.Empty; #>
<#= requiredSpanAttributeHtml #> +<# if (isEnum) { #> + <<#= inputTypeName #> id="<#= modelPropertyNameLowercase #>" @bind-Value="<#= modelName #>.<#= modelPropertyName #>" class="<#= inputClass #>" <#= ariaRequiredAttributeHtml #>> +<# if (isNullableEnum) { #> + +<# } #> + @foreach (var value in Enum.GetValues<<#= propertyShortTypeName #>>()) + { + + } + > +<# } else { #> <<#= inputTypeName #> id="<#= modelPropertyNameLowercase #>" @bind-Value="<#= modelName #>.<#= modelPropertyName #>" class="<#= inputClass #>" <#= ariaRequiredAttributeHtml #>/> +<# } #>
<# } #> @@ -71,7 +87,7 @@ private async Task Add<#= modelName #>() { using var context = DbFactory.CreateDbContext(); - context.<#= Model.ModelMetadata.EntitySetName #>.Add(<#= modelName #>); + context.<#= Model.DbContextInfo.EntitySetVariableName ?? modelName #>.Add(<#= modelName #>); await context.SaveChangesAsync(); NavigationManager.NavigateTo("/<#= pluralModelLowerInv #>"); } diff --git a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net8.0/BlazorCrud/Edit.cs b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net8.0/BlazorCrud/Edit.cs index c8a409a417..197e968b39 100644 --- a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net8.0/BlazorCrud/Edit.cs +++ b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net8.0/BlazorCrud/Edit.cs @@ -82,7 +82,9 @@ public virtual string TransformText() string modelPropertyName = property.Name; string modelPropertyNameLowercase = modelPropertyName.ToLowerInvariant(); string propertyShortTypeName = property.Type.ToDisplayString().Replace("?", string.Empty); - var inputTypeName = Model.GetInputType(propertyShortTypeName); + var isEnum = Model.IsEnumType(property.Type); + var isNullableEnum = Model.IsNullableEnumType(property.Type); + var inputTypeName = Model.GetInputType(propertyShortTypeName, isEnum); var inputClass = Model.GetInputClassType(propertyShortTypeName); var ariaRequiredAttributeHtml = property.HasRequiredAttribute() ? "aria-required=\"true\"" : string.Empty; var divWhitespace = new string(' ', 16); @@ -94,7 +96,9 @@ public virtual string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); this.Write("\" class=\"form-label\">"); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); - this.Write(":\r\n <"); + this.Write(":\r\n"); + if (isEnum) { + this.Write(" <"); this.Write(this.ToStringHelper.ToStringWithCulture(inputTypeName)); this.Write(" id=\""); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); @@ -106,7 +110,31 @@ public virtual string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(inputClass)); this.Write("\" "); this.Write(this.ToStringHelper.ToStringWithCulture(ariaRequiredAttributeHtml)); - this.Write("/>\r\n "); + this.Write(">\r\n"); + if (isNullableEnum) { + this.Write(" \r\n"); + } + this.Write(" @foreach (var value in Enum.GetValues<"); + this.Write(this.ToStringHelper.ToStringWithCulture(propertyShortTypeName)); + this.Write(">())\r\n {\r\n \r\n }\r\n \r\n"); + } else { + this.Write(" <"); + this.Write(this.ToStringHelper.ToStringWithCulture(inputTypeName)); + this.Write(" id=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); + this.Write("\" @bind-Value=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(modelName)); + this.Write("."); + this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); + this.Write("\" class=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(inputClass)); + this.Write("\" "); + this.Write(this.ToStringHelper.ToStringWithCulture(ariaRequiredAttributeHtml)); + this.Write("/>\r\n"); + } + this.Write(" "); this.Write(this.ToStringHelper.ToStringWithCulture(modelName)); this.Write("."); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); diff --git a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net8.0/BlazorCrud/Edit.tt b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net8.0/BlazorCrud/Edit.tt index cb51127cf6..ef9edd6867 100644 --- a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net8.0/BlazorCrud/Edit.tt +++ b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net8.0/BlazorCrud/Edit.tt @@ -3,20 +3,22 @@ <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Linq" #> +<#@ import namespace="Microsoft.DotNet.Tools.Scaffold.AspNet.Extensions" #> <# - string modelName = Model.ModelType.Name; - string pluralModel = Model.ModelType.PluralName; + string modelName = Model.ModelInfo.ModelTypeName; + string pluralModel = Model.ModelInfo.ModelTypePluralName; string modelNameLowerInv = modelName.ToLowerInvariant(); string pluralModelLowerInv = pluralModel.ToLowerInvariant(); - string dbContextNamespace = string.IsNullOrEmpty(Model.DbContextNamespace) ? string.Empty : Model.DbContextNamespace; - string dbContextFullName = string.IsNullOrEmpty(dbContextNamespace) ? Model.ContextTypeName : $"{dbContextNamespace}.{Model.ContextTypeName}"; + string dbContextNamespace = string.IsNullOrEmpty(Model.DbContextInfo.DbContextNamespace) ? string.Empty : Model.DbContextInfo.DbContextNamespace; + string dbContextFullName = string.IsNullOrEmpty(dbContextNamespace) ? Model.DbContextInfo.DbContextClassName : $"{dbContextNamespace}.{Model.DbContextInfo.DbContextClassName}"; string dbContextFactory = $"IDbContextFactory<{dbContextFullName}> DbFactory"; - string modelNamespace = Model.Namespace ?? Model.ModelType.Namespace; - string primaryKeyName = Model.ModelMetadata.PrimaryKeys[0].PropertyName; + string modelNamespace = Model.ModelInfo.ModelNamespace; + string primaryKeyName = Model.ModelInfo.PrimaryKeyName; string primaryKeyNameLowerInv = primaryKeyName.ToLowerInvariant(); - string primaryKeyShortTypeName = Model.ModelMetadata.PrimaryKeys[0].ShortTypeName; - string entitySetName = Model.ModelMetadata.EntitySetName; - var entityProperties = Model.ModelMetadata.Properties.Where(x => !x.IsPrimaryKey).ToList(); + string primaryKeyShortTypeName = Model.ModelInfo.PrimaryKeyTypeName; + string entitySetName = Model.DbContextInfo.EntitySetVariableName ?? modelName; + var entityProperties = Model.ModelInfo.ModelProperties + .Where(x => !x.Name.Equals(Model.ModelInfo.PrimaryKeyName, StringComparison.OrdinalIgnoreCase)).ToList(); #> @page "/<#= pluralModelLowerInv #>/edit" @using Microsoft.EntityFrameworkCore @@ -52,18 +54,32 @@ else <# foreach (var property in entityProperties) { - string modelPropertyName = property.PropertyName; + string modelPropertyName = property.Name; string modelPropertyNameLowercase = modelPropertyName.ToLowerInvariant(); - string propertyShortTypeName = property.ShortTypeName.Replace("?", string.Empty); - var inputTypeName = Model.GetInputType(propertyShortTypeName); + string propertyShortTypeName = property.Type.ToDisplayString().Replace("?", string.Empty); + var isEnum = Model.IsEnumType(property.Type); + var isNullableEnum = Model.IsNullableEnumType(property.Type); + var inputTypeName = Model.GetInputType(propertyShortTypeName, isEnum); var inputClass = Model.GetInputClassType(propertyShortTypeName); - var ariaRequiredAttributeHtml = property.IsRequired ? "aria-required=\"true\"" : string.Empty; + var ariaRequiredAttributeHtml = property.HasRequiredAttribute() ? "aria-required=\"true\"" : string.Empty; var divWhitespace = new string(' ', 16); - var requiredSpanAttributeHtml = property.IsRequired ? $"\r\n{divWhitespace}*" : string.Empty; + var requiredSpanAttributeHtml = property.HasRequiredAttribute() ? $"\r\n{divWhitespace}*" : string.Empty; #>
<#= requiredSpanAttributeHtml #> +<# if (isEnum) { #> + <<#= inputTypeName #> id="<#= modelPropertyNameLowercase #>" @bind-Value="<#= modelName #>.<#= modelPropertyName #>" class="<#= inputClass #>" <#= ariaRequiredAttributeHtml #>> +<# if (isNullableEnum) { #> + +<# } #> + @foreach (var value in Enum.GetValues<<#= propertyShortTypeName #>>()) + { + + } + > +<# } else { #> <<#= inputTypeName #> id="<#= modelPropertyNameLowercase #>" @bind-Value="<#= modelName #>.<#= modelPropertyName #>" class="<#= inputClass #>" <#= ariaRequiredAttributeHtml #>/> +<# } #>
<# } #> diff --git a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net9.0/BlazorCrud/Create.cs b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net9.0/BlazorCrud/Create.cs index af269af97b..5406776cf6 100644 --- a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net9.0/BlazorCrud/Create.cs +++ b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net9.0/BlazorCrud/Create.cs @@ -68,7 +68,9 @@ public virtual string TransformText() string modelPropertyName = property.Name; string modelPropertyNameLowercase = modelPropertyName.ToLowerInvariant(); string propertyShortTypeName = property.Type.ToDisplayString().Replace("?", string.Empty); - var inputTypeName = Model.GetInputType(propertyShortTypeName); + var isEnum = Model.IsEnumType(property.Type); + var isNullableEnum = Model.IsNullableEnumType(property.Type); + var inputTypeName = Model.GetInputType(propertyShortTypeName, isEnum); var inputClass = Model.GetInputClassType(propertyShortTypeName); var ariaRequiredAttributeHtml = property.HasRequiredAttribute() ? "aria-required=\"true\"" : string.Empty; var divWhitespace = new string(' ', 16); @@ -80,7 +82,36 @@ public virtual string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); this.Write("\" class=\"form-label\">"); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); - this.Write(": \r\n <"); + this.Write(": \r\n"); + + if (isEnum) { + + this.Write(" <"); + this.Write(this.ToStringHelper.ToStringWithCulture(inputTypeName)); + this.Write(" id=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); + this.Write("\" @bind-Value=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(modelName)); + this.Write("."); + this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); + this.Write("\" class=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(inputClass)); + this.Write("\" "); + this.Write(this.ToStringHelper.ToStringWithCulture(ariaRequiredAttributeHtml)); + this.Write(">\r\n"); + if (isNullableEnum) { + + this.Write(" \r\n"); + } + + this.Write(" @foreach (var value in Enum.GetValues<"); + this.Write(this.ToStringHelper.ToStringWithCulture(propertyShortTypeName)); + this.Write(">())\r\n {\r\n \r\n }\r\n \r\n"); + } else { + + this.Write(" <"); this.Write(this.ToStringHelper.ToStringWithCulture(inputTypeName)); this.Write(" id=\""); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); @@ -92,7 +123,10 @@ public virtual string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(inputClass)); this.Write("\" "); this.Write(this.ToStringHelper.ToStringWithCulture(ariaRequiredAttributeHtml)); - this.Write("/> \r\n "); + this.Write("/> \r\n"); + } + + this.Write(" "); this.Write(this.ToStringHelper.ToStringWithCulture(modelName)); this.Write("."); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); diff --git a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net9.0/BlazorCrud/Create.tt b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net9.0/BlazorCrud/Create.tt index daca0c2ef8..15f16e9cc5 100644 --- a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net9.0/BlazorCrud/Create.tt +++ b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net9.0/BlazorCrud/Create.tt @@ -44,7 +44,9 @@ string modelPropertyName = property.Name; string modelPropertyNameLowercase = modelPropertyName.ToLowerInvariant(); string propertyShortTypeName = property.Type.ToDisplayString().Replace("?", string.Empty); - var inputTypeName = Model.GetInputType(propertyShortTypeName); + var isEnum = Model.IsEnumType(property.Type); + var isNullableEnum = Model.IsNullableEnumType(property.Type); + var inputTypeName = Model.GetInputType(propertyShortTypeName, isEnum); var inputClass = Model.GetInputClassType(propertyShortTypeName); var ariaRequiredAttributeHtml = property.HasRequiredAttribute() ? "aria-required=\"true\"" : string.Empty; var divWhitespace = new string(' ', 16); @@ -52,7 +54,19 @@ #>
<#= requiredSpanAttributeHtml #> +<# if (isEnum) { #> + <<#= inputTypeName #> id="<#= modelPropertyNameLowercase #>" @bind-Value="<#= modelName #>.<#= modelPropertyName #>" class="<#= inputClass #>" <#= ariaRequiredAttributeHtml #>> +<# if (isNullableEnum) { #> + +<# } #> + @foreach (var value in Enum.GetValues<<#= propertyShortTypeName #>>()) + { + + } + > +<# } else { #> <<#= inputTypeName #> id="<#= modelPropertyNameLowercase #>" @bind-Value="<#= modelName #>.<#= modelPropertyName #>" class="<#= inputClass #>" <#= ariaRequiredAttributeHtml #>/> +<# } #>
<# } #> diff --git a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net9.0/BlazorCrud/Edit.cs b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net9.0/BlazorCrud/Edit.cs index 9457f5acc0..292ed797f8 100644 --- a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net9.0/BlazorCrud/Edit.cs +++ b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net9.0/BlazorCrud/Edit.cs @@ -83,7 +83,9 @@ public virtual string TransformText() string modelPropertyName = property.Name; string modelPropertyNameLowercase = modelPropertyName.ToLowerInvariant(); string propertyShortTypeName = property.Type.ToDisplayString().Replace("?", string.Empty); - var inputTypeName = Model.GetInputType(propertyShortTypeName); + var isEnum = Model.IsEnumType(property.Type); + var isNullableEnum = Model.IsNullableEnumType(property.Type); + var inputTypeName = Model.GetInputType(propertyShortTypeName, isEnum); var inputClass = Model.GetInputClassType(propertyShortTypeName); var ariaRequiredAttributeHtml = property.HasRequiredAttribute() ? "aria-required=\"true\"" : string.Empty; var divWhitespace = new string(' ', 16); @@ -95,7 +97,36 @@ public virtual string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); this.Write("\" class=\"form-label\">"); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); - this.Write(":\r\n <"); + this.Write(":\r\n"); + + if (isEnum) { + + this.Write(" <"); + this.Write(this.ToStringHelper.ToStringWithCulture(inputTypeName)); + this.Write(" id=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); + this.Write("\" @bind-Value=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(modelName)); + this.Write("."); + this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); + this.Write("\" class=\""); + this.Write(this.ToStringHelper.ToStringWithCulture(inputClass)); + this.Write("\" "); + this.Write(this.ToStringHelper.ToStringWithCulture(ariaRequiredAttributeHtml)); + this.Write(">\r\n"); + if (isNullableEnum) { + + this.Write(" \r\n"); + } + + this.Write(" @foreach (var value in Enum.GetValues<"); + this.Write(this.ToStringHelper.ToStringWithCulture(propertyShortTypeName)); + this.Write(">())\r\n {\r\n \r\n }\r\n \r\n"); + } else { + + this.Write(" <"); this.Write(this.ToStringHelper.ToStringWithCulture(inputTypeName)); this.Write(" id=\""); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyNameLowercase)); @@ -107,7 +138,10 @@ public virtual string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(inputClass)); this.Write("\" "); this.Write(this.ToStringHelper.ToStringWithCulture(ariaRequiredAttributeHtml)); - this.Write("/>\r\n "); + this.Write("/>\r\n"); + } + + this.Write(" "); this.Write(this.ToStringHelper.ToStringWithCulture(modelName)); this.Write("."); this.Write(this.ToStringHelper.ToStringWithCulture(modelPropertyName)); diff --git a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net9.0/BlazorCrud/Edit.tt b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net9.0/BlazorCrud/Edit.tt index 99828dfafe..246537a4aa 100644 --- a/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net9.0/BlazorCrud/Edit.tt +++ b/src/dotnet-scaffolding/dotnet-scaffold/AspNet/Templates/net9.0/BlazorCrud/Edit.tt @@ -57,7 +57,9 @@ else string modelPropertyName = property.Name; string modelPropertyNameLowercase = modelPropertyName.ToLowerInvariant(); string propertyShortTypeName = property.Type.ToDisplayString().Replace("?", string.Empty); - var inputTypeName = Model.GetInputType(propertyShortTypeName); + var isEnum = Model.IsEnumType(property.Type); + var isNullableEnum = Model.IsNullableEnumType(property.Type); + var inputTypeName = Model.GetInputType(propertyShortTypeName, isEnum); var inputClass = Model.GetInputClassType(propertyShortTypeName); var ariaRequiredAttributeHtml = property.HasRequiredAttribute() ? "aria-required=\"true\"" : string.Empty; var divWhitespace = new string(' ', 16); @@ -65,7 +67,19 @@ else #>
<#= requiredSpanAttributeHtml #> +<# if (isEnum) { #> + <<#= inputTypeName #> id="<#= modelPropertyNameLowercase #>" @bind-Value="<#= modelName #>.<#= modelPropertyName #>" class="<#= inputClass #>" <#= ariaRequiredAttributeHtml #>> +<# if (isNullableEnum) { #> + +<# } #> + @foreach (var value in Enum.GetValues<<#= propertyShortTypeName #>>()) + { + + } + > +<# } else { #> <<#= inputTypeName #> id="<#= modelPropertyNameLowercase #>" @bind-Value="<#= modelName #>.<#= modelPropertyName #>" class="<#= inputClass #>" <#= ariaRequiredAttributeHtml #>/> +<# } #>
<# } #> diff --git a/test/dotnet-scaffolding/dotnet-scaffold.Tests/AspNet/Integration/Blazor/BlazorCrudNet10IntegrationTests.cs b/test/dotnet-scaffolding/dotnet-scaffold.Tests/AspNet/Integration/Blazor/BlazorCrudNet10IntegrationTests.cs index 2148b8e818..187378e712 100644 --- a/test/dotnet-scaffolding/dotnet-scaffold.Tests/AspNet/Integration/Blazor/BlazorCrudNet10IntegrationTests.cs +++ b/test/dotnet-scaffolding/dotnet-scaffold.Tests/AspNet/Integration/Blazor/BlazorCrudNet10IntegrationTests.cs @@ -20,7 +20,21 @@ public async Task Scaffold_BlazorCrud_Net10_CliInvocation() File.WriteAllText(Path.Combine(_testProjectDir, "Program.cs"), ScaffoldCliHelper.GetBlazorProgramCs("TestProject")); var modelsDir = Path.Combine(_testProjectDir, "Models"); Directory.CreateDirectory(modelsDir); - File.WriteAllText(Path.Combine(modelsDir, "TestModel.cs"), ScaffoldCliHelper.GetModelClassContent("TestProject", "TestModel")); + File.WriteAllText(Path.Combine(modelsDir, "TestModel.cs"), @"namespace TestProject.Models; + +public class TestModel +{ + public int Id { get; set; } + public EmploymentType EmploymentType { get; set; } + public EmploymentType? OptionalEmploymentType { get; set; } +} + +public enum EmploymentType +{ + Permanent, + Contract +} +"); // Set up Blazor project structure required for scaffolded code to compile var componentsDir = Path.Combine(_testProjectDir, "Components"); @@ -48,14 +62,16 @@ public async Task Scaffold_BlazorCrud_Net10_CliInvocation() Assert.DoesNotContain("Failed", combinedOutput); Assert.DoesNotContain("No modifications made for file: Program.cs", combinedOutput); - // Assert — generated pages exist, Edit page includes persistent-state wiring, - // and the resulting project still compiles. + // Assert — enum inputs and persistent-state wiring were generated and the resulting project compiles. var blazorPagesDir = Path.Combine(_testProjectDir, "Components", "Pages", "TestModelPages"); Assert.True(Directory.Exists(blazorPagesDir), "Components/Pages/TestModelPages directory should be created."); foreach (var page in new[] { "Create.razor", "Delete.razor", "Details.razor", "Edit.razor", "Index.razor" }) { Assert.True(File.Exists(Path.Combine(blazorPagesDir, page)), $"Blazor page '{page}' should be created."); } + var createContent = File.ReadAllText(Path.Combine(blazorPagesDir, "Create.razor")); + Assert.Contains("(nameof(TestModel), out var restoredTestModel)", editContent); Assert.Contains("TestModel = restoredTestModel", editContent); Assert.Contains("ApplicationState.PersistAsJson(nameof(TestModel), TestModel)", editContent); + + var createContent = File.ReadAllText(Path.Combine(blazorPagesDir, "Create.razor")); + Assert.Contains("(nameof(TestModel), out var restoredTestModel)", editContent); Assert.Contains("TestModel = restoredTestModel", editContent); diff --git a/test/dotnet-scaffolding/dotnet-scaffold.Tests/AspNet/Templates/BlazorCrudTemplateTests.cs b/test/dotnet-scaffolding/dotnet-scaffold.Tests/AspNet/Templates/BlazorCrudTemplateTests.cs index 7ece218e3a..1826f1a98a 100644 --- a/test/dotnet-scaffolding/dotnet-scaffold.Tests/AspNet/Templates/BlazorCrudTemplateTests.cs +++ b/test/dotnet-scaffolding/dotnet-scaffold.Tests/AspNet/Templates/BlazorCrudTemplateTests.cs @@ -12,6 +12,79 @@ namespace Microsoft.DotNet.Tools.Scaffold.Tests.AspNet.Templates; public class BlazorCrudTemplateTests { + [Theory] + [InlineData(9, "Create")] + [InlineData(9, "Edit")] + [InlineData(10, "Create")] + [InlineData(10, "Edit")] + [InlineData(11, "Create")] + [InlineData(11, "Edit")] + [InlineData(8, "Create")] + [InlineData(8, "Edit")] + public void FormTemplate_WithEnumProperty_GeneratesInputSelect(int frameworkVersion, string pageType) + { + // Arrange + BlazorCrudModel model = CreateModel(pageType); + + // Act + string result = TransformTemplate(frameworkVersion, pageType, model); + + // Assert + string inputSelect = GetInputSelect(result, "employeetype"); + + Assert.Contains("@bind-Value=\"Employee.EmployeeType\"", inputSelect); + Assert.Contains("aria-required=\"true\"", inputSelect); + Assert.Contains("Enum.GetValues()", inputSelect); + Assert.Contains("", inputSelect); + Assert.Contains("", inputSelect); + Assert.DoesNotContain("", inputSelect); + Assert.Contains("Enum.GetValues()", inputSelect); + Assert.Contains("", inputSelect); + Assert.DoesNotContain("= 0, $"InputSelect with id '{id}' was not generated."); + + const string closingTag = ""; + int end = result.IndexOf(closingTag, start, System.StringComparison.Ordinal); + Assert.True(end >= 0, $"InputSelect with id '{id}' was not closed."); + + return result.Substring(start, end - start + closingTag.Length); + } private static List GetProperties(string source) { SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(source);