-
Notifications
You must be signed in to change notification settings - Fork 10.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Required parameters to blazor components #11815
Comments
This is an old idea. It was moved from original Blazor repository to this #5455. Unfortunately it is now closed. |
Thank you @Andrzej-W. I close it as duplicate. |
Reopening this. We do plan to do a feature like this but it won't happen in 3.0. |
The implementation of this may need to mix with the #nullable variable feature in c# 8. The null checks will flag [Parameter(required = true)] protected T myVar {get; set;} as uninitialized, but in fact this attribute is saying that the variable must be initialized; but it is initialized elsewhere. |
Clearing the milestone as I'd like to consider this for 5.0 now that we have a bunch of components that have required parameters. |
This could have came in handy for me too, for now I just wrapped the property.
|
Is not possible to add this to 3.1? |
Use [Parameter]
public UserEditViewModel UserEdit { get; set; } = null!; |
That works, but it really just tells the compiler to ignore the problem. It'd be nicer if we can have the compiler surface the problem on the component consumer's end:
|
I have solved this in a basic way with the following extension method during runtime: #nullable enable
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using FluentAssertions.Common;
using Microsoft.AspNetCore.Components;
namespace Blazor
{
public static class ComponentExtension
{
public record ParameterInfo(PropertyInfo PropertyInfo, bool IsRequired);
private static readonly ConcurrentDictionary<Type, ParameterInfo[]> _typeInfo = new();
/// <summary>
/// Validate parameters
/// </summary>
/// <param name="component"></param>
public static void ValidateParameters(this IComponent component)
{
#if DEBUG
var componentType = component.GetType();
if (!_typeInfo.TryGetValue(componentType, out var parameterInfo))
{
var props = componentType
.GetProperties()
.Where(x => x.IsDecoratedWith<ParameterAttribute>());
var list = new List<ParameterInfo>();
foreach (var prop in props)
{
list.Add(new ParameterInfo(prop, prop.GetCustomAttribute<RequiredAttribute>() != null));
}
_typeInfo[component.GetType()] = parameterInfo = list.ToArray();
}
foreach (var property in parameterInfo.Where(x=>x.IsRequired) )
{
var value = property.PropertyInfo.GetValue(component);
if (value == null)
throw new ArgumentNullException(property.PropertyInfo.Name);
switch (property.PropertyInfo.PropertyType)
{
case Type t when t == typeof(Guid):
{
if ((Guid)value == default)
throw new ArgumentNullException(property.PropertyInfo.Name);
break;
}
}
}
#endif
}
}
} In every component where I want to have validation I call this method [Parameter] [Required] public Guid Id { get; set; } = default!;
protected override void OnInitialized()
{
this.ValidateParameters();
} |
@JvanderStad the issue isn't checking in the component at runtime, but checking in the consumer at compile time. |
I'm aware of this, but it's better than nothing. I'm just sharing what works for me right now. |
Solving it at compile time has been possible (and stable) for many months now (see above comments). No need to work with runtime-only. The only real question is whether this should be a separate attribute ( |
Didn't see that. Ah wel ¯_(ツ)_/¯ |
Would one ever use a [Required] attribute without a [Parameter] attribute? I don't think so. Based on that, it seems like the [Parameter(required=true)] makes more sense. The "required" modifies the "Parameter" attribute, but is not an attribute on its own. |
I'm not in the position to make that decision, nor do I have a strong preference either way. But there is a reason for a separate attribute, and that is precedent and existing code: RequiredAttribute (System.ComponentModel.DataAnnotations) https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.requiredattribute?view=net-5.0 |
One attribute = fewer reflection calls |
At compile time, there's no concern about reflection. It doesn't matter to a source generator whether there are one or two attributes. |
What precedent is there? In data annotations, |
I think using |
… parameters are not specified. (dotnet/aspnetcore#33384) * Provide a tooling gesture that suggests values for required component parameters are not specified. Fixes dotnet/aspnetcore#11815 Commit migrated from dotnet/aspnetcore@e02723975a97
Is your feature request related to a problem? Please describe.
I'm building a component where optional parameter doesn't make sense.
Describe the solution you'd like
Add required parameter to
Parameter
attributeThe text was updated successfully, but these errors were encountered: