I wanted to make my Controller methods register as [HttpGet] if they have "get" in the method name, the same goes for [HttpPost] if they have "create" etc.
How can I create an "attributeAssigner", that would go over the assembly and do the job?
In fact you can't. The example Ygalbel mentioned is a solution which, to my opinion is kind of cheat.
The code in the example creates another class (a proxy) which inherits from the class you want to apply the attribute(s) to. In fact, if you use reflection to retrieve the custom attributes decorating your class (its properties and methods) you'll find none of them. The instance of a class in the suggested solution is instance of another class, not yours!
I'm not 100% sure, but I can guess ASP.NET (Core) does exactly this, so it'll find no attributes decorating your controller's actions.
In order to use the suggested solution you'll need to write some code which will have to do the following:
Inspect your controller class and figure out where to add the attributes as you want,
Use the solution described in the example,
Unregister the original controller a part,
Register the proxy created by the example code as substitute to the original with the provider.
Maybe this text could be a good starting point but still, your idea needs to be clarified.
Anyway, if you do insist on its implementation I wish you good luck. This is part of the advanced topics in ASP.NET Core.
HTH
Related
I have created a few razorpages and have been putting a lot of code inside the Post and Get methods i.e
public async Task<IActionResult> OnPostSaveSetStatusAsync(int? id) {
}
think of it as opening a detailed page containing a button that should set a status on a specific order.
I now need to set the same status, i.e executing the same code but from a view (another razorpage) having the order selected.
if I put all my code in helper classes there is a lot of methods parameters that need to be sent in. i.e sqlcontexts, cache, httcontext etc. is this a good approach anyway?
...or should I just create methods in the original razorpage and call it from all other places? (like helper methods inside the class)
thanks
Plain and simple: if there's any code that needs to be shared in multiple places, it should go into another class that can be used as a dependency where it's needed. The listed dependencies don't seem like too much, though you should strongly consider whether you need a dependency on HttpContext. Most of the time, you should really just be passing in some value to a method. For example, if you need to work with a user id, pass the user id into a method on your helper class, rather than making the helper class take a dependency on HttpContext and fetch the id itself.
If you still have too many dependencies, then you're likely breaking the single responsibility principle. You may need multiple helper classes, or a different strategy entirely. It's hard to say anything definitive without knowing exactly what you're doing.
I have decided that my controllers are getting a little to cluttered, and decided to adopt a pipeline-style system as I have used in a WebAPI project. The pipeline consists of actions, that get more and more general, i.e: ViewAccountDetailsAction > AccountAction > AuthenticatedAction > EmptyAction. The Actions both add to the pipleline in order of inheritance, and expose members, or abstract methods for different scenarios.
My problem lies in how to return views from pipeline elements. In the WebAPI example, it was as easy as returning an IHttpActionResult which didn't have to perform any view rendering, however, MVC is required to render its responses differently, with the additional step of Razor.
As Controllers expose internal protected helper methods like View() or RedirectToAction, I cant use these outside the controllers themselves.
Is there an elegant way to render these out? I have seen a few ways to do this, each being either cumbersome, or giving me uncomfortable feelings.
My most favoured way at the moment is to make an internal base class hiding the protected methods, and making them internal, whilst calling the base methods. The controller instance will then be provided to the instantiated action. Is there anything overly wrong with this? I can't think of any abusable cases, but wanted to see if there was any community consensus on the matter.
I would recommend taking your approach a step further.
This took a little bit of research, but I based it on an approach I did for a client with Web API 2. Basically the idea was we created a custom ControllerSelector, ActionSelector and ActionDescriptors and a controller base class that exposed a strongly typed business layer. Then through reflection/custom attributes, we marshalled the call to the business layer, handling transformations to an HttpResponseResponse message generically, including errors.
Controller: http://pastebin.com/iK8ieBKD
ControllerSelector: http://pastebin.com/qvEbggrP
ActionSelector: http://pastebin.com/CEFNeKZZ
The first thing you'll need to do is look at:
http://www.dotnet-tricks.com/Tutorial/mvc/LYHK270114-Detailed-ASP.NET-MVC-Pipeline.html
Unfortunately ASP.NET MVC5's pipeline is much less flexible than Web API 2's. However you can do three things:
Custom Controller Factory: https://msdn.microsoft.com/en-us/library/system.web.mvc.icontrollerfactory(v=vs.118).aspx
Custom ControllerDescriptor
Custom ActionInvoker that interprets the ControllerDescriptor: https://msdn.microsoft.com/en-us/library/system.web.mvc.iactioninvoker(v=vs.118).aspx
This way you leave your controller to do what controllers do best, and create a contract for your controller to generically interpret using your new pipeline. This is really the right way to do it.
High jacking/bastardizing the controller as you suggested I don't think is a great plan, this is a much more robust solution, however it would take significant effort. Best of luck!
I was wondering how to go about writing a custom attribute which can access both the input and output parameters of a function.
Below is an example of what I wish to achieve
[CustomAttribute("Creating Foo")]
public Foo CreateFoo(Foo newFoo)
{
//do logic
return newlyCreatedFoo;
}
From this, the CustomAttribute will create an entry in a DB with the "Creating Foo" tag, which is easy enough to do, but I want to be able to access both newFoo and newlyCreatedFoo as well. Is this possible?
Custom attributes can't do that in general: their purpose is to add metadata to a method to view during reflection.
That being said, there are some cases where attributes are leveraged to do that. For example, ASP.Net MVC uses custom attributes that implement IAuthorizationFilter to provide security for some web pages. This works because ASP is using reflection to launch the methods in the first place. Once it gets the method it checks to see if any attributes are IAuthorizationFilters, and does some extra work when they are. See this link for some more info.
Another way to think about this is to consider aspect-oriented programming. I think AOP frameworks for c# tend to make compile time decorations to methods based on attributes that implement a certain interface, but I have not used one.
My favorite way to deal with this is the good old Proxy pattern. Create a logging proxy.
I am afraid that this is not possible with custom attributes.
This could be achieved with post compilation processing. Tools like PostSharp would allow you to achieve this functionality.
Perhaps you should rephrase your question to "How can I intercept calls to specific methods and log the arguments"?
A custom attribute is just a decoration on a method. It does not intercept or in any way affect the execution of a method. It doesn't even know what member it is attached to.
If you want to intercept the calls you can use a dependency injection framework, or any other AOP framework for .NET to do just that. Some of them actually use attributes to mark their targets, but that isn't a requirement.
PostSharp is just one AOP framework for .NET.
Another option, is to use an IoC/Dependency Injection library like MEF to wrap your class in a proxy object that will intercept all calls and only log the values of the methods decorated with a special attribute.
We have an MVC app that injects our content into a HTML wrapper which supplied by the client.
There are multiple wrappers, such as fund.html, share.html, factsheet.html, and home.html
The wrapper is stored on our webserver. We need to load the wrapper into Site.Master and inject our content into the wrapper's content area, and then render the page.
Basically, I need some advice on how to determine which wrapper to use.
At first, I was thinking that we could map a wrapper to a Controller. So, if we're rendering a View on FundController we could use the wrapper Fund.html, and if it's ShareController, we could use Share.html. In BaseController, which is implemented by both FundController and ShareController I was getting the name of the Controller and using that to load the file, and all was good.
But as requirements changed, it became apparent that this won't work because sometimes we need a controller to render different Views which use different wrappers. So FundController might now have to render Fund.html & Factsheet.html. Now, the Controller doesn't map directly to a wrapper file.
I then thought that I could use the Action name instead of the Controller name to determine the wrapper I should use.. such as public ViewResult Fund() would correspond to Fund.html, and public ViewResult Factsheet() would correspond to Facthseet.html, but this is not ideal because the method that fires in BaseController will fire for all action methods that I execute, including those that return PartialViews and other Action Results, for which I don't want to load wrappers. I only want wrappers for ViewResults.
So, this being the case, I was wondering how best to determine which wrapper to use for which ViewResult I'm executing. One option is using a 'magic string' which, whenever a given Action Method is executing it sets a property in BaseController which can be used to determine the wrapper to use.. but I don't like magic strings. I'd prefer to avoid a hacky approach.
I was also thinking of using an Action Filter which could do the work of loading the wrapper associated with whichever Action Method the filter is associated with. But before doing this, I'd like to get the opinion of other people who may have had to deal with an issue similar to this before. Or if anyone could advise on a better approach to take? What is the best way for me to go about doing this? Thanks.
It sounds like you've already spent a good amount of time thinking about the best way to handle this. Perhaps just combining your existing ideas:
By default, controllers & actions will retrieve their wrappers based on convention. FundController uses the Fund.html wrapper, and ShareController uses the Share.html wrapper.
But also allow for the override of wrappers on a per-action basis, using an ActionFilter.
Barring additional requirements changes (multiple wrappers in multiple content areas within your Masterpage, for exampl), this should cover your needs, no?
I think your Action Filter is one option, or you might want to Extend your very own ViewEngine that is responsible for deciding when to use the wrapper, and when not to.
http://www.singingeels.com/Articles/Creating_a_Custom_View_Engine_in_ASPNET_MVC.aspx
Hope this helps...
I think it might be nice to mimic the rules of views. There is a rule where to look for views, but you can also state the viewname in the action.
The nice thing would be that developers had the same set of rules.
I dont know how you can implement this but I guess its possible.
I know it's possible, and I've seen simple examples in the documentation, but are they being used in the wild?
I use attributes at the class and method level all the time, but have never used them on method parameters. What are some real-world examples, and the reasons for the usage?
I'm not interested in seeing a textbook example, mind you. There are plenty of those out there. I want to see an actual reason why it solved a particular problem for you.
EDIT: Let's place aside the discussion about whether or not to use attributes in the first place. I understand some people don't like them because they "dirty" their code. That's for a different discussion!
You can for example create a ValidatorAttribute for every parameter, then before calling the method, you can reflect the parameter attributes and do parameter validation. Then call the method if all ok.
(I've left this answer here in case others find it a useful intro to PostSharp, but it doesn't actually answer the question properly! I misread the question as asking about method attributes instead of class attributes. Doh. From what I remember, the generated SOAP classes use parameter attributes. LINQ to SQL uses return attributes and may use parameter attributes too, when it comes to stored procs.)
I'm used them with PostSharp, although admittedly only in a quick demo so far (I haven't used PostSharp in production).
See my blog post for more details.
Oh, and of course NUnit tests specify [Test] all over the place :)
Jon
I haven't used them myself, but Scott Gu's post about ASP.NET MVC Preview 5 shows parameter attributes being used to declare model binders for action methods.
The link is at: http://weblogs.asp.net/scottgu/archive/2008/09/02/asp-net-mvc-preview-5-and-form-posting-scenarios.aspx
He notes that the attribute isn't yet available in Preview 5, but should be available in future builds.
Castle Monorail has been using for many years to databind request parameters. See http://www.castleproject.org/MonoRail/documentation/trunk/integration/ar.html
Dependency Injection is a very good example scenario.
ObjectBuilder (a dependecy injection container, part of the P&P Enterprise Libary, soon to be replaced by Unity), uses them all over the place to attribute what the container should be injecting at runtime. Here's a quick example of the constructor for a controller class that has a state value (injected from whatever state provider is active, usually HttpSession) as well as two service dependencies (a locator and an authorization service):
public class ShellController : ControllerBase, IShellController
{
public ShellController([StateDependency("State")] StateValue<ShuttleState> state,
[ServiceDependency] IHttpContextLocatorService contextLocator,
[ServiceDependency] IAuthorizationService authService)
: base(state, contextLocator, authService)
{
// code goes here
}
}
Unit test frameworks use them extensively:
To do anything in nUnit or MSTest, you have to decorate methods with a [TestFixture] or [TestClass] attribute.
My favorite? MbUnit's [DataFixture] attribute: lets you seed test cases with specific test data either within the attribute directly or an external resource.