question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Be able to access current HttpActionContext

See original GitHub issue

Hi Jeremy,

I’m working on an web API project using your awesome validation lib. I have requirement to access the current request context while doing validation. So that I resolve a service to do validation:

actionContext.Request.GetOwinContext().GetAutofacLifetimeScope().Resolve<MyService>().Validate(model);

Any clue? Thanks.

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Comments:29 (14 by maintainers)

github_iconTop GitHub Comments

2reactions
JeremySkinnercommented, May 20, 2016

I did a bit of research of this, in case you’re interested.

Simple validator:

public class BenchmarkValidator : AbstractValidator<Person> {
    public BenchmarkValidator() {
        RuleFor(x => x.Surname).NotNull();
        RuleFor(x => x.Forename).NotNull();
    }
}

Creating this validator 20000 times in a loop takes approximately 5 seconds. This is only with 2 very simple expression trees.

Caveat on a benchmark like this is that it doesn’t accurately represent the real world at all, but hopefully it at least gives some context to the performance implications of constantly recompiling an expression tree.

Caching expression trees in an external cache doesn’t seem particularly feasible- they have no concept of equality. Eg:

Expression<Func<Person, string>> expr1 = x => x.Surname;
Expression<Func<Person, string>> expr2 = x => x.Surname;
bool eq = expr1.Equals(expr2)

This returns false, even though these expression trees are the same, and they also generate distinct hash codes. We’d have to implement a custom equality comparison routine that walks the entire expression tree, which itself could be expensive.

As such, I’ll continue to recommend the current approach of caching the entire validator instance.

1reaction
gralincommented, Oct 14, 2015

@JeremySkinner loading http context thru static property is not recommended anymore but is still available for legacy reasons (but not if you self-host). In WebAPI it should be aquired from HttpRequestMessage.Properties collection therefor improving application testability.

@jwu-au

Singleton can’t run services that require HTTP context, e.g. I want to validate some fields basing on current request user profile.

Correct, that’s why I wrote if your service is registered as single instance then it could be done this way. Since you actually use the context (not only resolve the service thru it) then this is not the way to go.

If using ActionFilter then I lost the beauty of FluentValidation.

Well, since you want to resolve your service inside the validator and call it to do some validation, some of the beauty is lost anyway (I would expect the validation be done directly by validator using RuleFor syntax).

So are we able to extend ValidationContext to support request context in future version?

FluentValidations validators inherit from ModelValidator which is a core class in System.Web.Http.Validation. So not much can be done about what comes in. I think validators were meant to work context-agnostic and if your validation logic is context-aware then it should be done somewhere else (e.g. filter or controller). Not all validation can/should be done in those validators, e.g. if validation requires some db calls, you should do it in controller or service called from controller. I think checking context values also falls into the same category.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Be able to access current HttpActionContext · Issue #140
I have requirement to access the current request context while doing validation. So that I resolve a service to do validation: actionContext.
Read more >
Get access to HttpActionContext outside of my Web API 2 ...
Inside my Controller class I can do this: var userId = this.ActionContext.RequestContext.Principal.Identity.Name;. But I have a soap header that ...
Read more >
HttpActionContext Class (System.Web.Http.Controllers)
Initializes a new instance of the HttpActionContext class. System_CAPS_pubmethod ... Gets the current request context.
Read more >
Unable to fetch name from current principal ...
The property “name” inside the current principal from HttpActionContext actionContext is missing. The claim is already added for the access ...
Read more >
ASP.NET Web API Action Filter
In Action Filter, we are reading API Token from HTTP request's header and if specific header presents, then it calls the GetClient method...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found