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/...
Related
I got a webapi Authorize filter which does some security checks on the queryString for "Get" calls.
For post methods, since I need to peek at the payload to retrieve the object (moreover, that would make my filter dependent upon my dtos, which I'm not a huge fan either...), and since I didn't find an easy way to open the post payload in the filter, I ended the subject by making the check in a controller method.
Obviously, the logic is the same in both cases.
So I put the validation logic in an abstract controller and make it "public static" so they can be called from the filter and from all inheriting controllers. I've read the google results from the follwoing query (avoiding calling static methods), and truth be told, I also find this ugly and untestable.
But what would be an elegant alternative ?
I've considered creating a (static ?) helper class but I only find it's syntactic sugar around the same concept.
I also think that helpers should not be IOc'ed maybe I'm wrong here ?
Thanks for your input !
You should include the details of validations that you wanna do on the query string to help us understand the problem in more details. However based on the information provided I have following to say.
Creating a static method in Controllers and accessing it in Filters is more ugly than exposing DTOs to Authorize Filter. The controllers acts as service layer and Filters are (to some extent) part of it(service layer) too. So there is nothing wrong if you have to expose DTOs to Filters. It can simply be seen as "DTOs being exposed to service layer".
However, if you really wish to avoid it, put an abstraction as part of your service layers which can be exposed to the Filters. Like you can create a interface (and its implementations) that exposes a validation method for your purpose that can be consumed from within the Authorize Filter.
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
I'm building an API using WebAPI that will be accessed via AJAX calls. However, the API controller will need more than just one POST method. I understand I can specify {action} in my routing, but because I've seen that this is not recommended - am I using the right tool? So 2 questions:
Is Web API the best tool for this, or is there something else I should be using?
Why should I not use more than one POST method in a WebApiController? Is including {action} in my routing a good enough solution to this problem?
1. Is Web API the best tool for this, or is there something else I should be using?
I think WebAPI is a fine choice for you, regardless of whether you have one or many POST calls per controller.
2. Why should I not use more than one POST method in a WebApiController?
To remain RESTFul you'll want a controller per entity type. Without getting too deep into details, a POST against a specific type of entity should be the 'ADD entity' call, and why would you have more than one of those? Having said that, you don't have to be fully RESTFul... if your requirements suite a multi-POST model then go for it, you can always refactor later if necessary.
...Is including {action} in my routing a good enough solution to this problem?
Again, if your goal is to be RESTFul then this isn't a great practice. However, if you have needs that are best achieved using action routings then go for it. REST is not the only model.
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.