In my API's I am extending a custom class (myClass) which extends ApiController.
What I want to do is in the constructor for myClass, compare two values, and if they don't match, then kill the process. Meaning I don't want the functions in the API to actually get hit.
I'd like to return HttpStatusCode.Forbidden but I don't want to have to modify existing API functions to check a value that could be set by the controller.
I can't seem to find a good way to kill the request in the constructor and return the HttpStatusCode without blocking access to the rest of the API if it's supposed to continue to the requested API function.
Is there a relatively simple approach that could work for this?
you can set Authentication Filter to check that.
check more details here
Related
I have to implement HttpModule for a condition which should return http status 401 if condition get failed before request hits the controller. In this condition i need to access database to compare some values, My question is, Is it a good practice to use dbcontext inside the HttpModule implementation? or there are any other ways to achieve the same.
NOTE: I know the same can be done through the Custom Authorize attribute, but for that i need to change in lot of places.
Any help will be appreciated.
Usually we have a base controller in all our applications and that will be handling all the filtering and condition checking based on the request url, role and some more conditions, if all meets only the url redirection will perform and the request will hit the actual controller.
My suggestion is to have some kind of mechanism to keep base controller or some OOP approach in all your controllers, that will be much easier when you want to modify something which are common behavior
Probably you can give me a hint about good practices: In order to learn a bit more about Web API, I'm trying to create a Web-Service which helps doing some work with the TFS.
It would be very cool, if the Client could select, which TFS he wants to use by passing kindahow an object, which contains the needed data since TFS Service URL etc. But this gives me some troubles:
I created a type called TFSConfiguation, to kindahow pass these information, but this has some drawbacks:
I can't use Get-Method,s since I'd need to pass this object via Body
Every method in every Controller needs to get this object passed
I (think I) can't use Dependency injection, since I need to pass this TFS-Parameter to the Layers behind the Controllers
Other approaches would all hurt the open closed principles I guess, since the Controller really doesn't know which concrete TFS is used.
Is there a good possibility to make such stuff work? If not, what would be the best case for such a scenario?
I can't use Get-Method,s since I'd need to pass this object via Body
The ModelBinder can bind from the URI.
Every method in every Controller needs to get this object passed
Or you let the user store it in the session with a call, and read it from the session in other calls.
I (think I) can't use Dependency injection, since I need to pass this TFS-Parameter to the Layers behind the Controllers
Why do you want to inject this?
You could create a POST endpoint that accepts a TfsConfiguration object and returns a token, such as a GUID, that is passed to GET endpoints via the URL or a custom header. The flow could be:
POST TfsConfiguraton to api/tfstoken, which returns the token
Routes which require the token have URLs of the form api/tfstoken/...
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.)
I have a small website I implemented with AngularJS, C# and Entity Framework. The whole website is a Single Page Application and gets all of its data from one single C# web service.
My question deals with the interface that the C# web service should expose. For once, the service can provide the Entities in a RESTful way, providing them directly or as DTOs. The other approach would be that the web service returns an object for exactly one use case so that the AngularJS Controller only needs to invoke the web service once and can work with the responded model directly.
To clarify, please consider the following two snippets:
// The service returns DTOs, but has to be invoked multiple
// times from the AngularJS controller
public Order GetOrder(int orderId);
public List<Ticket> GetTickets(int orderId);
And
// The service returns the model directly
public OrderOverview GetOrderAndTickets(int orderId);
While the first example exposes a RESTful interface and works with the resource metaphor, it has the huge drawback of only returning parts of the data. The second example returns an object tailored to the needs of the MVC controller, but can most likely only be used in one MVC controller. Also, a lot of mapping needs to be done for common fields in the second scenario.
I found that I did both things from time to time in my webservice and want to get some feedback about it. I do not care too much for performance, altough multiple requests are of course problematic and once they slow down the application too much, they need refactoring. What is the best way to design the web service interface?
I would advise going with the REST approach, general purpose API design, rather than the single purpose remote procedure call (RPC) approach. While the RPC is going to be very quick at the beginning of your project, the number of end points usually become a liability when maintaining code. Now, if you are only ever going to have less than 20 types of server calls, I would say you can stick with this approach without getting bitten to badly. But if your project is going to live longer than a year, you'll probably end up with far more end points than 20.
With a rest based service, you can always add an optional parameter to describe child records said resource contains, and return them for the particular call.
There is nothing wrong with a RESTful service returning child entities or having an optional querystring param to toggle that behavior
public OrderOverview GetOrder(int orderId, bool? includeTickets);
When returning a ticket within an order, have each ticket contain a property referring to the URL endpoint of that particular ticket (/api/tickets/{id} or whatever) so the client can then work with the ticket independent of the order
In this specific case I would say it depends on how many tickets you have. Let's say you were to add pagination for the tickets, would you want to be getting the Order every time you get the next set of tickets?
You could always make multiple requests and resolve all the promises at once via $q.all().
The best practice is to wrap up HTTP calls in an Angular Service, that multiple angular controllers can reference.
With that, I don't think 2 calls to the server is going to be a huge detriment to you. And you won't have to alter the web service, or add any new angular services, when you want to add new views to your site.
Generally, API's should be written independently minded of what's consuming it. If you're pressed for time and you're sure you'll never need to consume it from some other client piece, you could write it specifically for your web app. But generally that's how it goes.
I have an authorize attribute that extends System.Web.Http.AuthorizeAttribute and overrides the onAuthorization method. It queries the DB with a token that comes from the request to see if the session is valid. From that, it knows the associated userId. I would like to somehow make the userId available to the controller of the action being called. Somehow setting an instance variable would be ideal because I want to unit test the controller. Perhaps that is not possible or there is a better way to go about doing it. Please let me know. I am using ApiController.
Thanks
Not sure if this is the appropriate way to handle this situation, but to answer my question, one can use actionContext.ControllerContext.Controller. From there I can call a setter or set a public instance variable Please let me know if this a bad approach. Regarding sessions with REST, I am not too concerned with having a pure REST implementation.