Nav: [Workbook](../workbook.md) | [Basic Concepts] (/workbook/basics/basics.md) | [Handling Requests: Header Fields](/workbook/handling_request/headers.md)
#Handling Requests: Form/Query Data
##### Table of Contents
- [Reading Form Data](#read)
- [Query Parameters](#query)
- [Form Parameters](#form)
- [Uniform Read](#uniform)
- [Reading Parameters and Values](#reading_pv)
- [How to read all parameters names](#all_names)
- [How to read single values](#single_values)
- [How to read multiple values](#multiple_values)
- [How to read table values](#table_values)
- [Reading raw data](#raw_data)
- [Upload Files](#upload)
- [Examples](#examples)
An HTML Form can handle GET and POST requests.
When we use a form with method GET, the data is attached at the end of the url for example:
>http://wwww.example.com?key1=value1&...keyn=valuen
If we use the method POST, the data is sent to the server in a different line.
Extracting form data from the server side is one of the most tedious parts. If you do it by hand, you will need
to parse the input, you'll have to URL-decode the value.
Here we will show you how to read input submitted by a user using a Form (GET and POST).
* How to handle missing values:
* client side validattion, server side validations, set default if it's a valid option.
* How to populate Eiffel objects from the request data.
## Reading Form Data
EWF [WSF_REQUEST]() class, provides features to handling this form parsing automatically.
### Query Parameters
WSF_REQUEST.query_parameters: ITERABLE [WSF_VALUE]
-- All query parameters
WSF_REQUEST.query_parameter (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
-- Query parameter for name `a_name'.
### Form Parameters
WSF_REQUEST.form_parameters: ITERABLE [WSF_VALUE]
-- All form parameters sent by a POST
WSF_REQUEST.form_parameter (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
-- Field for name `a_name'.
The values supplied to form_parameter and query_parameter are case sensitive.
### Read Data
The previous features, let you read the data one way for GET request and a different way for POST request. WSF_REQUEST provide a feature to read all the data in a uniform way.
WSF_REQUEST.item (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
-- Variable named `a_name' from any of the variables container
-- and following a specific order: form_, query_ and path_ parameters
So, you use **WSF_REQUEST.item** feature exactly the same way for GET and POST request.
>Note: if a query parameter has the same name as a form paramenter req.item will retrieve the form paramenter. Remember the precedence: form > query > path
## Reading Parameters and Values
Suppose we have the following HTML5 form using Method POST. This HTML5 form has client side form validation using the new HTML5 attribute, you can do the same using Javascript. So in this case if the user does not fill the fields as expected the form will not be submitted to the server.
>Note: You want to validate on the server side because you can protect against the malicious user, who can easily bypass your JavaScript and submit dangerous input to the server.
```
EWF Handling Client Request: Form example
```
### How to read all parameter names
To read all the parameters names we simple call WSF_REQUEST.form_parameters.
```
req: WSF_REQUEST
across req.form_parameters as ic loop show_parameter_name (ic.item.key) end
```
### How to read single values
To read a particular parameter, a single value, for example `given-name', we simple call WSF_REQUEST.form_parameter (a_name) and we check if it's attached to WSF_STRING (represents a String parameter)
```
req: WSF_REQUEST
if attached {WSF_STRING} req.form_paramenter ('given-name') as l_given_name then
-- Work with the given parameter, for example populate an USER object
-- the argument is case sensitive
else
-- Value missing, check the name against the HTML form
end
```
### How to read multiple values
To read multiple values, for example in the case of `languages', we simple call WSF_REQUEST.form_parameter (a_name) and we check if it's attached to WSF_MULTIPLE_STRING (represents a String parameter)
```
req: WSF_REQUEST
idioms: LIST[STRING]
-- the argument is case sensitive
if attached {WSF_MULTIPLE_STRING} req.form_paramenter ('languages') as l_languages then
-- Work with the given parameter, for example populate an USER object
-- Get all the associated values
create {ARRAYED_LIST[STRING]} idioms.make (2)
across l_languages as ic loop idioms.force (ic.item.value) end
elseif attached {WSF_STRING} req.form_paramenter ('languages') as l_language then
-- Value missing, check the name against the HTML form
create {ARRAYED_LIST[STRING]} idioms.make (1)
idioms.force (l_language.value)
else
-- Value missing
end
```
In this case we are handling strings values, but in some cases you will need to do a conversion, betweend the strings that came from the request to map them to your domain model.
### How to read table values
This is particularly useful when you have a request with the following format
``` ```
To read table values, for example in the case of `tab', we simple call WSF_REQUEST.form_parameter (a_name) and we check if it's attached to WSF_TABLE.
```
if attached {WSF_TABLE} req.query_parameter ("tab") as l_tab then
l_parameter_names.append ("
")
l_parameter_names.append (l_tab.name)
from
l_tab.values.start
until
l_tab.values.after
loop
l_parameter_names.append ("
")
l_parameter_names.append (l_tab.values.key_for_iteration)
if attached {WSF_STRING} l_tab.value (l_tab.values.key_for_iteration) as l_value then
l_parameter_names.append ("=")
l_parameter_names.append (l_value.value)
end
l_tab.values.forth
end
end
```
## Reading Raw Data
You can also access the data in raw format, it means you will need to parse and url-decode it, and also you will not be able to use the previous features, by default, to enable that you need to call `req.set_raw_input_data_recorded (True)'. This feature (reading raw data) is useful if you are reading POST data with JSON or XML formats, but it's not convinient for HTML forms.
To read raw data you need to do this
```
l_raw_data:STRING
req.set_raw_input_data_recorded (True) --
create l_raw_data.make_empty
req.read_input_data_into (l_raw_data)
```
> given-name=testr&family-name=test&dob=1976-08-26&email=test%40gmail.com&url=http%3A%2F%2Fwww.eiffelroom.com&phone=455555555555&languages=Spanish&languages=English
## Upload Files
How can we read data when the date come from an uploaded file/s?.
HTML supports a form element ``` ``` to upload a single file and ``` ``` to upload multiple files.
So supose we have the following form
```