aspnetcore icon indicating copy to clipboard operation
aspnetcore copied to clipboard

Blazor server Annotation Validators C# Error Message

Open bjm3819 opened this issue 2 years ago • 3 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Describe the bug

I'm using data annotations in a blazor server application. Were trying to prevent users from entering certain special characters. The problem is it appears the error message were including is causing something to choke, throw a null exception. T1134400_WithoutDevExpress.zip

https://user-images.githubusercontent.com/1268428/208206107-f99f9034-8020-476b-bd77-16e9cda2b469.mp4

` [RegularExpression(@"^[a-zA-Z0-9(){}|\/,.:;' -]*$", ErrorMessage = "Only Alpha numeric and the following special characters allowed: (){}|\/,.:;'-")] public string PropertyWithRegXMessageCausingException { get; set; }

`

Expected Behavior

upon entering = in the input Id get a validation message "Only Alpha numeric and the following special characters allowed: ()_{}|\/,.:;'-"

Steps To Reproduce

steps to recreate using my app attached run the app, click 'Data annotation test' from navigation menu. Then enter = in the lower input box. ("note the red border noting that the input is invalid") Now enter = in the upper input box. ( you'll get a unhandled exception ) reference my DataAnnotionsTest.cs class and DataAnnotateTest.razor file for source.

refer to original complaint to third party control library whom said the issue was not with their controls. ref

Exceptions (if any)

No response

.NET Version

.NET 6.0

Anything else?

No response

bjm3819 avatar Dec 16 '22 23:12 bjm3819

@bjm3819 thanks for contacting us.

Seems like we need to do some investigation here. Turning on "first chance exceptions" I see that the original exception is image

System.Private.CoreLib.dll!System.Text.ValueStringBuilder.ThrowFormatError() Line 335
	at /_/src/libraries/System.Private.CoreLib/src/System/Text/ValueStringBuilder.AppendFormat.cs(335)
System.Private.CoreLib.dll!System.Text.ValueStringBuilder.AppendFormatHelper(System.IFormatProvider provider, string format, System.ParamsArray args) Line 133
	at /_/src/libraries/System.Private.CoreLib/src/System/Text/ValueStringBuilder.AppendFormat.cs(133)
System.Private.CoreLib.dll!string.FormatHelper(System.IFormatProvider provider, string format, System.ParamsArray args) Line 504
	at /_/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs(504)
System.Private.CoreLib.dll!string.Format(System.IFormatProvider provider, string format, object arg0, object arg1) Line 476
	at /_/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs(476)
System.ComponentModel.Annotations.dll!System.ComponentModel.DataAnnotations.RegularExpressionAttribute.FormatErrorMessage(string name) Line 82
	at /_/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RegularExpressionAttribute.cs(82)
System.ComponentModel.Annotations.dll!System.ComponentModel.DataAnnotations.ValidationAttribute.IsValid(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext) Line 377
	at /_/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationAttribute.cs(377)
System.ComponentModel.Annotations.dll!System.ComponentModel.DataAnnotations.ValidationAttribute.GetValidationResult(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext) Line 416
	at /_/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationAttribute.cs(416)
System.ComponentModel.Annotations.dll!System.ComponentModel.DataAnnotations.Validator.TryValidate(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext, System.ComponentModel.DataAnnotations.ValidationAttribute attribute, out System.ComponentModel.DataAnnotations.Validator.ValidationError validationError) Line 630
	at /_/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/Validator.cs(630)
System.ComponentModel.Annotations.dll!System.ComponentModel.DataAnnotations.Validator.GetValidationErrors(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext, System.Collections.Generic.IEnumerable<System.ComponentModel.DataAnnotations.ValidationAttribute> attributes, bool breakOnFirstError) Line 597
	at /_/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/Validator.cs(597)
System.ComponentModel.Annotations.dll!System.ComponentModel.DataAnnotations.Validator.TryValidateProperty(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext, System.Collections.Generic.ICollection<System.ComponentModel.DataAnnotations.ValidationResult> validationResults) Line 62
	at /_/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/Validator.cs(62)
Microsoft.AspNetCore.Components.Forms.dll!Microsoft.AspNetCore.Components.Forms.EditContextDataAnnotationsExtensions.DataAnnotationsEventSubscriptions.OnFieldChanged(object sender, Microsoft.AspNetCore.Components.Forms.FieldChangedEventArgs eventArgs) Line 82
	at /_/src/Components/Forms/src/EditContextDataAnnotationsExtensions.cs(82)
Microsoft.AspNetCore.Components.Forms.dll!Microsoft.AspNetCore.Components.Forms.EditContext.NotifyFieldChanged(Microsoft.AspNetCore.Components.Forms.FieldIdentifier fieldIdentifier) Line 79
	at /_/src/Components/Forms/src/EditContext.cs(79)
Microsoft.AspNetCore.Components.Web.dll!Microsoft.AspNetCore.Components.Forms.InputBase<string>.CurrentValue.set(string value) Line 83
	at /_/src/Components/Web/src/Forms/InputBase.cs(83)
Microsoft.AspNetCore.Components.Web.dll!Microsoft.AspNetCore.Components.Forms.InputBase<string>.CurrentValueAsString.set(string value) Line 109
	at /_/src/Components/Web/src/Forms/InputBase.cs(109)
BlazorAppDevX.dll!BlazorAppDevX.Pages.MyInputText.BuildRenderTree.AnonymousMethod__0_0(string __value)
Microsoft.AspNetCore.Components.dll!Microsoft.AspNetCore.Components.EventCallbackFactoryBinderExtensions.CreateBinderCore.AnonymousMethod__0(Microsoft.AspNetCore.Components.ChangeEventArgs e) Line 716
	at /_/src/Components/Components/src/EventCallbackFactoryBinderExtensions.cs(716)
[Native to Managed Transition]
[Managed to Native Transition]
System.Private.CoreLib.dll!System.Delegate.DynamicInvokeImpl(object[] args) Line 92
	at /_/src/coreclr/System.Private.CoreLib/src/System/Delegate.CoreCLR.cs(92)
System.Private.CoreLib.dll!System.Delegate.DynamicInvoke(object[] args) Line 61
	at /_/src/libraries/System.Private.CoreLib/src/System/Delegate.cs(61)
Microsoft.AspNetCore.Components.dll!Microsoft.AspNetCore.Components.EventCallbackWorkItem.InvokeAsync<object>(System.MulticastDelegate delegate, object arg) Line 66
	at /_/src/Components/Components/src/EventCallbackWorkItem.cs(66)
Microsoft.AspNetCore.Components.dll!Microsoft.AspNetCore.Components.EventCallbackWorkItem.InvokeAsync(object arg) Line 38
	at /_/src/Components/Components/src/EventCallbackWorkItem.cs(38)
Microsoft.AspNetCore.Components.dll!Microsoft.AspNetCore.Components.ComponentBase.Microsoft.AspNetCore.Components.IHandleEvent.HandleEventAsync(Microsoft.AspNetCore.Components.EventCallbackWorkItem callback, object arg) Line 303
	at /_/src/Components/Components/src/ComponentBase.cs(303)
Microsoft.AspNetCore.Components.dll!Microsoft.AspNetCore.Components.EventCallback.InvokeAsync(object arg) Line 61
	at /_/src/Components/Components/src/EventCallback.cs(61)
Microsoft.AspNetCore.Components.dll!Microsoft.AspNetCore.Components.RenderTree.Renderer.DispatchEventAsync(ulong eventHandlerId, Microsoft.AspNetCore.Components.RenderTree.EventFieldInfo fieldInfo, System.EventArgs eventArgs) Line 386
	at /_/src/Components/Components/src/RenderTree/Renderer.cs(386)
Microsoft.AspNetCore.Components.Web.dll!Microsoft.AspNetCore.Components.RenderTree.WebRenderer.WebRendererInteropMethods.DispatchEventAsync(System.Text.Json.JsonElement eventDescriptor, System.Text.Json.JsonElement eventArgs) Line 112
	at /_/src/Components/Web/src/WebRenderer.cs(112)

If we step through the exceptions, we end up in a situation where clientProxy is null.

I am not sure if:

  • The order of operations is wrong (unlikely) and we see the unhandled exception and tear down the circuit before the callback gets a chance to run.
  • We somehow leave the circuit context (somewhere in our code do not await things correctly).

In any case, an exception on the validation code, should cause the circuit to crash, but the original exception should be preserved.

javiercn avatar Dec 19 '22 16:12 javiercn

To learn more about what this message means, what to expect next, and how this issue will be handled you can read our Triage Process document. We're moving this issue to the .NET 8 Planning milestone for future evaluation / consideration. Because it's not immediately obvious what is causing this behavior, we would like to keep this around to collect more feedback, which can later help us determine how to handle this. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact work.

ghost avatar Dec 19 '22 17:12 ghost

An update so far,

There seems to be a couple things going on here. Since String.format() is used during the validation process, the curly braces in the "bad" string are going to cause an issue.

What this has uncovered is that there's an unhandled NullReferenceException that is terminating the circuit. There likely is a missing await somewhere and would likely be a bug if that were the case. I'm continuing to investigate.

Nick-Stanton avatar Jan 03 '23 22:01 Nick-Stanton

Hi @bjm3819, By design, error messages in attributes support string formatting, so empty curly braces are going to cause issues. To make your code work, you have to escape those characters.

Changing your error message to the string "Only Alpha numeric and the following special characters allowed: ()_{{}}|\\/,.:;'-" should work the way you intended.

In the meantime, we're keeping this issue open while we investigate how that String.format() error is unhandled/tears down the circuit. Thanks for reporting this!

Nick-Stanton avatar Jan 05 '23 21:01 Nick-Stanton

Closing this since the author's question has been answered and a new issue has been opened to track the awkward teardown behavior.

Nick-Stanton avatar Jan 09 '23 21:01 Nick-Stanton