I'm having an issue that, while not critical, still called my attention.
I happen to have an MVC4 web application where I've replaced the default controller factory for one implemented by myself, within this factory I use unity to inject the constructor parameters for the controller.
What I don't understand is why, for each and every request I make, the CreateController method gets called for every controller in the application and not just the one in the url and the ones called by partial views.
Is that behaviour normal? Is it necessary or is there a way to prevent it?
I see no reason for this and my research hasn't lead me to any good answer.
Thanks!
Ha! It turns out that when you use mvc sitemap solution it builds every controller for every request, by removing this line, that weird behaviour didn't happen anymore
#Html.MvcSiteMap().SiteMapPath()
Thanks anyway for the ones who read this and I hope someone finds this useful!
Related
What I'm trying to do is look directly at the incoming web request and manually select a controller to handle it. So far, I have created a custom implementation of IControllerFactory, but it seems that this runs after routing. Since the requests that are coming in don't match a route registered with MVC, it immediately goes to 404.
What I'm trying to figure out is how I can skip the routing portion straight to IControllerFactory step.
This sounds super odd, but I'm doing a proof of concept on creating routes at runtime. The idea is that, at runtime, I can download and load an assembly that has some controllers in it (i.e. a plugin) and then attempt register the route without restarting the service. I have most of it worked out I think, but I'm trying to figure out the routing part and it seemed easiest to simply grab the request and manually select the controller.
I've looked into implementing IRouter and then using app.UseRouter(myRouter) but I couldn't quite find what I was looking for.
Suggestions?
this is my first post, and I really have tried hard to find an answer, but am drawing a blank thus far.
My implementation of IDataContractSurrogate creates surrogates for certain 'cached' objects which I maintain (this works fine). What doesn't work is that in order for this system to operate effectively, it needs to access the service instance for some properties of the instance which it is maintaining from the interaction with its client. Also, when my implementation of IDataContractSurrogate works in its 'client mode' it needs access to the properties of the client instance in a similar way. Access to the information from the client and service instance affects how I create my surrogate types (or rather SHOULD do if I can answer this question!)
My service instancing is PerSession and concurrent.
On the server side, calls to GetDataContractType and GetDeserializedObject contain a valid OperationContext.Current from which I can of course retreive the service instance. However on the client side, none of the calls yield an OperationContext.Current. We are still in an operation as I am translating the surrogate types to the data contract types after they have been sent from the server as part of its response to the client request so I would have expected one? Maybe the entire idea of using OperationContext.Current from outside of an Operation invocation is wrong?
So, moving on, and trying to fix this problem I have examined the clientRuntime/dispatchRuntime object which is available when applying my customer behaviour, however that doesn't appear to give me any form of access to the client instance, unless I have a message reference perhaps... and then calling InstanceProvider. However I don't have the message.
Another idea I had was to use IInstanceProvider myself and then maybe build up a dictionary of all the ones which are dished out... but that's no good because I don't appear to have access to any session related piece of information from within my implementation of IDataContractSurrogate to use as a dictionary key.
I had originally implemented my own serializer but thats not what I want. I'm happy with the built in serializer, and changing the objects to special surrogates is exactly what I need to do, with the added bonus that every child property comes in for inspection.
I have also looked at applying a service behavior, but that also does not appear to yield a service instance, and also does not let me set a Surrogate implementation property.
I simply do not know how to gain access to the current session/instance from within my implementation IDataContractSurrogate. Any help would be greatly appreciated.
Many thanks,
Sean
I have solved my problem. The short answer is that I implemented IClientMessageFormatter and IDispatchMessageFormatter to accomplish what I needed. Inside SerializeReply I could always access the ServiceInstance as OperationContext.Current is valid. It was more work as I had to implement my own serialization and deserialization, but works flawlessly. The only issue remaining would be that there is no way to get the client proxy which is processing the response, but so far that is not a show stopper for me.
In structuremap you can control the lifeCycle of an object you register, normally some interface to a concrete type as follows:
x.For<IMyInterface>().Transient().Use<MyObject>();
So I can control the life cycle. However when resolving objects (Concrete) types that are not registered the life cycle defaults to what seems to be Transient().
This is obviously a convenient feature of structuremap as I surely dont want to register each concrete type.
However is there a way to override this life cycle without registration?
Furthermore it would be great if you can specify the life cycle of an object as an override much like:
ObjectFactory.With<SomeUnregisteredConcreteObject>().LifeCycleIs(...)
In such a case the life cycle would be modified for the next resolution to GetInstance
Any idea how any of this can be done?
You could create a child container & register the component:
var child = ObjectFactory.Container.CreateChildContainer();
child.Configure(config => config.For<SomeUnregisteredConcreteType>().Singleton());
var #object = child.GetInstance<...>();
I assume that the reason why you didn't want to register was because you didn't want the registration to hang around. I think this solves that problem.
I also don't know of built-in a way to specify a default lifecycle. However, I think it's probably possible using the IAutoMocker interface. You could probably browse through the code in that whole folder to figure out how to do it. The AutoMocking hooks into the container so that a component is requested that isn't registered, it calls into the IAutoMocker and gives it a chance to register a component. I imagine that you could use IAutoMocker to register components with a different default lifecycle.
If you succeed in this, I hope you send a pull request or write a blog post to share with the rest of us.
I was working on a presentation and thought the following should fail since the ActionResult isn't being returned on the right context. I've load tested it with VS and got no errors. I've debugged it and know that it is switching threads. So it seems like it is legit code.
Does ASP.NET not care what context or thread it is on like a client app? If so, what purpose does the AspNetSynchronizationContext provide? I don't feel right putting a ConfigureAwait in the action itself. Something seems wrong about it. Can anyone explain?
public async Task<ActionResult> AsyncWithBackendTest()
{
var result = await BackendCall().ConfigureAwait(false);
var server = HttpContext.Server;
HttpContext.Cache["hello"] = "world";
return Content(result);
}
ASP.NET doesn't have the 'UI thread' need that many clients apps do (due to the UI framework below it). That context isn't about thread affinity, but for tracking the page progress (and other things, like carrying around the security context for the request)
Stephen Toub mentions this in an MSDN article:
Windows Forms isn't the only environment that provides a
SynchronizationContext-derived class. ASP.NET also provides one,
AspNetSynchronizationContext, though it's not public and is not meant
for external consumption. Rather, it is used under the covers by
ASP.NET to facilitate the asynchronous pages functionality in ASP.NET
2.0 (for more information, see msdn.microsoft.com/msdnmag/issues/05/10/WickedCode). This
implementation allows ASP.NET to prevent page processing completion
until all outstanding asynchronous invocations have been completed.
A little more detail about the synchronization context is given in Stephen Cleary's article from last year.
Figure 4 in particular shows that it doesn't have the 'specific thread' behavior of WinForms/WPF, but the whole thing is a great read.
If multiple operations complete at once for the same application,
AspNetSynchronizationContext will ensure that they execute one at a
time. They may execute on any thread, but that thread will have the
identity and culture of the original page.
In your code, HttpContext is a member of your AsyncController base class. It is not the current context for the executing thread.
Also, in your case, HttpContext is still valid, since the request has not yet completed.
I'm unable to test this at the moment, but I would expect it to fail if you used System.Web.HttpContext.Current instead of HttpContext.
P.S. Security is always propagated, regardless of ConfigureAwait - this makes sense if you think about it. I'm not sure about culture, but I wouldn't be surprised if it was always propagated too.
It appears because the Controller captures the Context whereas using System.Web.HttpContext is live access to what is part of the synchronization context.
If we look at the ASP.NET MVC5 sources we can see that the ControllerBase class that all controllers inherit from has its own ControllerContext which is built from the RequestContext.
I would assume this means that while the synchronization context is lost after a ConfigureAwait(false); the state of the Controller in which the continuation is happening still has access to the state of the control from before the continuation via the closure.
Outside of the Controller we don't have access to this ControllerContext so we have to use the live System.Web.HttpContext which has all the caveats with ConfigureAwait(false);.
OK, I am building an application that will be using ASIHttpRequest in several places to either get JSON data from a web service or will be posting to a web service. I have it working, but really don't like having several instantiations of the request object sprinkled around the different view controllers (Login view controller, a tableview controller, and a detail view controller. I would like to move all my ASIHttpRequest methods to one class and just get back a dictionary of values that came back from the web service. The problem with this is that the delegate methods don't return that I need to have returned.
What would be some suggestions on how I can consolidate all the methods that will create an HTTPRequest and return values when the request is finished.
I can post code if need be, but this is really more of a general question and not a specific issue. If there are any tutorials on how this should be done, I would appreciate it. I want my code to be efficient and pretty :)
Thanks!
Your problem is going to be asynchronousity. I'm not sure what you mean by consolidate, but you can have a singleton (you can just use your app delegate) to call the requests. So you would do something like this:
[(MyAppDelegateClass *)[UIApplication sharedApplication].delegate doLoginStuff:(NSDictionary *)params delegate:self];
If you're doing all this asynchronously, you can't just call this method and have it return something. You'll be stuck with having some sort of callback to your view controller, which is the way ASI works out of the box essentially. At best, you can minimize the code to generate the request and set any repetitive properties.
I'm not sure what you mean by having the instantiations floating throughout. If it's memory you're worried about, it would be no different reusing the same object. ASI typically uses an autoreleased request, so it would be the same as creating it in a "consolidated" method. If it's just clean code, I would do a singleton way and maybe make a shortcut c-based method call in some type of Utilities class that you create and import in with your prefix file. But again, you need the callback methods in your view controller so it doesn't get too much cleaner than it already is meant to work. I share your pain though.
When any request comes back, I almost always have a method that parses the results. Typically I'm only working with one type of web service, so have a method that parses the results and (also logs it to NSLog for debugging purposes) also gives me back an NSDictionary or NSArray.