Is there some way to acces the user object from a custom routing class?
I'd like to add a parameter when generating a url, and that parameter is inside the user session, so I need to access it.
The only way I found to access is using the sfContext::getInstance()->getUser(), but it's known to be inefficient.
Thanks!
I'd write it the way you mention - I've used that method in similar situations and never had an issue performance wise, and suspect you will be the same.
Also, never heard this mentioned as inefficient, but it is a little bit frowned upon because it couples the route to the context. An alternative that would overcome this would be to pass the variable to the route as you would any other parameter (or the user object if you need the whole thing). If you need to do this a lot, you can always make a custom url helper that wraps the existing url_for method, adding this param to any other details passed.
A workaround I have implemented (for now), is getting some data from somewhere (not ideal, I'm willing to access the user session yet), and set a new parameter inside $params, in the generate method of the custom routing class.
Hope it helps...
Related
Short story: I want to get the Injectee from within a Supplier that is bound using Jersey's AbstractBinder.bindFactory(Class) method.
Basically to work around JERSEY-3675
Long story: I was using the org.glassfish.hk2.api.Factory method to create an instance of my RequestScoped Object and life was good.
I moved my registration into a Feature and then life was not good because of JERSEY-3675.
Long story short, org.glassfish.hk2.utilities.binding.AbstractBinder do not work inside Features. No problem, I thought, I will use org.glassfish.jersey.internal.inject.AbstractBinder.
Slight problem I encountered: Jersey's AbstractBinder.bindFactory() method takes in Supplier not Factory. No problem, I thought, I will use Supplier (I like it better, anyway).
Bigger problem I encountered: I had been using org.glassfish.hk2.api.Injectee to get the InstantiationData about who was calling the injection. This does not get injected if I do not use HK2's Factory. The javadoc even says the method is 'indeterminate' if not called from Factory.provide().
Even though there is a Jersey Injectee (org.glassfish.jersey.internal.inject.Injectee), this seems to only be available when using Jersey's InjectionResolver. I do not want to use InjectionResolver because
HK2's InjectionResolver must be Singleton but I want to have RequestScoped stuff in my injected object.
On second read, though, Jersey's InjectionResolver does not say anything about needing to be Singleton. Can anyone confirm?
I do not want to create my own annotation for this (I have created my own annotations and InjectionResolvers for other cases)
I do not feel confident overriding #Inject with an InjectionResolver. Not sure what that means or how I would be able to register multiple of those and have them work together (one for each Feature)
In meantime, I am using the workaround mentioned in the bug.
I am new to DI scene, so if something (or all of it) does not make sense, please let me know.
I'm creating a wrapper class for an API because my application will need to call it with different credentials at different times. I started off passing the wrapper a method and arguments and then doing (basically) this when calling it
call
set_credentials
TheAPI::Thing.send(method, args)
ensure
reset_credentials_to_default
end
HOWEVER, I realized that a challenge here is if I need to chain methods; this way I can only call one at a time; so for example I wouldn't be able to to TheAPI::Thing.find(id).delete. (At least, not without re-calling the credentials setter, which is undesirable since I have to fetch a token).
Is there a way using ruby to collect the methods/args being chained onto an object? Or would I simply have to pass in some ugly ordered set of things?
EDIT: Surely activerecord's query builder does something like this, collecting the chained methods before returning, and then after they're all collected, ensuring that as a final step the query is built, called, and returned?
the way to do this is to define a proxy object and to pass that around instead of the actual thing.
In the object itself, hold a reference to the Thing and override method_missing: http://ruby-doc.org/core-2.1.0/BasicObject.html#method-i-method_missing
In the method missing do the thing you are doing today. In a nutshell this is what ActiveRecord is doing.
As far as chaining things, I don't believe it would be a problem as methods that can be chained usually return references to self. When you call the 2nd method in the chain, you actually have done the work for the first one and have an object that has the 2nd method in the chain. The only trick you need to pay attention to is that you want to return a reference to the proxy class that encapsulates the thing instead of the actual return of the thing if you want the chaining to succeed.
Give it a shot and ping me if you run into trouble and I can spin up a fully working example.
I've read the documentation, and it confuses me every time, just because it doesn't answer some basic things. I realize the main purpose of the class method ::respond_to (which is normally used at the top of the controller) is for use in conjunction with respond_with. And the purpose of the instance method #respond_to (normally at the end of each action) is to provide different responses for different formats.
I also know that it's possible to consolidate the instance method version to look like the class method, but used inside an action, for conciseness, like this: respond_to(:html). The use case for this is another purpose of #respond_to, which is to refuse requests for unspecified formats. (I think it raises an UnspecifiedFormat exception)
Does the class method also have the same functionality? For instance, if I have a controller that only responds to html, if I just put respond_to(:html) at the top of the file, can I expect it to refuse requests for other formats? I've had problems with it doing that, so I don't know if I've been doing something wrong, or if it's just not supposed to work the same as the instance method in that respect.
So I finally ran an experiment, and no, the class method respond_to does NOT refuse requests to unspecified formats like the instance method does. Kind of a confusing disparity, but there you have it. If you want to refuse requests for invalid formats (with a 406), you have to specify valid formats inside each action of each controller (using the instance method respond_to)
My base controller has:
[Authorize(Roles = "sys_admin")]
I want to have one action in a controller that's different and is available to "user" and "sys_admin". Can I override and how do I do that?
Also any suggestions on what else I could put in a base controller that might make my coding simpler. For example what's in your base controllers?
Anything that you use in every controller - attributes, methods, properties, etc. The same stuff you would put in any base class.
Just to add to the discussion, I have a few extra utility methods in my shared controller. I write a bunch of little apps for corporate use, so I try to repeat code as little as possible here.
getContext(): Puts together an object containing user info like IP, hostname, id, etc. for logging purposes.
Shared Views/Partials such as Error, Default, and Redirect (used for redirecting ajax requests).
RedirectToError(): I created this to use similar to RedirectToAction. I load up an ErrorObject with info, throw it in session, and return a Redirect to my Error page.
General logging and tracing methods so I can quickly spit out information to a file.
I override OnActionExecuting and check if my session is still valid and redirect to login if its not. Probably better with attributes...went with quick and dirty. Also trace Url.PathAndQuery for debugging here.
Any data access actions that I would use across views with ajax, like loading up a list of departments.
OnException is overridden, as well.
That's what I got in mine so far.
In my base controllers I actually put some utility method ([NonAction]) collected over time. I prefer to add functionalities to Controllers by decorating with Attributes if possible.
Lately my base controller has:
some Properties for retrieving information about the current user (my app
specific informations, not the User.Identity stuffs)
A simple protected override void OnException(ExceptionContext
filterContext); override for at least logging unhandled exception and have
some sort of automatic notifications
A bunch of Cookies related methods (WebForms auth cookies management
for example)
A bunch of usefull standard attributes (usually [Authorize], [HandleError], [OutputCache]) in its declaration.
some standard method for preparing widely used json data types on the fly (when possible I prefer to have a standard json object with ErrorCode, ErrorMessage and a UserData).
With time you'll find more and more utilities to keep with your controllers, try to keep an assembly with the simpler ones (avoiding heavy dependencies), will come handy with your next MVC projects. (the same goes for Helpers and to some degree also for EditorTemplates).
For the Authorize Attribute part, well, I think the cleanest way is to write your own AuthorizeAttribute class, specifically a NonAuthorizeAttribute. I think I've also seen it somewhere on SO.
You can also play with the Order Property of the default AuthorizeAttribute - put different Order in BaseController and in Action, in order to have Action's one executed first, but I cannot recall if you can actually break the Attributes processing chain.
Regards,
M.
We cant tell you what you need in your base controller, you have to reveal these kind of thing as you implement your controllers and see repeating code.. Dont hesitate to refactor these things to your BaseController, and keep in mind, that maybe you should have 2 or more BaseControllers, or 2-layer hierarchy of BaseControllers.
I give you two tips, what i always have in my BaseController :
super-useful helper method for interface-based model binding :
protected T Bind<T, U>()
where T : U, new()
where U : class
{
T model = new T();
TryUpdateModel<U>(model);
return model;
}
You can then have multiple "sets" of properties you want to bind in different scenarios implemented as interfaces, and simple model bind your object (even existing object, from DB) with incoming values.
2.If you use custom AcionResults (maybe your specific Json builders etc.), make your "shortcuts" methods in BaseController. Same thing as View() method is shortcut for return new ViewResult(...)
To add more to the good responses already here -
caching caching caching caching
See
Disable browser cache for entire ASP.NET website
This is similar to the question asked at StructureMap - Override constructor arguments for a named instance, but different in the respect that I don't know the type at coding time and therefore cannot use the generic form of GetInstance().
So while:
ObjectFactory.With(IFoo).GetInstance<IBar>("foobar");
will work, there is apparently no way to call:
ObjectFactory.With(IFoo).GetInstance(typeof(IBar), "foobar");
I have a workaround using a private generic method and the MakeGenericMethod() on that private method's MethodInfo.
As you might imagine, I'm not really happy with that approach, but I cannot see any other way out of the situation.
The method you want is GetNamedInstance(), which is not available when you use the With() method. I'm sure it would not be too hard to add it, maybe you could email Jeremy Miller and see if he can add it in StructureMap 3. Or submit a patch :)