dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.39k stars 4.75k forks source link

Validator.TryValidateObject does not handle Record Type validation #64736

Open vsfeedback opened 2 years ago

vsfeedback commented 2 years ago

This issue has been moved from a ticket on Developer Community.


using Microsoft.VisualStudio.TestTools.UnitTesting;

using System.ComponentModel.DataAnnotations;
using System;
using System.Collections.Generic;

namespace TestProject1
{
   [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestClass()
        {
            // Validate ClassTest

            var classTest = new ClassTest("Test");
            var classTestValidationResults = new List<ValidationResult>();
            Assert.IsFalse(
                Validator.TryValidateObject(
                    classTest, 
                    new ValidationContext(classTest, null, null), 
                    classTestValidationResults, 
                    true));
        }

        [TestMethod]
        public void TestRecord()
        {
            // Validate RecordTest

            var recordTest = new RecordTest("Test");
            var recordTestValidationResults = new List<ValidationResult>();
            Assert.IsFalse(
                Validator.TryValidateObject(
                    recordTest, 
                    new ValidationContext(recordTest, null, null), 
                    recordTestValidationResults, 
                    true)); // This test fails !
        }
    }

    public class ValidationTestAttribute : ValidationAttribute
    {
        protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
        {
            return new ValidationResult("Failed");
        }
    }

    public class ClassTest
    {
        public ClassTest(string value)
        {
            Value = value ?? throw new ArgumentNullException(nameof(value));
        }

        [ValidationTest]
        public string Value { get; }
    }

    public record RecordTest([ValidationTest] string Value);
}

Is this an expected behavior or a bug?

System : Windows 11 Pro Visual Studio 2022 Version 17.0.0 Preview 4.1 .Net 6 RC 1 (the lastest version)


Original Comments

null on 10/11/2021, 07:19 AM:

Does this reproduce for all project or specific project? If it’s reproduce with the specific project, which project do you use(C# , C++ console, Web, UWP or others )? In order for us to investigate this further, could you please provide repro steps, a more detailed description of the faulty behavior and the actions you were taking when the issue appeared to help us better understand this scenario? What is the actual result and which result do you expect to happen?

fewane on 10/11/2021, 08:27 AM:

If I use the Record type as a parameter in a controller (Api) or as a data model in a Blazor component (Blazor WebAssembly), the attributes are automatically applied.

On the other hand, if I manually call the validation (Validator.TryValidateObject(…)) on the same type Record (Api or Blazor WebAssembly), the attributes are not called (as you can see on the test code).

I need it to apply a cross validation in another module (which receives the type as parameter) with a design pattern (decorator). The module is a library in C# .Net 6 RC1.

Feedback Bot on 10/18/2021, 09:32 AM:

We have directed your feedback to the appropriate engineering team for further evaluation. The team will review the feedback and notify you about the next steps.

Feedback Bot on 10/26/2021, 00:43 PM:

Thank you for sharing your feedback! Our teams prioritize action on product issues with broad customer impact. See details at: https://docs.microsoft.com/en-us/visualstudio/ide/report-a-problem?view=vs-2019#faq. In case you need answers to common questions or need assisted support, be sure to use https://visualstudio.microsoft.com/vs/support/. We’ll keep you posted on any updates to this feedback.

Feedback Bot on 10/26/2021, 10:26 PM:

We have directed your feedback to the appropriate engineering team for further evaluation. The team will review the feedback and notify you about the next steps.

Luna Mi [MSFT] on 1/21/2022, 09:30 AM:

Thank you for taking the time to log this issue! Did you still reproduce this issue in the latest stable version of Visual Studio installed from https://visualstudio.microsoft.com/downloads ?
If so, could you please provide a sample solution that has this problem so that we can conduct further research?

We look forward to hearing from you!

fewane on 1/21/2022, 11:28 AM:

System : Windows 11 Pro
Visual Studio 2022 Version 17.0.5
.Net 6 (6.0.1)

Yes, the problem occurs again. However, by applying the appropriate target attribute, it works.
Changing

public record RecordTest([ValidationTest] string Value);

To

public record RecordTest([property : ValidationTest] string Value);

Feedback Bot on 1/24/2022, 09:45 AM:

We have directed your feedback to the appropriate engineering team for further evaluation. The team will review the feedback and notify you about the next steps.


Original Solutions

(no solutions)

dotnet-issue-labeler[bot] commented 2 years ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

ghost commented 2 years ago

Tagging subscribers to this area: @ajcvickers, @bricelam, @roji See info in area-owners.md if you want to be subscribed.

Issue Details
_This issue has been moved from [a ticket on Developer Community](https://developercommunity.visualstudio.com/t/ValidatorTryValidateObject-does-not-han/1549691)._ --- ``` using Microsoft.VisualStudio.TestTools.UnitTesting; using System.ComponentModel.DataAnnotations; using System; using System.Collections.Generic; namespace TestProject1 { [TestClass] public class UnitTest1 { [TestMethod] public void TestClass() { // Validate ClassTest var classTest = new ClassTest("Test"); var classTestValidationResults = new List(); Assert.IsFalse( Validator.TryValidateObject( classTest, new ValidationContext(classTest, null, null), classTestValidationResults, true)); } [TestMethod] public void TestRecord() { // Validate RecordTest var recordTest = new RecordTest("Test"); var recordTestValidationResults = new List(); Assert.IsFalse( Validator.TryValidateObject( recordTest, new ValidationContext(recordTest, null, null), recordTestValidationResults, true)); // This test fails ! } } public class ValidationTestAttribute : ValidationAttribute { protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) { return new ValidationResult("Failed"); } } public class ClassTest { public ClassTest(string value) { Value = value ?? throw new ArgumentNullException(nameof(value)); } [ValidationTest] public string Value { get; } } public record RecordTest([ValidationTest] string Value); } ``` Is this an expected behavior or a bug? System : Windows 11 Pro Visual Studio 2022 Version 17.0.0 Preview 4.1 .Net 6 RC 1 (the lastest version) --- ### Original Comments #### null on 10/11/2021, 07:19 AM:

Does this reproduce for all project or specific project? If it’s reproduce with the specific project, which project do you use(C# , C++ console, Web, UWP or others )? In order for us to investigate this further, could you please provide repro steps, a more detailed description of the faulty behavior and the actions you were taking when the issue appeared to help us better understand this scenario? What is the actual result and which result do you expect to happen?

#### fewane on 10/11/2021, 08:27 AM:

If I use the Record type as a parameter in a controller (Api) or as a data model in a Blazor component (Blazor WebAssembly), the attributes are automatically applied.

On the other hand, if I manually call the validation (Validator.TryValidateObject(…)) on the same type Record (Api or Blazor WebAssembly), the attributes are not called (as you can see on the test code).

I need it to apply a cross validation in another module (which receives the type as parameter) with a design pattern (decorator). The module is a library in C# .Net 6 RC1.

#### Feedback Bot on 10/18/2021, 09:32 AM:

We have directed your feedback to the appropriate engineering team for further evaluation. The team will review the feedback and notify you about the next steps.

#### Feedback Bot on 10/26/2021, 00:43 PM:

Thank you for sharing your feedback! Our teams prioritize action on product issues with broad customer impact. See details at: https://docs.microsoft.com/en-us/visualstudio/ide/report-a-problem?view=vs-2019#faq. In case you need answers to common questions or need assisted support, be sure to use https://visualstudio.microsoft.com/vs/support/. We’ll keep you posted on any updates to this feedback.

#### Feedback Bot on 10/26/2021, 10:26 PM:

We have directed your feedback to the appropriate engineering team for further evaluation. The team will review the feedback and notify you about the next steps.

#### Luna Mi [MSFT] on 1/21/2022, 09:30 AM:

Thank you for taking the time to log this issue! Did you still reproduce this issue in the latest stable version of Visual Studio installed from https://visualstudio.microsoft.com/downloads ?
If so, could you please provide a sample solution that has this problem so that we can conduct further research?

We look forward to hearing from you!

#### fewane on 1/21/2022, 11:28 AM:

System : Windows 11 Pro
Visual Studio 2022 Version 17.0.5
.Net 6 (6.0.1)

Yes, the problem occurs again. However, by applying the appropriate target attribute, it works.
Changing

public record RecordTest([ValidationTest] string Value);

To

public record RecordTest([property : ValidationTest] string Value);
#### Feedback Bot on 1/24/2022, 09:45 AM:

We have directed your feedback to the appropriate engineering team for further evaluation. The team will review the feedback and notify you about the next steps.

--- ### Original Solutions (no solutions)
Author: vsfeedback
Assignees: -
Labels: `area-System.ComponentModel.DataAnnotations`, `untriaged`
Milestone: -
ajcvickers commented 2 years ago

@pranavkm @mkArtakMSFT Is validation of record types important to Blazor or MVC? In other words, is it something you might want to put resources on to implement?

pranavkm commented 2 years ago

@rafikiassumani-msft owns this particular area of MVC, so he'd be the one to make a decision here.

Bartmax commented 2 years ago

I'm also interested on support Validation on records Lost a huge deal of time before I find this issue.

Records are a perfect fit for model binding in MVC and azure functions, hence quite important to support validation.