Can I create a web api web service which accepts user input? - c#

Let's assume we have a RESTful web service that will calculate UK Royal Mail postage charges.
There would be a number of essential input parameters:
weight of item (grams, int),
length of item (cm, int),
width of item (cm, int),
category of item (letter/parcel, string/enum),
service required (first class/second class/special delivery/etc, string/enum),
destination (domestic/international/maybe further specify the latter, string/enum)
Such an application would be easy to create as a WebAPI. It could be called via a URL such as ...
http://myserver.com/api/mailcharges?weight=150&length=15&width=10&category=letter&service=first&destination=domestic
The web service would then do a simple lookup on its internal tables and return the postage in its response payload.
The beauty of this is that it could then be utilised by a variety of applications within an organisation (or even outside it!). However, this requires that each application that calls the web service needs to be able to populate these parameters; the integers are OK, they are just that - numbers. But the strings or enums are more difficult. The logic for entering and validating these needs to be replicated in every client application. Wouldn't it be nicer if the web service could prompt the user for any which are not passed in or passed as nulls or invalid values. In fact wouldn't it be nicer still if the web service had a user interface which allowed a user to enter any or all of the parameters.
What I am looking for is a cross between a web site and a web service. A web application which can be called via a simple RESTful http request, which pops up a user dialogue, accepts user input, and when the user clicks on a suitable button, does its calculation and returns its answers as a JSON/XML response.
Does anyone have any ideas on how to implement such an architecture? I have tried calling MVC actions/views from within a web api controller but the response is the html for the MVC view, and is returned to the api controller directly rather than being rendered and POSTing back its user input.
I hope I am just being thick, and that the answer is obvious, but all my experiments have so far failed, and any suggestions, no matter how far fetched or outrageous, would be very welcome.
I realize that this is a fairly trivial example, but the same argument goes for much more complicated web services where the replication of user input forms, input validation, complex processing logic etc. across multiple client applications would be far more of an issue than with this example.

if the web service could prompt the user is essentially missing the point of a service. It is no longer a webservice, but a webpage.
In order for internal/external applications/websites to utilize your service, they essentially need to know three things:
where to ask - this is your http://myserver.com/api/mailcharges
what are the arguments - that is weight, length…
what are accepted argument values
While 1. and 2. are usually mere API documentation you seem to have a problem with p. 3 - you want the user to be somehow prompted to choose among possible values and not guess. But you also want the user application not to be responsible for maintaining/validating the list of possible values.
Guess what? You simply need another API. :) An API to describe your arguments.
Let's concentrate on category field. Your API could be extended with a new URL: http://myserver.com/api/getCategories which essentially returns a list of available (currently understood by API) possible category values. This can be JSON, or comma separated string or whatever reliable. Now your end-user GUI-enabled application calls the API, asks for categories, and creates UI accordingly - populating ComboBox or whatever with obtained values. The same is done for other fields. You can. i.e. obtain acceptable ranges of weight or length.
The important thing you mention in your question is validation: logic for entering and validating these needs to be replicated in every client application. This is somehow true, as it essentially depends on the technology used in the end-user application. On the other hand it is very important, that the API performs validation itself! You can never know who is going to use your API. And it is always better to check twice then never.

Related

Which is the best way (WCF or WEB API) to send data(complex data/primitive data) to a service and get the response(complex data/primitive data)

I have one scenario, Let Say A is a Web based Application and needs to show some data on screen based on data returned from component B.
Now A send some data(which is going to be input parameter for a component B) on an event to B , and component B is going to do calculation on input parameter and return data to A.
Both A and B are handled by different organization, So what is the best way to communicate between them, is WCF or WEB API(also suggest how can we implement this scenario)?
I am thinking of creating Web API for component B here , so that A can consume that and call component B,and Transfer data in JSON format.
But the issue in this approach is that, this request is going to be GET Request, and we can't send complex types on GET request. Even if we are communicating through JSON format, how can we send huge data in GET request.Please correct me if mine understanding is wrong.
No of Input Parameter is ranging between 10 to 20 and number of request made to Component B is very much frequent, So we have to take care of performance as well.
Updatde 1: First Issue is we can't send data in Request Body for GET.
Generally the question is WCF for complexity and security vs WebApi for simplicity and speed. If WCF features are not required, I will go for WebApi. If you need to send complex data with request, you can use POST.
It is perfectly correct to request data using POST, there are only small limitations.
Look here: https://www.w3schools.com/jquery/jquery_ajax_get_post.asp

Commonly used Web API parameters - route vs header?

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)

Web api performance?

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

accessing websites using C#

I have a problem here. Assume there's a basic calculator implemented in javascript hosted on a website ( I have googled it and to find an example and found this one: http://www.unitsconverter.net/calculator/ ). What I want to do is make a program that opens this website, enters some value and gets the return value. So, in our website calculator, the program:
- open the website
- enters an operand
- enters an operation
- enters an operand
- retrieve the result
Note: things should be done without the need to show anything to the user ( the browser for example ).
I did some search and found about HttpWebRequest and HttpWebRespond. But I think those can be used to post data to the server, which means, The file I'm sending data to must be php, aspx or jsp. But Javascript is client side. So, I think they are kind of useless to me in this case.
Any help?
Update:
I have managed to develop the web bot using WebBrowser Control tool ( found in System.Windows.Forms )
Here's a sample of the code:
webBrowser1.Navigate("LinkOfTheSiteYouWant"); // this will load the page specified in the string. You can add webBrowser1.ScriptErrorsSuppressed = true; to disable the script in a page
webBrowser1.Document.GetElementById("ElementId").SetAttribute("HTMLattrbute", "valueToBeSet");
Those are the main methods I have used to do what I wanted to.
I have found this video useful: http://www.youtube.com/watch?v=5P2KvFN_aLY
I guess you could use something like WatiN to pipe the user's input/output from your app to the website and return the results, but as another commenter pointed out, the value of this sort of thing when you could just write your own calculator fairly escapes me.
You'll need a JavaScript interpreter (engine) to parse all the JavaScript code on the page.
https://www.google.com/search?q=c%23+javascript+engine
What you're looking for is something more akin to a web service. The page you provided doesn't seem like it accepts any data in an HTTP POST and doesn't have any meaningful information in the source that you could scrape. If for example you wanted to programmatically make searches for eBay auctions, you could figure out how to correctly post data to it eg:
http://www.ebay.com/sch/i.html?_nkw=http+for+dummies&_sacat=267&_odkw=http+for+dummies&_osacat=0
and then look through the http response for the information you're looking for. You'd probably need to create a regular expression to match the markup you're looking for like if you wanted to know how many results, you'd search the http response for this bit of markup:
<div class="alt w"><div class="cnt">Your search returned <b>0 items.</b></div></div>
As far as clientside/javascript stuff, you just plain aren't going to be able to do anything like what you're going for.
It is a matter of API: "Does the remote website expose any API for the required functionality?".
Well web resources that expose interactive API are called web service. There are tons of examples (Google Maps for istance).
You can access the API -depending on the Terms & Conditions of the service- through a client. The nature of the client depends on the kind of web service you are accessing.
A SOAP based service is based on SOAP protocol.
A REST based service is based on REST principles.
So, if there is an accessible web service called "Calculator", then you can access the service and, for istance, invoke the sum method.
In your example, the calculator is a Javascript implementation, so it is not a web service and it cannot be accessed via HTTP requests. Though, its implementation is still accessible: it is the javascript file where the calculator is implemented. You can always include the file in your website and access its functions via javascript (always mind terms and conditions!!).
A very common example is the jQuery library stored in Google Libraries.

Global variables in WCF REST services

My applciation works as follows
[user]----username/password/domain----->[WCF service]
then i access the domain server to see to which actual DB the user is associated,
after getting that, i validate the user in his actual DB(DB is per domain)
the problem is that i need a place to store the domain name for the following requests against the db.
for example,if the users calls a WCF service operation:
Test()
first the validation procedure is called, (WCF UserNamePasswordValidator) which validates the user password(which is sent as part of the header for REST or as part of the SOAP), and the next function to be called is the Test, but by then i cant tell the domain of the user(to actually serve the request agains that domain..)
I dont want to change the signature of each domain to
Test(string domain)
I cant simply access the headers since i expose the same methods both as REST and as SOAP and the authentication is different for each of them..(one is with headers as with Amazon S3 and the later is using the SOAP standard)
so basically i'm looking for a global, per call storage.(i want to avoid the Per-Call initiation method)
thanks.
EDIT:
Maybe i should use the ThreadStaticAttribute? will that work?
This will not work. You can't store anything in UserNamePasswordValidator. It even doesn't have access to OperationContext because it runs on different thread.
The way to do this is create custom message inspector and extract the information from custom message header to custom operation context extension as Frank mentioned.
WCF knows a Current OperationContext. You can write your own extensions for it. Unrelated to this issue, I used the same mechanics in this NHibernate Session management here, which may work in its concept for you as well. It accesses the InstanceContext, but the concepts are similar.

Categories

Resources