I have a WFC Data Service using OData v3. Following REST specification I created a method invoked by POST that adds an entity (a Client in this case) using Entity Framework.
Everything works great and adds as expected but the thing is I'm not pretty comfortable passing all the parameters I need using the query string, meaning the "typical" POST is usually application/x-www-form-urlencoded and sends the parameters in the request body instead of the query string. WCF Data Services don't seem to allow this in a relatively straightforward way.
Are there any major drawback/security issue (besides the obvious size limitation of the query string) using the query string that I should know of? Can I send parameters in the request body and use application/x-www-form-urlencoded without jumping through millions of hoops?
It just doesn't feel right to use the query string for everything.
The standard way of creating entities using OData is to send a POST to the entity set URL (of the entity set you want the entity to insert into). That POST has the entity in its body either as ATOM or JSON payload. http://www.odata.org/documentation/operations#CreatingnewEntries
Using service operations to create new entities is definitely possible, but it's not that common. It's currently not possible to send the parameters to the service operation inside a body (without some serious hacking).
Related
I started recently to use CosmosDB with the Core (SQL) API to use CosmosDB as DocumentDB. But the Interface of CosmosDB, primarily CosmosDBClient.CreateDocumentQuery() [1] and .CreateDatabaseQuery() [2] accepts only Expression or SQL statements. Now I am stuck because the query gets in as a string but has to be translated somehow and I am afraid that whatever I try will never be good enough to be considered as stable.
The question would be now how to handle the query that comes from a web interface and should be used from an internal sqlstatement/expression interface?
If you ask why the query is getting in as a string: We use microservices which are triggered via (e.g.:) HTTP GET. And with this GET a query should be provided, for example as Parameter ...?name=Hans&surname=Wurst Or even ODATA.
Links:
[1] https://learn.microsoft.com/en-us/dotnet/api/microsoft.azure.documents.client.documentclient.createdocumentquery?view=azure-dotnet
[2] https://learn.microsoft.com/en-us/dotnet/api/microsoft.azure.documents.client.documentclient.createdatabasequery?view=azure-dotnet
Where you can use the SQL API with a client library to create a document (See DocumentClient.CreateDocumentQuery Method) and create a database (See DocumentClient.CreateDatabaseQuery Method), there is a corresponding REST API to make that same call and will return items in a JSON string:
REST: Create Document
REST: Create Database
As an option.
I'm looking for best way of passing a common parameter between pretty much all of my web API methods. The parameter in this case is a repository identifier as there is a choice on login into the SPA over which database is to be used to read and write data from/to. This choice is then stored in the app and used in all future API calls.
The choices I'm considering are:
Route value - this means adding a route parameter to all of the routes and ensuring it's sent for each call the SPA makes: [Route("api/{repo}/{user}/{id}")]. The advantage here is it's maybe more explicit.
Custom header value which is applied blindly by the app on every API request and used by the API whenever required. It is therefore a requirement that this header is passed. The advantage here is there's a separation of concern - the part of the SPA managing the users screen doesn't need to know which repo it's working with.
Are there any best practise guidelines for parameters that are commonly used in an API? Where's the distinction over when parameters should be passed FromUri and FromBody over using custom header values?
It depends on the situation but if you have made APIs in which every time you need to pass certain parameter then better you send this parameter in header. HTTP header meant to send extra information about request context, but be aware of adding too much header key-value.
Through header and querystring (through URL) you can only send data in key-value pair whereas through HTTP body you can send different types of payload (data) i.e. JSON, XML, txt, FileStream etc.
There are certain limitations on the data size based on which methods choose to send data. Through header you can pass data up to 8KB size for each key-value pair, in querystring you can add up to 2048 chars and through body we can send as much as 0 to >= 2 MB of data (Size may vary from server to server).
For more detail please refer RFC 7231
Its depends of use cases
If you need to share links between users you will definitely need to use path
It is also looks more transparent and understandable
I believe you need to use headers if you want to hide information for the end user
If you are trying to achieve some kind of multi tenancy here I can also propose use different sub domains for each repository and then add midleware/filter/etc to resolve repository based on request subdomain. You can automate subdomain creation (most of popular providers have API to do this)
This question already has answers here:
C# - How to make a HTTP call
(3 answers)
Closed 7 years ago.
i want to get the data from elastic search using NEST but we are unable to write more consistent queries using nest.
so i want to write a url and get the json data from the CURL command and use it building my UI.
SO how can i do this using c#?
While it is a duplicate I wouldn't call out to another program just to hit a url.
Just use WebClient or WebRequest (difference)
curl is a linux tool to transfer data from & to servers through URLs.
elastic search is a full-text search engine with a RESTful web interface.
nest is a library that abstracts the REST api for you, if you say the abstractions do not fit your needs, you don't need to fall back to another command line program to query a REST server... if you're in a programming language that can do this easily and a lot more!
You can query REST server using C# just fine. This is the API spec:
https://github.com/elastic/elasticsearch/tree/master/rest-api-spec
You can write your own REST webclient:
Create a URL request and then submit the request using HTTP GET or
POST protocol . When the response data is returned, you must serialize
the data against a set of data contracts. As REST Services add new
functionality, these data contracts may need to be updated. A benefit of
working with JSON serialization rather than XML serialization is that
changes in the schema rarely cause issues for existing applications.
For instance, if a new property is added to the REST Services, an application that uses the old data contracts can still process a response without errors; however, the new property will not be available. To get the new property, you must update the data contracts. In order to make use of JSON serialization in .NET, use the DataContractJsonSerializer by referencing the following libraries in your project:
System.Runtime.Serialization
System.ServiceModel.Web
Source:
https://msdn.microsoft.com/en-GB/library/jj819168.aspx
Since ASP.Net 2012.2 was released I have been attempting to create a Web API which returns OData which in turn can be consumed by PowerPivot. I have this working with a predefined model.
However I have a scenario whereby I will not know the number of properties prior to the request being made. What I would like to do is be able to execute a stored procedure to get a DataTable and be able to return the contents of this DataTable as odata.
My initial attempts with returning an IQueryable<DataRow> ended up with the following response.
Response, Status=406 (NotAcceptable), Method=GET, Url=http://localhost:43438/odata/Products, Message='Content-type='none', content-length=unknown'
I have since attempted to use ExpandoObject to create a dynamic object to represent the contents of the DataTable however this also gives the response above.
Is there a feasible way to use a dynamic number of properties and serialize this to OData?
You should build an EDM model and add an OData route. Refer to this blog post for the 3 steps to do to expose odata services.
I was thinking ,
The WebApi along with routing mechanism works in such way that it reads the http verb ( GET POST etc...) and then searches for matched method names / parameters :
For example :
If it's GET and the URI is api/Customers/5:
method should start with Get
if it has ID so search a method which accepts int as parameter.
etc. (there are more rules).
I mostly believe they did it using reflection.
Question :
Isn't it a performance hit , for every URI request - to search all this data just to attach a method ?
Where I could easily send a very short string from a client which will imply on the method on the server side ?
Why not doing it the simple way ? Ok cause we want to use http verbs as meaning. OK. but so much operations just to execute a method
example #1
get api/Customers/5
could be
a.ashx?m=gc&id=5 (method=GetCustomer & id=5)
example #2
put api/Customers/5?v=123
could be
a.ashx?m=uc&id=5?v=123' (method=UpdateCustomer & id=5 & value=123)
mine is even shorter.
Dont get me wrong. I believe this api was done by very smart people who knew what they talk about.
Just want o know what am I missing.
Web api has a lot of options that you don't have with HTTP Handler if you don't code it
Full list: http://www.asp.net/whitepapers/mvc4-release-notes#_Toc317096197
OData support (via Queryable attribute)
Content Negotiation
Filters
Model binding and validation
Ability to self host outside of IIS
Link generation to related resources that incorporates routing rules
Full support for routes/routing
Ability to create custom help and test pages using IApiExplorer
Performance comparison HttpHandler vs WebAPI: http://www.west-wind.com/weblog/posts/2012/Sep/04/ASPNET-Frameworks-and-Raw-Throughput-Performance
As always, you need to choose the the technology that suits you best, if you want performance go with Http Handler. If you want flexibility and rest go with Web API. You might want rest if you expose web services that other will consume