Cannot resolve dependency in a custom ValidationAttribute, IServiceProvider is set to null on the ValidatationContontext parameter - .net-core

An ASP.NET Core 2.1 MVC app, using Autofac following their documentation on setup (https://autofaccn.readthedocs.io/en/latest/integration/aspnetcore.html).
I am trying to resolve a dependency in a custom ValidationAttribute. The returned value from valicationContext.GetService is always returning null. Inspecting the validatationContext the private member serviceProvider is always null.
what am I missing in the setup that this isnt working. The dependancies resolve everywhere else in the app, just not in the ValidationAttributes.
public class MyCustomAttribute : ValidationAttribute
{
public MyCustomAttribute ()
{
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
// THIS IS ALWAYS RETURNING NULL
var IMyService service = (IMyService)validationContext.GetService(typeof(IMyService));
return ValidationResult.Success;
}
}

I can't say I've tried this before, but doing some searching I found this issue which seems to indicate that the service provider (not the ServiceContainer property, but the service provider that will respond to GetService calls) should always be populated. Granted, that's from an archived repo from early on in .NET Core, but it should still hold.
Looking at the source for ValidationContext I see that the private serviceProvider field is actually a function that needs to be instantiated somewhere; it's not actually a reference to a provider proper. That means if it's null, one of two things is happening:
The path through ASP.NET Core that's instantiating that ValidationContext is not passing in the IServiceProvider required to provide services.
Something is broken.
If it's #1, I'd guess there are a variety of potential reasons. I'd think about things like...
The attribute is being used by something running outside the "ASP.NET Pipeline" - like a manually invoked validation or possibly something at application startup where there's no request at the moment.
The attribute is being used in a test where the full pipeline isn't in effect.
Something like that. I'm not saying this is what's happening, but I've seen questions like this before where it appears something isn't working right when it's actually an application code problem. For example, there are lots of questions about why "instance-per-request" dependencies aren't working and it turns out the code is running on a background thread where there's no request so... yeah. I don't know how your app works, but that sort of "I'm doing something I forgot to mention because I didn't think it was relevant" stuff comes into play here.
Let's assume you've got a super vanilla ASP.NET Core app, though. Based on the issue I mentioned earlier and the code you've posted, this looks like it should work but it's not. There shouldn't be anything you need to wire up for this, it should just work. Given that, you might want to file an issue about it. You may have found something that legitimately isn't working.
Before you do that, you might want to debug a little more. You can step right into ASP.NET Core source code and that could help you figure out what's up. The article I linked there explains how to set it up. It's not a two step process and needs screen shots to help or I'd put it right in here.
Set a breakpoint on your failing statement up there and then switch over to the Visual Studio "call stack" window. Click on the call stack frames higher up in the stack and see what's actually creating that context object. With a little clicking around and intuition you can probably figure out where the issue is. Maybe it'll point to something in your app you didn't realize you were doing, maybe it'll point to a bug in ASP.NET Core. If it's a bug in ASP.NET Core, having the information you found from your debugging session will be really helpful to that team.
Finally, I'd be remiss if I didn't mention that manually resolving a service in an attribute like this is technically service location rather than dependency injection and it'd be a better all-around solution if you avoided it entirely. There's an extremely similar question to yours right here walking through how to get around this with Simple Injector, though the principle holds for Autofac, too. Setting up model validators and using a model validator provider rather than attributes might be a better, more testable way to go. The answer in that question has more explanation on this.

Related

Possibility to modify or extend code in D365FO to suppress thrown error

Original class function creates an SQL query and executes it.
Since there is an syntax error in the query it throws an error. What's the correct way to achieve fixation? Class extension does not work, because CoC executes the complete original function.
originalFunction(..)
{
createSomeSQLQueryWithSyntayErrorInIt();
executeQuery();
}
The class in question is ReqDemPlanMissingForecastFiller. In method insertMissingDatesForecastEntries a direct SQL statement string is generated. The date variable nonFrozenForecastStartDate is added to the string, but is not escaped correctly as it seems.
If the SQL statement is executed, a syntax error occurs. If the statement is fixed, it can be executed e.g. in SQL Server Management Studio (SSMS).
In this specific case, based on your comments, you may be able to sidestep.
Create a new class ReqDemPlanMissingForecastFiller_Fix extending ReqDemPlanMissingForecastFiller then copy/paste the erroneous function and correct the mistake.
Create an extension class and change the newParameters static funcion.
[ExtensionOf(classStr(ReqDemPlanMissingForecastFiller))]
class ReqDemPlanMissingForecastFiller_Extention
{
public static ReqDemPlanMissingForecastFiller newParameters(
ReqDemPlanCreateForecastDataContract _dataContract,
ReqDemPlanAllocationKeyFilterTmp _allocationKeyFilter,
ReqDemPlanTaskLoggerInterface _logger = null)
{
ReqDemPlanMissingForecastFiller filler = next newParameters(_dataContract, _allocationKeyFilter, _logger);
filler = new ReqDemPlanMissingForecastFiller_Fix(); //Throw away previous value
filler.parmDataContract(_dataContract);
filler.parmAttributeManager(_dataContract.attributeManager());
filler.parmAllocationKeyFilter(_allocationKeyFilter);
filler.parmLogger(_logger);
filler.init();
return filler;
}
}
Code above was based on AX 2012 code. Stupid solution to a stupid problem.
It goes almost without saying that you should report the problem to Microsoft.
#Jan B. Kjeldsen's answer describes how the specific case can be solved without involving Microsoft.
Since overlayering is no longer possible, the solution involves copying a fair bit of standard code. This brings its own risks, because future changes by Microsoft for that code are not reflected in the copied code.
Though it cannot always be avoided, other options should be evaluated first:
As #Jan B. Kjeldsen mentioned, errors in the standard code should be reported to Microsoft (see Get support for Finance and Operations apps or Lifecycle Services (LCS)). This enables them to fix the error.
Pro: No further work needed.
Con: Microsoft may decline the fix or take a long time to implement it.
If unlike in this specific case the issue is not a downright error, but a lack of extension options, an extensibility request can be created with Microsoft. They will then add an extension option.
Pro: No further work needed.
Con: Microsoft may decline the extensibility request or take a long time to implement it.
For both errors as well as missing extension options, Microsoft also offers the Community Driven Engineering program (CDE). This enables you to develop changes in the standard code directly via a special Microsoft hosted repository where the standard code is not locked for changes.
Pro: Most flexible and fastest of all options involving Microsoft.
Con: You have to do the work yourself. Microsoft may decline the change. It can still take some time before the change is available in a GA version.
You can also consider a hybrid approach: For a quick solution, copy standard code and customize it as required. But also report an error, create an extensibility request or fix it yourself in the CDE program. When the change is available in standard code, you can then remove the copied code again.

Symfony2 - Do not render a view from controller like ZF setNoRender

Relatively new convert to Symfony2 from ZF1.
I have Googled and cannot seem to find the answer. Just wondering if there is a way to not render a view from a controller action in Symfony2.
In a ZF controller I could use:
$this->_helper->viewRenderer->setNoRender(true);
What is the equivalent in Symfony2?
In Symfony nothing is rendered for you automatically. If you need to render something, you have to do it explicitly. If you don't want to render, just don't do it :) Simply return a response:
return new Response();
Only job of a Symfony controller is to return a response. Rendering a template actually creates a response as well.
Wanted to give my Opinion:
Just because there is a possibility to render(ControllerMethod,{ params}) in a template doesn't mean you have to use it.
Doing so leads almost always to a shitty architecture, the turning point where projects start to be hard to debug, since you are mixing a VIEW (Presentation layer) with a CONTROLLER, that in turn renders another VIEW. You get the point.
Then when you have an error in the ControllerMethod, and instead you get a template error, not so nice isn't it ?
I vouch for strong architecture in software projects. This cheap solutions, like using this commodities, lead to the start of the bad. And I suggest to avoid it as much as you can unless there is no other possible way. And certainly there is!
That is the reason to use MVC. To separate Code from Presentation layer, start mixing both, and your architecture will leak.

testing ASP.net MVC 3 business/data logic

What is the best way to test data access layers and business logic in mvc 3 solutions?
I currently have a project where I am using repository classes to access databases, which in turn use hibernate. When I try to create a unit test for them in the auto generated unit tests, they always fail since the configuration for nhibernate is in web.config and and it doesnt try to look there. What am i doing wrong? This particular method returns this error
"The Web request 'http://localhost:35601/' completed
successfully without running the test"
The test methods look like this
[TestMethod()]
[HostType("ASP.NET")]
[AspNetDevelopmentServerHost("C:\\Users\\...", "/")]
[UrlToTest("http://localhost:35601/")]
public void GetByIdTest()
{
string someid= "..";
SomeObj actual = MyRepository.GetById(someid);
Assert.AreEqual(some, SomeObj.id);
}
How do i get this to work properly?
Putting the settings in the app.config should solve the issue you posed above however, the more correct answer is that you should be using a mocking framework to mock the nHibernate session.
The fact that you found an area that you would need to change to accomodate testing is great!!! That is one advantage of unit testing; you find coupling in your code that should be refactored.
I found another post that addresses what you are trying to do directly Mocking an NHibernate ISession with Moq. There are two answers in the post that offer to approaches which may be helpful.
I hope this helps. I havent used nHibernate so I can't speak authoritatively about it or that the link above will provide you with an answer, but each answer has ten upvotes so it looks like it was a solid post!

Spark lifecycle changes between Flex 4.5 and 4.6

I have recently migrated some of my projects to the shiny new Flex 4.6 SDK. I wasn't expecting much trouble since it was only a minor release. But as a matter of fact I got hundreds of errors all over the place. These errors would mostly come from Spark SkinnableComponents; for example:
override protected function getCurrentSkinState():String {
return mySkinPart.someProperty ? "normal" : "someOtherState";
}
would work just fine under 4.5, but would throw me a nullpointer error in 4.6. The reason is simple enough: in 4.6 getCurrentSkinState() is called before the skinparts are created, whereas in 4.5 I could be certain that the skinparts in the default state would be there.
Further investigation led me to believe that the initial state of a Skin is now undefined instead of the first state in the States array (until it calls getCurrentSkinState() that is).
Fixing these problems is usually pretty easy and requires just somewhat more defensive programming from my part. But that's not my real issue.
The real issue is that if the component lifecycle has changed, I'd like to know exactly what has changed and what parts of my projects might be affected.
I would be very appreciative if someone could shed some light on this or at least point me to the right place where I can read all about it (because the only release notes I could find were only covering the new mobile components).
Edit (this doesn't change the question; I just wanted to share my findings with you)
Another issue I just ran into: the dynamic modifier seems to no longer be inherited by subclasses. This is a pure ActionScript issue, so I guess it's the compiler that treats it differently.
Let me explain. Consider this class:
public class MyClass extends Array { }
Now, if I try to push a new item into this custom Array like this:
var t:Array = new MyClass();
t.push("hello");
SDK 4.5.1: no problem
SDK 4.6: "Cannot create property 0 on MyClass" at runtime
Apparently that's because Array is dynamic and MyClass isn't, so it's easily fixed:
public dynamic class MyClass extends Array { }
and the error's gone.
But what if I used a third-party library that has code like this and to which I had no source code access? My application would break and there's no way I could fix it. I mean: come on, that's no minor change for a dot-release.
I think there are two questions in there.
1 ) The real issue is that if the component lifecycle has changed, I'd
like to know exactly what has changed and what parts of my projects
might be affected.
I haven't seen a comprehensive low-level analysis of the differences between the two version. If you are really concerned, and you have the time to spare, you could use a diff tool to compare the source code for the two SDK's. There shouldn't be too many major structural changes - e.g. renamed classes or packages, so it might not be so bad. I expect a lot of classes won't have changed at all.
2 ) Another issue I just ran into: the dynamic modifier seems to no longer
be inherited by subclasses. This is a pure ActionScript issue, so I
guess it's the compiler that treats it differently.
This one is easier. dynamic has never been inherited. Object is dynamic, so if the attribute was inherited every class would have to be dynamic too.
If there appears to be a change in behaviour related to dynamic class instances, then there is something else going on in your code.

ASP.NET - How do you Unit Test WebControls?

Alright.
So I figure it's about time I get into unit testing, since everyone's been banging on about it for long enough. I've installed NUnit and gone through a few "intro to unit testing" type tutorials.
I'm currently putting together a small framework to help with the rebuild of one of our web apps, so I've created a VS2008 project for my framework and I want to unit test it as I go.
How on earth do I go about unit testing the WebControls? The methods are all protected or private, and since it's a framework, there isn't much else but WebControls.
Any pointers?
Burns
You can do model-view-controller or model-view-presenter type architectures without using a full blown framework. You already found out that unit-testing ui-components is difficult. There are ways around that but you probably don't want to go that route. Usually this will make your tests very hard to maintain, more maintenance nightmare's is something programmers can do without :-)
Try to separate out the functionality you want to test in a "controller" or "presenter" class. Then test that class. To make it more testable you can hide the usercontrol class (the view) behind an interface and make the controller or presenter talk to the view through the interface. That way you can mock up the view in your tests.
I know this sounds like a lot of work and it seems like a workaround but if you get used to this it's a realy nice architecture that makes it far easier to change ui behaviour. You can always start using a "real" mvc framework when you realy need it :-)
Ues the assembly:InternalsVisibleTo attribute and you'll be able to access those private members.
Put it in your webcontrol project's AssemblyInfo.cs (under Properties node)
[assembly:InternalsVisibleTo("YourTestProjectName")]
You have found the biggest pain point of ASP.NET. As far as sealed, private classes that hinder unit testing.
This is the main reason that TDD people will use a MVC framework (ASP.NET MVC, Castle MonoRail) as it provides a clear seperation from your view templates and your controller logic. The controllers are fully testable.
You could also look at testing components through the browser as a user would see them using a testing framework such as WebAii. I've seen it work and its pretty cool. I've also been told you can plug it into automated builds but I've not seen that as of yet.
Hope it helps ...
This is an old article by now, but I was using NUnitASP to write nunit tests for asp.net WebControls in 2004. That article gives a detailed example of testing a simple control using their concept of creating a corresponding "Tester" class that encapsulates the details of your control from you tests. The Tester can (should) also be in the same assembly as your control so can share some things between them (e.g. utility functions, constants, etc.).
I used the technique (and others use variants of the technique) still today to test very sophisticated controls.
I hope that is helpful.
The MVC framework mentioned above is the best way to test what the control does. However testing how it works is a bit different.
This is totally off the cuff but you could make the user control expose some protected methods and properties to return validation information and then have a testing user control inherit it. That control could populate fields, press buttons and what not. Kind of messy but it could work.
You can also take a look at this Rhino Igloo framework. It is a compromised MVC framework for WebForms.
Ivonna
can test WebControls in isolation, within the Asp.Net context
Just call session.GetControl("Path.ascx") and verify that it has all necessary properties.
You test them like this:
[Test]
public void ConditionQueryBuilderTest_RendersProperHtml()
{
var sw = new StringWriter();
var queryBuilder = new ConditionQueryBuilderStub
{
ID = "UnitTestbuilder",
QueryBuilderURL = #"\SomeAspxPage\SomeWebMethod",
ResetQueryBuilderURL = #"\SomeAspxPage\OnQueryBuilderReset",
FilterValuesCollection = new Dictionary<int, string> { {15, "Some Condition"}}
};
queryBuilder.RenderAllContents(new HtmlTextWriter(sw));
AppendLog(sw.ToString());
Assert.AreEqual(ExpectedHtml, sw.ToString()); // ExpectedHTML is the raw expected HTML
}
Here is my stub:
internal class ConditionQueryBuilderStub : ConditionQueryBuilder // ConditionQueryBuilder is a WebControl
{
internal void RenderAllContents(HtmlTextWriter writer)
{
RenderContents(writer);
}
}

Resources