ActionFilterAttribute behavior without MVC - c#

I'm looking at some code we have in a particular library in our project. This library contains API calls that may or may not come from MVC. Many of them start with the exact same code... save the current lazy loading value and then turn it off. At the end of these methods, the lazy loading is restored to its original value.
What I am wanting to do is add some sort of attribute on these methods to handle this. Since it is a library rather than MVC code, ActionFilterAttributes are not available, and adding a reference to MVC seems architecturally rather inappropriate in this library. Is there something else I can use to behave similarly (i.e., add an attribute to a method so that code associated with the attribute runs at the beginning and at the end of the method)?

You want AOP.
Look at PostSharp.
In particular, action filters are implemented within the MVC pipeline, and wouldn't work at all for you.

Related

What does the attribute "[ApiExplorerSettings(IgnoreApi = true)]" do?

EDIT: I'm aware of what attributes in general do, the question is for this specific attribute alone. Sorry for the confusion!
I've read the following question, along with this one, which point to how the attribute is used to ignore the generated swagger/swashbuckle documentation for specific methods or whole controllers. (documentation is the swagger page with all the api's listed I believe?)
But other than swagger/swashbuckle (which is a NuGet package), what other function does this attribute possess in ASP.NET?
When applied to a public method on a controller, it prevents that method from appearing in the swagger ui.
First of all, to clarify, an attribute in C# does not trigger anything by itself. External code searches for classes, methods or properties marked with a specific attribute, and act accordingly.
Of course, there are many building blocks in ASP.NET MVC, it can be confusing sometimes.
This attribute is used by Swagger to hide the endpoint.
Also usedd (in .NET core at least) by the given implementations of IApiDescriptionProvider and other related interfaces, but that would be effective only if you actually use them (by configuring them up in Startup.cs)
(for some more details and example, see https://andrewlock.net/introduction-to-the-apiexplorer-in-asp-net-core/)
This attribute helps to control the visibility. We can use this on the controller class or an action method when we want to hide that specific controller or action from showing in the swagger UI.

Dynamically Ignore WebAPI method on controller for api explorer documentation

we have implemented a webAPI and we have a number of API controllers.
We provide an API documentation for our API and what we want to do is to exclude certain web methods from the documentation but we want this to be done dynamically depending on the environment we are running.
just to give you an understanding of what I mean, let's say I have the following web method
[ApiExplorerSettings(IgnoreApi = true)]
public Product getProduct()
{
...
}
By setting the IgnoreAPI property on the ApiExplorerSettingAttribute to true, it excludes the web method from the documentation which is what we want but we need a way of setting the "true" value dynamically.
Ideally we would like to have a database table with bool values for each webMethod and based on these set the value for IgnoreAPi property.
Is there a way to achieve this? Your help will be much appreciated.
You can implement a custom IApiExplorer and register it in Web API's services to have full control over which APIs are listed or not.
Here's a blog post from the dev who implemented most of this: https://learn.microsoft.com/en-us/archive/blogs/yaohuang1/asp-net-web-api-introducing-iapiexplorerapiexplorer
And here's the IApiExplorer interface definition: http://msdn.microsoft.com/en-us/library/system.web.http.description.iapiexplorer(v=vs.118).aspx
One thing you could do is derive from (or re-use the existing source of) the existing ApiExplorer implementation and call base to get the default list, and then further filter it however you want.
And per s_hewitt's comment, the recommendation is:
Deriving from ApiExplorer, implementing the two methods ShouldExploreAction and ShouldExploreController is the way to go. Make your DB calls in those two methods, looking up based on route, controller and action.
I don't know much about the documentation generation of WebAPI, but I do know about attributes. Attributes are compiled into the code and result in hard coded values being held in directly in the data in the EXE or DLL. They cannot be changed.
Having said that, you might be able to apply attributes as a second set after normal compilation. Perhaps PostSharp could help here? Perhaps changing the solution configuration could be a way of indicating the environment you want to build for and this which methods get the IgnoreApi treatment. You could create your own attribute to apply to the methods that describes which environments the method should be ignored within. (I think it's more likely you'll be able to do what you want in PostSharp if you don't try and call a database to get hold of this data.)

using attribute to read Method Parameters

I want to log the entry of methods. In entry log I would have inputs\parameters received by the method. This has to be done for thousands of methods.
I thought of doing this logging of input parameters using C# ATTRIBUTES, since they fired before method call. (Something similar to ActionFilters in MVC)
Is that possible to read method parameters through attributes?
The concept you are looking for is called aspect oriented programming (AOP). It is a technique that allows you to "weave" in blocks of boilerplate code across your application code. Logging is a perfect example for that. You can either go the hard way and implement logging before and after each method call manually (which is on the one hand not feasible in large projects and on the other hand error prone).
Or you can use an AOP Framework that allows you to define these cross cutting functions in one place and apply it declaratively to your application code. There are several approaches to achieve this; one is to create IL after the build of the application logic and therefore integrating the aspects at compile time. A well known example for this is PostSharp. There also is a free edition that is good for the start.
BTW: PostSharp heavily relies on attributes, so you're on the right track.
Another option is to integrate the aspects at run time (keyword is interception). Most IoC Frameworks offer this. This approach is easy to use but has some downsides IMHO (weaker runtime Performance, only virtual methods can be intercepted).
Attributes are not 'fired before method call', the code that invokes a method that is decorated with an Attribute may (or may not) do something based on the presence of the Attribute.
The Attribute doesn't know the member it is applied on, nor can access it in any (straight forward) way.

ModelMetadataProvider overrides alternative to MetadataTypeAttribute

After playing around with Asp.Net MVC for some time I have decided to actually use it in a project. One of the issues that came up is that the frontend site might have different validation rules for a given model than the admin panel.
I am aware of the MetadataType property but since you have more than one contexts this would not work for us out of the box.
In order to solve this I implemented a custom ModelMetadataProvider that redirects the default ModelMetdataProvider to a different type based on the request's execution context. This works pretty well for displaying the needed UI.
The part of this solution I do not like is that I ended up reading the stack from my custom model metadata provider to determine if the given call is for model binding. This is because when I did not do that I would correctly get "Object does not match target type" during the call to TryUpdateModel from the Controller since the model binder was trying to use properties from type A to set values to an instance of type B.
Is reading the call stack such a bad idea for production?
Is there a way to replicate the MetadataTypeAttribute behavior selectively without using attributes?
Thanks in advance,
John
This is one of those instances where you wish the ASP.NET MVC Team hadn't sealed a class - I'm sure they had their reasons. I was going to suggest simply creating your own attribute, derived from MetadataTypeAttribute.
One way to go about this is to take the source of the attribute and write your own:
http://dotnetinside.com/framework/v4.0.30319/framework/v4.0.30319/System.ComponentModel.DataAnnotations/MetadataTypeAttribute
Although, of course, this makes your code less maintainable.
I would assert that to the best of my knowledge, you are already making the right decision with a ModelMetadataProvider as your solution. I'm a little nervous for you regarding analysing the call stack though, change locations, move something to an area; you get my drift, i.e. it would be very easy to break the code with a build time decision that isn't found until runtime or beyond QA.
You haven't supplied how the context is roughly determined, but I would personally tackle that by adding a property to the class itself with an Enum (finite possibilities and design time breakage) with a list of possible contexts, then during spin up of the class, populate it, ready for execution of the Provider, which will pass through the correct metatdatatype based on the value of the Enum.
Many ways to skin this cat, but something that is going to break on build will serve you best, IMHO.
Unless you are using MVC 6 you may find ModelMetadata Fluent Configuration useful.
Some nice examples of how to use it can be found here and here.
What is really important is that it is just code which is completely under your control. Thus, once you have different contexts, you may decide to define different configurations, or you may play a bit harder and make (a set of) different registrations for different contexts.
What really helps is "decorating" (the term used on purpose!) properties of a base class, at least nothing seems to stooping you from doing it.
EDIT: Model Metadata shouldn't be confused with WCF RIA Services Contrib.

Why would you use 'custom attributes' in your code (.NET)

Could anyone explain the benefits (or reasons) to use custom attributes in your code. Of course I use (and understand the purpose of) defined attributes in certain scenarios (WCF, Serialization etc.), but I cannot imagine any algorithms where I would need to create and use my own custom attributes. Could someone provide a real-world case where usages of custom defined attributes bring something to a project.
The same reason as for WCF etc, but something that's specific to your project - you want to add some metadata to some members (types, fields, methods, whatever) to specify something about the mechanism involved, and it's not something which is covered by existing attributes.
For example, NUnit wanted to add their own indication that a particular type contained unit tests - there was no such existing attribute, so they created TestFixtureAttribute.
It's a relatively rare event, sure - but it can happen.
If you want to write your own system like WCF, Serialization, etc...
If you write code that iterates over types or members and does things with them, you will frequently want to use your own custom attributes to mark some members as being different or special.
I regularly use custom .Net attributes to support tooling in my infrastructure. One example was from very early in the .Net days (C# 1.0 to be exact). I was working on a research project which had a native C++ front and a brand new C# back end written by yours truly.
The front and back end shared a very similar object model which was evolving very rapidly. Not wanting to have to hand code both a C++ front end model, C++ serialization mechanism and a C# serialization mechanism I chose instead to attribute my C# types with custom attributes. They told me the parts of the model which were shared between the front and back end.
Once those attributes were in place I wrote a quick and dirty tool which
Parsed out the attributes to construct the core shared model
Generated the C# serialization code
Generated the C++ code
Generated the C++ serialization code
This made it dirt simple to keep my model up to date between my 2 projects. Just change the C# code, compile and re-run my tool.
I have used annotations in a custom AOP (Aspect-Oriented Programming) system I developed a while back. Attributes are also very useful for controlling orthogonal concerns like code generation.
Custom validation is a very good use case and can be seen from these links:
http://odetocode.com/blogs/scott/archive/2011/02/21/custom-data-annotation-validator-part-i-server-code.aspx
How to create Custom Data Annotation Validators
They can be used for marking tests, as in MBUnit for example. They can also be useful for code that inspects and loads classes (like a Plugin system) to provide meta-information.
They are really useful in building object mappers / ORM tools as well. If you ever decide to roll your own mapping system they are almost "required" to get all the functionality one would need. It's used more for making methods / classes more generic and using reflection to determine how to handle objects / select objects /etc...
To give you a specific case where I've used them. I once had to interact with a Mainframe screenscraper. I created a custom attribute to annotate which fields I wanted to send from my classes to the Mainframe, names that fell outside of conventions, special rules to deal with formatting and collections. I then had a class which was able to reflect over instances and realise which subset of fields were needed to interact with the mainframe screen scraper appropriately.

Categories

Resources