Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

When creating a custom ValidationAttribute, the ValidationContext always don't have a valid ServiceContainer #6346

Closed
jlVidal opened this issue May 31, 2017 · 5 comments
Labels

Comments

@jlVidal
Copy link

jlVidal commented May 31, 2017

Following this article: https://andrewlock.net/injecting-services-into-validationattributes-in-asp-net-core/

When creating custom ValidationAttribute several people already note that is impossible to access/get any service from the GetService method inside the ValidationContext class, ServiceContainer property. Looking into the code is possible to see:

            var context = new ValidationContext(
                instance: container ?? validationContext.Model,
                serviceProvider: validationContext.ActionContext?.HttpContext?.RequestServices,
                items: null)
            {
                DisplayName = metadata.GetDisplayName(),
                MemberName = memberName
            };

https://github.com/aspnet/Mvc/blob/760c8f38678118734399c58c2dac981ea6e47046/src/Microsoft.AspNetCore.Mvc.DataAnnotations/Internal/DataAnnotationsModelValidator.cs

Since the ActionContext was obsolete: https://stackoverflow.com/questions/37286530/actioncontext-gone-in-microsoft-aspnetcore-mvc-controller - The service provider for a validation attribute is always null or empty. Let's make the ValidationAttribute great again, please fix this issue in the next patch.

@rynowak
Copy link
Member

rynowak commented May 31, 2017

Are you saying that 328f4d6 does not fix this issue?

It's certainly our intent that ValidationContext has the right service provider.

@jlVidal
Copy link
Author

jlVidal commented May 31, 2017

To be confirmed... Since I'm compiling against NET452 I can't test in the newer/beta version (2.0.0-preview1) If fixed, I believe that should be explicit mentioned in the release notes.

@rynowak thanks for the follow up anyway

@rynowak
Copy link
Member

rynowak commented Jun 1, 2017

@jlVidal - 328f4d6 dates all the way back to 1.0.0-rc2 so I expect this to be working in whatever release you are using.

Can you please clarify for me... is this working for you or not?

@jlVidal
Copy link
Author

jlVidal commented Jun 1, 2017

It's working in new/blank project! I'm still trying to figure out why my specific solution doesn't work correctly.. I can't request any services to the ServiceProvider (always returns null). I'm using:

    <PackageReference Include="Microsoft.AspNetCore" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.DataProtection.Extensions" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.3" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.WebApiCompatShim" Version="1.1.3" />
    <PackageReference Include="Microsoft.AspNetCore.ResponseCompression" Version="1.0.2" />
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.2" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="1.0.0" />

EDIT: OK I found the issue:

I was trying to do:

            var result = validationContext.ServiceContainer.GetService(typeof(FooServiceTest));
            if (result == null)
                throw new ArgumentNullException(nameof(result));

but the way that works is:

            var result = validationContext.GetService(typeof(FooServiceTest));
            if (result == null)
                throw new ArgumentNullException(nameof(result));

API call problem 😢 - so the bug exists with the ServiceContainer property.

@rynowak
Copy link
Member

rynowak commented Jun 1, 2017

https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validationcontext.servicecontainer(v=vs.110).aspx#Anchor_1

Yeah that's a bit of a bizzare property. I guess it's intended for you to be able to share state? Since service provider is read-only but service container is r/w.

Ok, going to close this since there's no actual ASP.NET problem. Glad you got it figured out.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants