Simple validation crashing on just one property (+other validation issues)

Hi,


Later edit (LE):
I have edited this to summarize issues I’ve encountered so far in this entire thread, all having to do with field validations:

  1. Although I have a working validator to handle the [Required] property, on Production environment, on .NET Core, .NET 8, errors still show in the Console tab in browser, cluttering the client-side maintenance/debugging side of work. I don’t know how to disable/mute/treat these as to not appear anymore as they are not needed (validation is already taken care of).
  2. config.ClientSideValidation = false does not work (see rest of thread). Is there any other way to disable client side validation??
  3. [Required(AllowEmptyStrings = true)] - not able to understand this, it fails validation for whitespace strings and also for empty strings;
  4. (NEW) I have a PostBack button that relates to a whole bunch of fields arranged in various sections and subsections that are IncludeInPage false or true depending or business logic, all those sections have validated properties. How do I validate with that single button only the properties that are part of sections with IncludeInPage true ?
    This is a typical scenario for non-trivial WebForms apps.



I'm struggling to understand why in the entire application, just one single property validation is crashing here.

The property:
image

The markup:

The crash:

The why???:
I don’t understand why DotVVM keeps on doing client-side validation while I explicitly set it to false in config:
image

When I push the button that runs the validation, no change in the Network tab and the Validator text appears as expected:

But why do I get errors in Console tab? It’s just one property validation, my first in the entire app and I’ve used the steps/info from the online documentation… there has to be something simple I cannot see right now.

This is driving me chestnuts and acorns on a country road…

PS: .NET 8 Blazor app with DotVVM pages, the trigger button, dropdownlist and validator are all inside a ModalDialog inside a MarkupControl inside another MarkupControl inside a DotVVM page with MasterPage. I will experiment with validation in a simple bare bone page, work it up from there.

update:

same error and client-side validation with Textbox on completely different page (simple .dothtml page with MasterPage) and config.ClientSideValidation still false:

MARKUP:
image

VIEW MODEL:
image

update:

Did a test on a new DotVVM project for .NET Core (.NET 7, no Business Pack this time):

Results:

Error still there on the client-side, with the textbox and button copy-pasted from the last test page.

I started to think this might be the “normal” expected behavior which, if it is the case, would be weird.

UPDATE

On the brand new DotVVM .NET Core project,
this error appears:

  1. regardless of setting Development / Production in launchSettings.json

    “ASPNETCORE_ENVIRONMENT”: “Production”

  2. regardless of how we set config.ClientSideValidation

image

UPDATE

Why is [Required(AllowEmptyStrings = true)] of course crashing in the Console tab but! also not working with space-only content in text boxes ?

DefaultViewModel.cs:

Also, again on the matter of config.ClientSideValidation = false; not seeming to work: on hitting Save button, that breakpoint is never reached on the command. And neither these:

which tells me that indeed all is happening client-side, does not reach towards server, and config.ClientSideValidation = false; thus does not make sense.

UPDATE

Writing Button like below (by looking into EnforceClientSideValidationDisabled.dothtml from DotVVM.Samples.Common project) does not help.

image

UPDATE

Same problem with ValidationSummary control instead of Validator controls:

Console in browser:

Network in browser:

DotvvmStartup.Configure:
image

… what am I missing in this story?

Whenever I see “uncaught” or “unhandled” exceptions anywhere, my dev mind is just “hey, your work is not completed, something is bleeding somewhere, NOT GOOD for production”.

PS: I thought about something. Maybe it is possible for these exceptions to be caught / muted in a client-side dotvvm event. If this is true, please advise me what event would be most proper and what code to write.

This is important
@tomasherceg

This is the number 1. issue in this thread.

Following from our discussion by email, @tomasherceg , I would like to give a bit of background and to suggest changes to this particular issue.

First and most importantly, our project deals with sensitive and very sensitive data that needs careful multi-step validation, it deals with business critical data that can, if improperly addressed, spiral quickly and even unexpectedly into impacts on client base, business revenue and event fines from the state official regulating entities.
So, seeing that validation crashes from dotvvm.internal on production environment and nowhere from our own code, we seriously thought if this is a deal breaker for using DotVVM framework at all. Since for our needs, the number one technical concern of our project is data validation.

Jump scares aside and thinking there could be very well other potential DotVVM customers to consider serious real-world projects built/migrated with your framework that could be challenged by this validation behavior,
I think this is really important if not critical and as far as my knowledge goes, I propose adding some leveraging config settings coupled with their counterpart online documentation. Settings something like:

config.SignalValidationFailOnClientSide //(bool)
config.SignalValidationFailOnClientSideIfNotAddressedByValidatorOrValidationSummary //(bool) - loooong but you get the idea
config.ThrowValidationClientSideErrors //(bool)
config.ValidationFailSignalingLevelOnClientSide //(enum with: Error, Warning, Info, maybe None to mute them)
config.EnableValidationFailSignalingOnDevelopment //(bool)
config.EnableValidationFailSignalingOnProduction //(bool)

Sorry, the Required(AllowEmptyString=true) and config.ClientSideValidation=false not working are both bugs (fixed in validation client-side: Fix Required(AllowEmptyString=true) by exyi · Pull Request #1775 · riganti/dotvvm · GitHub; Fix config.ClientSideValidation switch, remove redundant vm.validationRules property by exyi · Pull Request #1773 · riganti/dotvvm · GitHub)

Regarding the console error, yes it is expected. Well, the first one (“validation failed: postback aborted: …”) is expected, while the second one (“Uncaught (in promise)”) definitely shouldn’t be there. Do I understand it correctly, that the “Uncaught (in promise)” only occurs with bp:Button, but doesn’t with plain dot:Buttons?

If you only have a problem with the “Uncaught (in promise)”, that can (and should) be fixed.

However, I don’t understand the problem with the first error, do you use DotVVM validation to show something that the user should not interpret as an error? I think that it is common show both user and internal errors in the console, even the browsers write an error line if you respond with with a “user error” response (HTTP 400 Bad request ~= validation failure, HTTP 401 Unauthorized)

1 Like

Either by removing the unused sections from the view model (setting them to null), or manually using the Context.AddModelError. The validation in DotVVM ignores what is displayed or hidden to the user, the validation is purely done in the viewmodel, it doesn’t depend on the View (beyond Validation.Target and Validation.Enabled).

1 Like

Yes. I’ve checked this just now and the “Uncaught (in promise)” occurs only with the bp:Button control.

here is the result of a single click on bp:Button:

and here that of a single click on dot:Button:



We use it as we always used data validation for users: to communicate to the user that validation failed by displaying a proper message styled according to the page / context / gravity the user is on (all according to business logic). This is enough. The error in the Console I see it as intended for debug / technical interventions and is strictly the realm of “something wrong with the app” but the app is working perfectly.

I agree with displaying the error if validation is not addressed by a Validator or ValidationSummary control or in any other possible way. But again, if it is addressed, the validation aspect is considered complete, no reason for misleading and cluttering as we have potentially many other errors to appear in Console and imagine what mess when multi step validations errors intertwine with other errors we have to debug / consult / repair.

I am not saying this feature is not useful, it is very useful! But for the particular use cases and use scenarios of at least our business / project, we certainly require it to be configurable (see the suggestions in the answer that tags Tomáš). Otherwise we will experience a drop in maintenance productivity/clarity compared to how we went about it with the project in the days of WebForms. But surely, this is just how we see it, from our point of view on this ever changing, morphing and developing 10+ years project.

(A)

By this you are saying to make a sub view model specifically for every section, bind it to DataContext property and then set it to null every time it is hidden and then when redisplayed populate all the data back in the section as state of form demands it (as the user to maintain their typed in data after redisplay of sections) ?

In this example, to do NewModelSectionInstance = null whenever DisplayNewModelSection is false, and beforehand to save its state. And when DisplayNewModelSection becomes true, to make another instance for NewModelSectionInstance and redo its state (from where it was saved, like a “shadow” NewModelSectionInstance lets say).
:question: Did I understood correctly?


(B)

I like how much flexibility this approach gives you!
:question: Is this usable only for the server-side validation?


(C)

I read this as “ignores {what is not displayed} or {what is hidden} to the user”. If so, what I experience in the page is this:

MarcaNou* and TipModelNou* properties are rightfully validated as they correspond to the two indicated fields from the visible section (IncludeInPage true). While the other two are from another similar section which is not visible in the page (IncludeInPage false). This though does not stop the validation mechanism from also validating them, 4 validations instead of two as the state of the UI requires.
:question: Is this correct and expected DotVVM behavior?

Essentially yes, it’s one option. For example, it works well for modal dialogs - we set Validation.Target={value: MyModal} when you are in to ignore errors from outside the dialog. Then we close it with MyModal = null, to avoid getting errors from inside of the dialog (and also to avoid ballooning the viewmodel size with 50 unused modals).

This only works on the server. You can similarly manually add errors client-side with dotvvm.validation.addErrors({ errorMessage: "Something bad.", propertyPath: "/Rows/10/Name"}) (dotvvm-docs/Pages/concepts/validation/extensibility.md at 81c20786232a4a2da262eab2908572395c71b9ae · riganti/dotvvm-docs · GitHub)

1 Like

Yes, that’s expected. We don’t want validation to just disappear if I’d forget to add a validator control to the page, or if the user manages to hide it by manipulating the view model.

I understand, thanks. I’ll see what I can do to ensure a decent scalability of our forms with nested collapsible sections.

image

@tomasherceg
I think that design-wise, a framework has to leave the way in which an app to communicate the data validation failure:

  • completely in the hands of the app’s development, not to impose errors when validation is complete and correctly addressed with UI elements (validators etc.). Sure, postback abort to be enforced - this is functionality and basic security. But how is this communicated to the client is another matter and it translates right now (as DotVVM has it implemented) into enforcing some drawbacks and limitations in the process of app maintenance that are not needed.
  • or at least (as I suggested), to be configurable after the framework arrives out-of-the box with the error display always on for any case of the validation.

I thought about the new app architecture (MVVM) and I understand this to be a healthy principle to start from when planning page structure involving collapsible/hideable containers (panels, sections, modals).

I’d say it’s definitely a good idea to group the relevant properties together to nested view models. It will probably solve some of the validation scoping issues, but the system is still quite limited. We are somewhat interested in possible extensions, but we also don’t want to overcomplicate things, since you can always opt-out of the auto-validation and do it with AddModelError. For example, we have FluentValidation support on the list, it’s essentially waiting for someone who’d have a use case :smiley:

1 Like

I’ve switched to sub view models that accept null and bound them to my sections. I get warnings of possible null value in markup in many places. I suspect this is because nullable context is enabled at the project level (it was convenient to leave it like that).
image

Do you have any suggestions for getting rid of this?
image

PS:
Disabling it at the top of the .cs view model file of the MarkupControl does not resolve this.
image