Get запрос windows api


 by Alex Stylianos

In a recent article we showed how HTTP requests are formed in low level. We demonstrated how to create a simple HTTP GET request, a URL encoded POST request, and an upload request (multipart POST HTTP request).

This article has working examples on how to create those HTTP requests programmatically using C# for MS Windows.

The next sections of this article include the code that does the job, and then a couple of examples that demonstrate ways to create different types of HTTP requests.

The code

Create a new class (Menu: Project > Add Class..) with any name and copy/paste the following code. The file name in our example is HttpRequestWorker.cs . Adjust the namespace to match the one used by your project.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Net;
using System.IO;

namespace LowLevelHttpRequest {

    enum HttpRequestVarLayout {NOT_SET, ADDRESS, URL_ENCODED, MULTIPART};

    class HttpRequestInputFileElement {

        public String variable_name;
        public String local_filename;
        public String request_filename;
        public String mime_type;

    }

    class HttpRequestInput {

        public String url_str;
        public String http_method;
        public HttpRequestVarLayout var_layout = HttpRequestVarLayout.NOT_SET;
        public Dictionary<String, String> vars;
        public List<HttpRequestInputFileElement> files;

        public HttpRequestInput() {
            initialize();
        }

        public HttpRequestInput(String v_url_str, String v_http_method) {
            initialize();
            url_str = v_url_str;
            http_method = v_http_method;
        }

        private void initialize() {
            url_str = "";
            http_method = "GET";
            vars = new Dictionary<String, String>();
            files = new List<HttpRequestInputFileElement>();
        }

        public void add_var(String key, String value) {
            vars.Add(key, value);
        }

        public void add_file(String variable_name, String local_filename, String request_filename, String mime_type) {
            HttpRequestInputFileElement file = new HttpRequestInputFileElement();
            file.variable_name = variable_name;
            file.local_filename = local_filename;
            file.request_filename = request_filename;
            file.mime_type = mime_type;
            files.Add(file);
        }

    }

    class HttpRequestWorker {

        public StringBuilder response;
        public Exception error;
        public event EventHandler OnCompleted;

        const int BUFFER_SIZE = 4096;
        public byte[] buffer;
        public HttpWebRequest request;
        public Stream stream_response;
        private List<byte[]> request_content;

        public void add_response_content(int length) {
            response.Append(Encoding.ASCII.GetString(buffer, 0, length));
        }

        public void execution_completed() {
            if (stream_response != null) {
                stream_response.Close();
                stream_response = null;
            }
            OnCompleted(this, EventArgs.Empty);
        }

        private StringBuilder urlencode(String input) {
            byte[] input_c = Encoding.UTF8.GetBytes(input);
            StringBuilder result = new StringBuilder();
            for (int i = 0; i < input_c.Length; i++) {
                char c = (char)input_c[i];
                if (
                    (c >= '0' && c <= '9')
                    || (c >= 'A' && c <= 'Z')
                    || (c >= 'a' && c <= 'z')
                    || c == '-' || c == '.' || c == '_' || c == '~'
                ) {
                    result.Append(c);
                }
                else {
                    result.Append('%');
                    result.Append(((int)c).ToString("X2"));
                }
            }

            return result;
        }

        private String http_attribute_encode(String attribute_name, String input) {
            // result structure follows RFC 5987
            bool need_utf_encoding = false;
            StringBuilder result = new StringBuilder();
            byte[] input_c = Encoding.UTF8.GetBytes(input);
            char c;
            for (int i = 0; i < input_c.Length; i++) {
                c = (char)input_c[i];
                if (c == '\\' || c == '/' || c == '\0' || c < ' ' || c > '~') {
                    // ignore and request utf-8 version
                    need_utf_encoding = true;
                }
                else if (c == '"') {
                    result.Append("\\\"");
                }
                else {
                    result.Append(c);
                }
            }

            if (result.Length == 0) {
                need_utf_encoding = true;
            }

            if (!need_utf_encoding) {
                // return simple version
                return String.Format("{0}=\"{1}\"", attribute_name, result);
            }

            StringBuilder result_utf8 = new StringBuilder();
            for (int i = 0; i < input_c.Length; i++) {
                c = (char)input_c[i];
                if (
                    (c >= '0' && c <= '9')
                    || (c >= 'A' && c <= 'Z')
                    || (c >= 'a' && c <= 'z')
                ) {
                    result_utf8.Append(c);
                }
                else {
                    result_utf8.Append('%');
                    result_utf8.Append(((int)c).ToString("X2"));
                }
            }

            // return enhanced version with UTF-8 support
            return String.Format("{0}=\"{1}\"; {0}*=utf-8''{2}", attribute_name, result, result_utf8);
        }

        private void add_request_content(String str) {
            request_content.Add(Encoding.UTF8.GetBytes(str));
        }

        private void add_request_content(StringBuilder str) {
            request_content.Add(Encoding.UTF8.GetBytes(str.ToString()));
        }

        private void add_request_content(char c) {
            request_content.Add(new byte[1] {(byte)c});
        }

        public void execute(HttpRequestInput input) {
            try {
                // reset variables

                response = new StringBuilder();
                error = null;

                buffer = new byte[BUFFER_SIZE];
                stream_response = null;
                request_content = new List<byte[]>();


                // decide on the variable layout

                if (input.files.Count > 0) {
                    input.var_layout = HttpRequestVarLayout.MULTIPART;
                }
                if (input.var_layout == HttpRequestVarLayout.NOT_SET) {
                    input.var_layout = input.http_method.Equals("GET") || input.http_method.Equals("HEAD")
                        ? HttpRequestVarLayout.ADDRESS
                        : HttpRequestVarLayout.URL_ENCODED;
                }


                // prepare request content

                String boundary = "";

                if (input.var_layout == HttpRequestVarLayout.ADDRESS || input.var_layout == HttpRequestVarLayout.URL_ENCODED) {
                    // variable layout is ADDRESS or URL_ENCODED

                    if (input.vars.Count > 0) {
                        bool first = true;
                        foreach (KeyValuePair<string, string> element in input.vars) {
                            if (!first) {
                                add_request_content('&');
                            }
                            first = false;

                            add_request_content(urlencode(element.Key));
                            add_request_content('=');
                            add_request_content(urlencode(element.Value));
                        }

                        if (input.var_layout == HttpRequestVarLayout.ADDRESS) {
                            StringBuilder new_url = new StringBuilder(input.url_str);
                            new_url.Append("?");

                            foreach (byte[] ba in request_content) {
                                new_url.Append(Encoding.UTF8.GetString(ba));
                            }

                            input.url_str = new_url.ToString();
                            request_content.Clear();
                        }
                    }
                }
                else {
                    // variable layout is MULTIPART

                    Random random = new Random();
                    int boundary_random = random.Next();
                    int boundary_timestamp = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;

                    boundary = "__-----------------------" + boundary_random.ToString() + boundary_timestamp.ToString();
                    String boundary_delimiter = "--";
                    String new_line = "\r\n";

                    // add variables
                    foreach (KeyValuePair<string, string> element in input.vars) {
                        // add boundary
                        add_request_content(boundary_delimiter);
                        add_request_content(boundary);
                        add_request_content(new_line);

                        // add header
                        add_request_content("Content-Disposition: form-data; ");
                        add_request_content(http_attribute_encode("name", element.Key));
                        add_request_content(new_line);
                        add_request_content("Content-Type: text/plain");
                        add_request_content(new_line);

                        // add header to body splitter
                        add_request_content(new_line);

                        // add variable content
                        add_request_content(element.Value);
                        add_request_content(new_line);
                    }

                    // add files
                    foreach (HttpRequestInputFileElement file_info in input.files) {
                        FileInfo fi = null;
                        if (file_info.local_filename != null && file_info.local_filename.Length > 0) {
                            fi = new FileInfo(file_info.local_filename);
                        }

                        // ensure necessary variables are available
                        if (
                            file_info.variable_name == null || file_info.variable_name.Length == 0
                            || fi == null || !fi.Exists
                        ) {
                            // silent abort for the current file
                            continue;
                        }

                        FileAttributes attr = File.GetAttributes(file_info.local_filename);
                        if (
                            (attr & FileAttributes.Directory) == FileAttributes.Directory
                            || (attr & FileAttributes.Device) == FileAttributes.Device
                        ) {
                            // silent abort for the current file
                            continue;
                        }

                        // ensure filename for the request
                        if (file_info.request_filename == null || file_info.request_filename.Length == 0) {
                            file_info.request_filename = fi.Name;
                            if (file_info.request_filename.Length == 0) {
                                file_info.request_filename = "file";
                            }
                        }

                        // add boundary
                        add_request_content(boundary_delimiter);
                        add_request_content(boundary);
                        add_request_content(new_line);

                        // add header
                        add_request_content(String.Format("Content-Disposition: form-data; {0}; {1}",
                            http_attribute_encode("name", file_info.variable_name),
                            http_attribute_encode("filename", file_info.request_filename)
                        ));
                        add_request_content(new_line);

                        if (file_info.mime_type != null && file_info.mime_type.Length > 0) {
                            add_request_content("Content-Type: ");
                            add_request_content(file_info.mime_type);
                            add_request_content(new_line);
                        }

                        add_request_content("Content-Transfer-Encoding: binary");
                        add_request_content(new_line);

                        // add header to body splitter
                        add_request_content(new_line);

                        // add file content
                        request_content.Add(File.ReadAllBytes(file_info.local_filename));
                        add_request_content(new_line);
                    }

                    // add end of body
                    add_request_content(boundary_delimiter);
                    add_request_content(boundary);
                    add_request_content(boundary_delimiter);
                }


                // prepare connection

                request = (HttpWebRequest)WebRequest.Create(input.url_str);
                request.Proxy = null;
                request.Method = input.http_method;
                request.UserAgent = "Agent name goes here";

                if (input.var_layout == HttpRequestVarLayout.URL_ENCODED) {
                    request.ContentType = "application/x-www-form-urlencoded";
                }
                else if (input.var_layout == HttpRequestVarLayout.MULTIPART) {
                    request.ContentType = "multipart/form-data; boundary=" + boundary;
                }


                // send request content, if applicable

                if (input.var_layout == HttpRequestVarLayout.URL_ENCODED || input.var_layout == HttpRequestVarLayout.MULTIPART) {
                    Stream request_stream = request.GetRequestStream();
                    BinaryWriter write_stream = new BinaryWriter(request_stream);

                    foreach (byte[] ba in request_content) {
                        write_stream.Write(ba);
                    }

                    write_stream.Flush();
                    write_stream.Close();
                    request_stream.Close();
                }


                // receive response

                request.BeginGetResponse(new AsyncCallback(response_callback), this);
            }
            catch (WebException e) {
                error = e;
                execution_completed();
            }
            catch (Exception e) {
                error = e;
                execution_completed();
            }
        }

        private static void response_callback(IAsyncResult async_result) {
            HttpRequestWorker worker = (HttpRequestWorker)async_result.AsyncState;

            try {
                HttpWebResponse response = (HttpWebResponse)worker.request.EndGetResponse(async_result);
                worker.stream_response = response.GetResponseStream();
                worker.stream_response.BeginRead(worker.buffer, 0, BUFFER_SIZE, new AsyncCallback(read_callback), worker);
            }
            catch (WebException e) {
                worker.error = e;
                worker.execution_completed();
            }
            catch (Exception e) {
                worker.error = e;
                worker.execution_completed();
            }
        }

        private static void read_callback(IAsyncResult async_result) {
            HttpRequestWorker worker = (HttpRequestWorker)async_result.AsyncState;

            try {
                int length = worker.stream_response.EndRead(async_result);
                if (length > 0) {
                    worker.add_response_content(length);
                    worker.stream_response.BeginRead(worker.buffer, 0, BUFFER_SIZE, new AsyncCallback(read_callback), worker);
                }
                else {
                    worker.execution_completed();
                }
            }
            catch (WebException e) {
                worker.error = e;
                worker.execution_completed();
            }
            catch (Exception e) {
                worker.error = e;
                worker.execution_completed();
            }
        }

    }

}

The controller class should contain one or more places that call the worker unit and one handler function. The handler function is required because this example’s code makes asynchronous HTTP calls in order for the main thread to keep being responsive and not freeze.

private void button1_Click(object sender, EventArgs e) {
    // trigger the request
}

private void handle_result(object sender, EventArgs e) {
    HttpRequestWorker worker = (HttpRequestWorker)sender;
    string msg;

    if (worker.error == null) {
        // communication was successful
        msg = "Success - Response: " + worker.response.ToString();
    }
    else if (worker.error is WebException) {
        // WebException exception
        msg = "WebException: " + worker.error.Message;
    }
    else if (worker.error is Exception) {
        // generic exception
        msg = "Exception: " + worker.error.Message;
    }
    else {
        // unknown response - should never happen
        msg = "Error: Unhandled communication response";
    }

    MessageBox.Show(msg);
}

There are a couple of notable things in this code:

  1. The use of asynchronous methods for the communication process.

    The experienced eye will notice the use of

    HttpWebRequest.BeginGetResponse() . HttpWebRequest supports several methods to communicate. We picked one that receives the web response in an asynchronous way. This helps your UI thread to keep being responsive and not freeze while the web server sends the response.

  2. The significance of specialized classes for the HTTP input.

    This code uses the class

    HttpRequestInput as an encapsulation for input variables of the HTTP request.

  3. The role of urlencode()

    This little function was required as C# offers this functionality only for web applications. Our example works as a desktop app and therefore is not supported by native .NET functions for URL encoding.

  4. The role of http_attribute_encode()

    One small detail is the way we must escape attribute values in the HTTP protocol. Being Greek gives us the advantage to have increased appreciation in internationalization/localization issues. When attribute values have non-latin characters things may get out of control. RFC 5987 makes the necessary provisions for not allowing the mess, and this function implements this provision.

  5. Trigger code

    The code we just showed includes the function

    button1_Click(). The next sections of this article will differentiate this function to implement different types of HTTP requests. In any case, this function is supposed to be an event handler of a button click from the UI.

  6. Result handling

    This code uses the

    handle_result() function to handle the communication result. You may notice that the result can be a number of different classes. For your convenience the one that signals success is on the top. The rest of possible cases handle different types of errors.

  7. Little things you need to adjust in your implementation:

    As previously stated, you need to adjust the namespace of the worker unit (

    LowLevelHttpRequest in this example) to match the one used by your project.

    This code sets the HTTP header for the name of the HTTP client/agent. You need to change «Agent name goes here» with the name of your client.

    You obviously need to set the right code for triggering the code in

    button1_Click() . Read the next sections for more examples on this function.

    Naturally, you should customize

    handle_result() . Our code is just an example of the different things you can do when the communication is completed.

Simple HTTP GET requests

Lets see how to run a simple GET request.

private void button1_Click(object sender, EventArgs e) {
    String url_str = "http://www.example.com/path/to/page.php";

    HttpRequestInput input = new HttpRequestInput(url_str, "GET");

    HttpRequestWorker worker = new HttpRequestWorker();
    worker.OnCompleted += handle_result;
    worker.execute(input);
}

This will produce the following HTTP request:

GET /path/to/page.php HTTP/1.1
User-Agent: Agent name goes here
Host: www.example.com
Connection: Keep-Alive

The previous example calls a plain URL. Lets add a few variables.

private void button1_Click(object sender, EventArgs e) {
    String url_str = "http://www.example.com/path/to/page.php";

    HttpRequestInput input = new HttpRequestInput(url_str, "GET");

    input.add_var("key1", "value1");
    input.add_var("key2", "value2");

    HttpRequestWorker worker = new HttpRequestWorker();
    worker.OnCompleted += handle_result;
    worker.execute(input);
}

This will produce the following HTTP request:

GET /path/to/page.php?key1=value1&key2=value2 HTTP/1.1
User-Agent: Agent name goes here
Host: www.example.com
Connection: Keep-Alive

URL encoded HTTP POST requests

We can make a slight adjustment and turn the GET request to a URL encoded POST request.

private void button1_Click(object sender, EventArgs e) {
    String url_str = "http://www.example.com/path/to/page.php";

    HttpRequestInput input = new HttpRequestInput(url_str, "POST");

    input.add_var("key1", "value1");
    input.add_var("key2", "value2");

    HttpRequestWorker worker = new HttpRequestWorker();
    worker.OnCompleted += handle_result;
    worker.execute(input);
}

This will produce the following HTTP request:

POST /path/to/page.php HTTP/1.1
User-Agent: Agent name goes here
Content-Type: application/x-www-form-urlencoded
Host: www.example.com
Content-Length: 23
Expect: 100-continue
Connection: Keep-Alive

key1=value1&key2=value2

Multipart HTTP POST requests

Finally, lets push it to the limits. Lets upload some files using a multipart POST request.

private void button1_Click(object sender, EventArgs e) {
    String url_str = "http://www.example.com/path/to/page.php";

    HttpRequestInput input = new HttpRequestInput(url_str, "POST");

    input.add_var("key1", "value1");
    input.add_var("key2", "value2");

    input.add_file("file1", @"C:\path\to\file1.png", null, "image/png");
    input.add_file("file2", @"C:\path\to\file2.png", null, "image/png");

    HttpRequestWorker worker = new HttpRequestWorker();
    worker.OnCompleted += handle_result;
    worker.execute(input);
}

This will produce the following HTTP request:

POST /path/to/page.php HTTP/1.1
User-Agent: Agent name goes here
Content-Type: multipart/form-data; boundary=__-----------------------9446182961397930864818
Host: www.example.com
Content-Length: 686
Expect: 100-continue
Connection: Keep-Alive

--__-----------------------9446182961397930864818
Content-Disposition: form-data; name="key2"
Content-Type: text/plain

value2
--__-----------------------9446182961397930864818
Content-Disposition: form-data; name="key1"
Content-Type: text/plain

value1
--__-----------------------9446182961397930864818
Content-Disposition: form-data; name="file1"; filename="file1.png"
Content-Type: image/png
Content-Transfer-Encoding: binary

[... contents of C:\path\to\file1.png ...]
--__-----------------------9446182961397930864818
Content-Disposition: form-data; name="file2"; filename="file2.png"
Content-Type: image/png
Content-Transfer-Encoding: binary

[... contents of C:\path\to\file2.png ...]
--__-----------------------9446182961397930864818--

Provide feedback

Saved searches

Use saved searches to filter your results more quickly

Sign up

Appearance settings

The .NET 2.0 included WebClient class to communicate with web server using HTTP protocol. However, WebClient class had some limitations. The .NET 4.5 includes HttpClient class to overcome the limitation of WebClient. Here, we will use HttpClient class in console application to send data to and receive data from Web API which is hosted on local IIS web server. You may use HttpClient in other .NET applications also such as MVC Web Application, windows form application, windows service application etc.

Let’s see how to consume Web API using HttpClient in the console application.

We will consume the following Web API created in the previous section.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace MyWebAPI.Controller
{
    public class StudentController : ApiController
    {
        public IHttpActionResult GetAllStudents(bool includeAddress = false)
        {
            IList<StudentViewModel> students = null;

            using (var ctx = new SchoolDBEntities())
            {
                students = ctx.Students.Include("StudentAddress").Select(s =&gt; new StudentViewModel()
                {
                    Id = s.StudentID,
                    FirstName = s.FirstName,
                    LastName = s.LastName,
                    Address = s.StudentAddress == null || includeAddress == false ? null : new AddressViewModel()
                    {
                        StudentId = s.StudentAddress.StudentID,
                        Address1 = s.StudentAddress.Address1,
                        Address2 = s.StudentAddress.Address2,
                        City = s.StudentAddress.City,
                        State = s.StudentAddress.State
                    }
                }).ToList<StudentViewModel>();
            }

            if (students.Count == 0)
            {
                return NotFound();
            }

            return Ok(students);
        }

        public IHttpActionResult PostNewStudent(StudentViewModel student)
        {
            if (!ModelState.IsValid)
                return BadRequest("Not a valid data");

            using (var ctx = new SchoolDBEntities())
            {
                ctx.Students.Add(new Student()
                {
                    StudentID = student.Id,
                    FirstName = student.FirstName,
                    LastName = student.LastName
                });

                ctx.SaveChanges();
            }
            return Ok();
        }

        public IHttpActionResult Put(StudentViewModel student)
        {
            if (!ModelState.IsValid)
                return BadRequest("Not a valid data");

            using (var ctx = new SchoolDBEntities())
            {
                var existingStudent = ctx.Students.Where(s =&gt; s.StudentID == student.Id).FirstOrDefault<Student>();

                if (existingStudent != null)
                {
                    existingStudent.FirstName = student.FirstName;
                    existingStudent.LastName = student.LastName;

                    ctx.SaveChanges();
                }
                else
                {
                    return NotFound();
                }
            }
            return Ok();
        }


        public IHttpActionResult Delete(int id)
        {
            if (id <= 0)
                return BadRequest("Not a valid studet id");

            using (var ctx = new SchoolDBEntities())
            {
                var student = ctx.Students
                    .Where(s => s.StudentID == id)
                    .FirstOrDefault();

                ctx.Entry(student).State = System.Data.Entity.EntityState.Deleted;
                ctx.SaveChanges();
            }
            return Ok();
        }
    }
}

Step 1:

First, create a console application in Visual Studio 2013 for Desktop.

Step 2:

Open NuGet Package Manager console from TOOLS -> NuGet Package Manager -> Package Manager Console and execute following command.

Install-Package Microsoft.AspNet.WebApi.Client

Step 3:

Now, create a Student model class because we will send and receive Student object to our Web API.

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Send GET Request

The following example sends an HTTP GET request to Student Web API and displays the result in the console.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net.Http.Headers;

namespace HttpClientDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri("http://localhost:60464/api/");
                //HTTP GET
                var responseTask = client.GetAsync("student");
                responseTask.Wait();

                var result = responseTask.Result;
                if (result.IsSuccessStatusCode)
                {

                    var readTask = result.Content.ReadAsAsync<Student[]>();
                    readTask.Wait();

                    var students = readTask.Result;

                    foreach (var student in students)
                    {
                        Console.WriteLine(student.Name);
                    }
                }
            }
            Console.ReadLine();
        }        
    }
}

Let’s understand the above example step by step.

First, we have created an object of HttpClient and assigned the base address of our Web API. The GetAsync() method sends an http GET request to the specified url. The GetAsync() method is asynchronous and returns a Task. Task.wait() suspends the execution until GetAsync() method completes the execution and returns a result.

Once the execution completes, we get the result from Task using Task.result which is HttpResponseMessage. Now, you can check the status of an http response using IsSuccessStatusCode. Read the content of the result using ReadAsAsync() method.

Thus, you can send http GET request using HttpClient object and process the result.

Send POST Request

Similarly, you can send HTTP POST request using PostAsAsync() method of HttpClient and process the result the same way as GET request.

The following example send http POST request to our Web API. It posts Student object as json and gets the response.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net.Http.Headers;

namespace HttpClientDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            var student = new Student() { Name = "Steve" };

            var postTask = client.PostAsJsonAsync<Student>("student", student);
            postTask.Wait();

            var result = postTask.Result;
            if (result.IsSuccessStatusCode)
            {

                var readTask = result.Content.ReadAsAsync<Student>();
                readTask.Wait();

                var insertedStudent = readTask.Result;

                Console.WriteLine("Student {0} inserted with id: {1}", insertedStudent.Name, insertedStudent.Id);
            }
            else
            {
                Console.WriteLine(result.StatusCode);
            }
        }
    }
}

The following table lists all the methods of HttpClient to send different HTTP requests.

Method Name Description
GetAsync Sends a GET request to the specified Uri as an asynchronous operation.
GetByteArrayAsync Sends a GET request to the specified Uri and returns the response body as a byte array in an asynchronous operation.
GetStreamAsync Sends a GET request to the specified Uri and returns the response body as a stream in an asynchronous operation.
GetStringAsync Sends a GET request to the specified Uri and returns the response body as a string in an asynchronous operation.
PostAsync Sends a POST request to the specified Uri as an asynchronous operation.
PostAsJsonAsync Sends a POST request as an asynchronous operation to the specified Uri with the given value serialized as JSON.
PostAsXmlAsync Sends a POST request as an asynchronous operation to the specified Uri with the given value serialized as XML.
PutAsync Sends a PUT request to the specified Uri as an asynchronous operation.
PutAsJsonAsync Sends a PUT request as an asynchronous operation to the specified Uri with the given value serialized as JSON.
PutAsXmlAsync Sends a PUT request as an asynchronous operation to the specified Uri with the given value serialized as XML.
DeleteAsync Sends a DELETE request to the specified Uri as an asynchronous operation.

Visit MSDN to know all the members of HttpClient and HttpClientExtension.

Back to: ASP.NET Web API Tutorials For Beginners and Professionals

How to Implement the GET Method in Web API Application

In this article, I am going to discuss how to Implement GET Method in Web API Application with an example. Please read our previous article where we discussed Media Type Formatter in Web API with examples. As part of this article, we are going to discuss the following pointers.

  1. Understanding CRUD Operations.
  2. Understanding Request Verbs, Request Header, Request Body, Response Body, and Response Status Codes in Web API.
  3. Create the database schema in SQL Server with testing data.
  4. Using Entity Framework to interact with the database.
  5. How to Implement the GET method in ASP.NET Web API?
  6. Testing the Web API Get Method using Fiddler.
Understanding CRUD Operations.

In general, when we talk about a database table, there are four operations (known as CRUD Operations) that we perform on it. They are as follows

  1. C- Create a Row,
  2. R- Read a Row,
  3. U- Update a Row, and
  4. D- Delete a Row

From the context of an ASP.NET Web API resource, the above four actions (Read, Create, Update and Delete) are corresponded to GET, POST, PUT and DELETE methods respectively. Let us understand some concepts which are required to understand the HTTP verbs.

Request Verbs (GET, POST, AND DELETE)

These describe what should be done with the resource.

Request Header

When a client sends a request to the server, the request contains a header and a body. The request method contains additional information, such as – what type of response is required. For example, The response should be in XML, JSON, or some other format.

Request Body

The request body contains the data that we want to send to the server. For example, a post request contains the data for a new item that we want to create. The data format may be in XML or in JSON

Response Body

The response body contains the data of the response from the server. For example, if the request is for a specific employee, the response body includes employee details in XML, JSON, and so on.

Response Status Codes

The Response Status codes are nothing but the HTTP status codes which specifically gives the status of the response to the client. Some of the common status codes are 404 not found, 200 OK, 204 No content, 500 Internal Server Error and so on.

Use the below SQL Script to create and populate the necessary database table with some test data. The below script
  1. Create a database called WEBAPI_DB
  2. Creates the Employees table and populate it with some test data
CREATE DATABASE WEBAPI_DB
GO

USE WEBAPI_DB
GO

CREATE TABLE Employees
(
     ID int primary key identity,
     FirstName nvarchar(50),
     LastName nvarchar(50),
     Gender nvarchar(50),
     Salary int
)
GO

INSERT INTO Employees VALUES ('Pranaya', 'Rout', 'Male', 60000)
INSERT INTO Employees VALUES ('Anurag', 'Mohanty', 'Male', 45000)
INSERT INTO Employees VALUES ('Preety', 'Tiwari', 'Female', 45000)
INSERT INTO Employees VALUES ('Sambit', 'Mohanty', 'Male', 70000)
INSERT INTO Employees VALUES ('Shushanta', 'Jena', 'Male', 45000)
INSERT INTO Employees VALUES ('Priyanka', 'Dewangan', 'Female', 30000)
INSERT INTO Employees VALUES ('Sandeep', 'Kiran', 'Male', 45000)
INSERT INTO Employees VALUES('Shudhansshu', 'Nayak', 'Male', 30000)
INSERT INTO Employees VALUES ('Hina', 'Sharma', 'Female', 35000)
INSERT INTO Employees VALUES ('Preetiranjan', 'Sahoo', 'Male', 80000)
GO

Fetch the records: SELECT * FROM Employees Will give the following result

Creating a new ASP.NET Web API Project

Open Visual Studio and select File – New – Project as shown below

implementing the GET Method in WEB API

From the “New Project” window, from the left pane select the “Visual C#” which is under the “Installed – Templates” section. Similarly, from the middle pane select ASP.NET Web Application and then provide the name of the project as “EmployeeService“. Finally, click on the “OK” button as shown in the image below.

implementing the GET Method in WEB API

Once we click on the OK button a new dialog will pop up with Name “New ASP.NET Project” for selecting project Templates.

implementing the GET Method in WEB API

In this dialog, we are going to choose the Web API project template and click on the OK button. At this point, you should have the Web API project created.

Adding ADO.NET Entity Data Model to retrieve data from the database

Right-click on the Models folder and then select Add – New Item option which will open the Add New Item window and from the “Add New Item” window select the “Data” option from the left pane and from the middle pane select ADO.NET Entity Data Model. In the Name text box, type EmployeeDataModel and finally click the Add button as shown in the below image.

implementing the GET Method in WEB API

Once you click on the Add button, it will open the Entity Data Model Wizard and from that wizard select “EF Designer from database” option and click on the “Next” button as shown below.

implementing the GET Method in WEB API

On the next screen, click on the “New Connection” button as shown in the image below

implementing the GET Method in WEB API

Once you click on the New Connection Button it will open the Connection Properties window. On “Connection Properties” window, set

  1. Server Name = provide the server name
  2. Authentication = Select the authentication type
  3. Select or enter a database name = WEBAPI_DB
  4. Click the OK button as shown below.

implementing the GET Method in WEB API

Once you click on the OK button it will navigate back to the Choose Your Data Connection wizard. Here Modify the Connection String as EmployeeDBContext and click on the Next Button as shown in the below image.

implementing the GET Method in WEB API

On the next screen, select Entity Framework 6.x as shown in the below image. This step may be optional if you are using a higher version of visual studio.

implementing the GET Method in WEB API

On Choose Your Database Objects and Settings screen, select the “Employees” table, provide the model namespace name and click on Finish button as shown below. 

implementing the GET Method in WEB API

Once you click on the Finish Button the following edmx file will be generated within the Models folder as shown below.

Adding Web API Controller

Right-click on the Controllers folder and select Add – Controller option and then select “Web API 2 Controller – Empty” and click on the “Add” button as shown below.

implementing the GET Method in WEB API

On the next screen set, the Controller Name as EmployeesController and click on the Add button as shown in the below image.

implementing the GET Method in WEB API

Implementing the GET method in ASP.NET Web API:

Copy and paste the following code in EmployeesController.cs

public class EmployeesController : ApiController
{
    public IEnumerable<Employee> Get()
    {
        using (EmployeeDBContext dbContext = new EmployeeDBContext())
        {
            return dbContext.Employees.ToList();
        }
    }
    public Employee Get(int id)
    {
        using (EmployeeDBContext dbContext = new EmployeeDBContext())
        {
            return dbContext.Employees.FirstOrDefault(e => e.ID == id);
        }
    }
}

At this point when we navigate to /api/employees we should see all employees and when we navigate to /api/employees/1 we should see all the details of the employee whose Id=1

We have two get methods one without parameter and one with a parameter. Whenever we pass the id parameter then it will return the employee whose id we passed and if we do not pass the id parameter value then it will return all the employees.

Let’s see what will happen when we issue a request for an employee whose id that does not exist with one example.

implementing the GET Method in WEB API

Here we are trying to get the details of an employee whose id does not exist in the database. So when we click on the execute button it will give us the below response.

implementing the GET Method in WEB API

The above image clearly shows that we get null as the response and the status code is 200 OK. According to the standards of REST when an item is not found, then it should return 404 Not Found.

To achieve this, we need to modify the Employees Controller as shown below. 
public class EmployeesController : ApiController
{
    public HttpResponseMessage Get()
    {
        using (EmployeeDBContext dbContext = new EmployeeDBContext())
        {
            var Employees =  dbContext.Employees.ToList();
            return Request.CreateResponse(HttpStatusCode.OK, Employees);
        }
    }
    public HttpResponseMessage Get(int id)
    {
        using (EmployeeDBContext dbContext = new EmployeeDBContext())
        {
            var entity = dbContext.Employees.FirstOrDefault(e => e.ID == id);
            if(entity != null)
            {
                return Request.CreateResponse(HttpStatusCode.OK, entity);
            }
            else
            {
                return Request.CreateErrorResponse(HttpStatusCode.NotFound,
                    "Employee with ID " + id.ToString() + "not found");
            }
        }
    }
}

At this point, when we issue a request for an employee with ID = 15 which does not exist we get a 404 along with the message “Employee with Id 15 not found” as shown below.

implementing the GET Method in WEB API

In the next article, I will discuss how to implement the POST method in WEB API. Here, in this article, I try to explain Implementing the GET Method in ASP.NET WEB API step by step with a simple example. I hope you enjoy this article.

About the Author: Pranaya Rout

Pranaya Rout has published more than 3,000 articles in his 11-year career. Pranaya Rout has very good experience with Microsoft Technologies, Including C#, VB, ASP.NET MVC, ASP.NET Web API, EF, EF Core, ADO.NET, LINQ, SQL Server, MYSQL, Oracle, ASP.NET Core, Cloud Computing, Microservices, Design Patterns and still learning new technologies.

Introduction

HttpClient class provides a base class for sending/receiving the HTTP requests/responses from a URL. It is a supported async feature of .NET framework. HttpClient is able to process multiple concurrent requests. It is a layer over HttpWebRequest and HttpWebResponse. All methods with HttpClient are asynchronous.

Example

In this example, I have created a console application.

To call Web API methods from the console Application, the first step is to install the required packages, using NuGet Package Manager. The following package needs to be installed in the console Application.

Install-Package Microsoft.AspNet.WebApi.Client

Next step is to create HttpClient object. In the following code snippet, the main function calls private static method «CallWebAPIAsync» and this blocks until CallWebAPIAsync completes the process, using wait function.

static void Main(string[] args)  
{  
    CallWebAPIAsync()  
        .Wait();  
}  
static asyncTaskCallWebAPIAsync()  
{  
    using(var client = newHttpClient())  
    {  
        //Send HTTP requests from here.  
    }  
}

Afterwards, we have set the base URL for the HTTP request and set the Accept header. In this example, I have set Accept header to «application/json» which tells the Server to send the data into JSON format.

using(var client = newHttpClient())  
{  
    client.BaseAddress = newUri("http://localhost:55587/");  
    client.DefaultRequestHeaders.Accept.Clear();  
    client.DefaultRequestHeaders.Accept.Add(newMediaTypeWithQualityHeaderValue("application/json"));  
} 

HTTP GET Request

Following code is used to send a GET request for department, as shown below:

using(var client = newHttpClient())  
{  
    client.BaseAddress = newUri("http://localhost:55587/");  
    client.DefaultRequestHeaders.Accept.Clear();  
    client.DefaultRequestHeaders.Accept.Add(newMediaTypeWithQualityHeaderValue("application/json"));  
    //GET Method  
    HttpResponseMessage response = awaitclient.GetAsync("api/Department/1");  
    if (response.IsSuccessStatusCode)  
    {  
        Departmentdepartment = awaitresponse.Content.ReadAsAsync < Department > ();  
        Console.WriteLine("Id:{0}\tName:{1}", department.DepartmentId, department.DepartmentName);  
        Console.WriteLine("No of Employee in Department: {0}", department.Employees.Count);  
    }  
    else  
    {  
        Console.WriteLine("Internal server Error");  
    }  
}

In the code given above, I have used GetAsync method to send HTTP GET request asynchronously. When the execution of this method is finished, it returns HttpResponseMessage,  which contains HTTP response. If the response contains success code as response, it means the response body contains the data in the form of JSON. ReadAsAsync method is used to deserialize the JSON object.

HttpClient does not throw any error when HTTP response contains an error code, but it sets the IsSuccessStatusCode property to false. If we want to treat HTTP error codes as exceptions, we can use HttpResponseMessage.EnsureSuccessStatusCode method.

When we run the code, given above, it throws the exception «Internal Server error».

We have to configure the serializer to detect then handle self-referencing loops. The following code needs to be placed in Global.asax.cs in Web API:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings  
.PreserveReferencesHandling =Newtonsoft.Json.PreserveReferencesHandling.All;  

HTTP POST request

Following code is used to send a POST request for the department:

var department = newDepartment() { DepartmentName = "Test Department" };  
HttpResponseMessage response = awaitclient.PostAsJsonAsync("api/Department", department);  

if (response.IsSuccessStatusCode)  
{  
   // Get the URI of the created resource.  
   UrireturnUrl = response.Headers.Location;  
   Console.WriteLine(returnUrl);  
}

In this code, PostAsJsonAsync method serializes the object into JSON format and sends this JSON object in POST request. HttpClient has a built-in method «PostAsXmlAsync» to send XML in POST request. Also, we can use «PostAsync» for any other formatter.

HTTP PUT Request

Following code is used to send a PUT request for the department:

//PUT Method  
var department = newDepartment() { DepartmentId = 9, DepartmentName = "Updated Department" };  
HttpResponseMessage response = awaitclient.PutAsJsonAsync("api/Department", department);  
if (response.IsSuccessStatusCode)  
{  
   Console.WriteLine("Success");  
} 

Same as POST, HttpClient also supports all three methods: PutAsJsonAsync, PutAsXmlAsync and PutAsync.

HTTP DELETE Request

Following code is used to send a DELETE request for the department:

intdepartmentId = 9;  
HttpResponseMessage response = awaitclient.DeleteAsync("api/Department/" + departmentId);  
if (response.IsSuccessStatusCode)  
{  
   Console.WriteLine("Success");  
}

HttpClient only supports DeleteAsync method because Delete method does not have a request body.

Summary 

HttpClient is used to send an HTTP request, using a URL. HttpClient can be used to make Web API requests from the console Application, Winform Application, Web form Application, Windows store Application, etc.

Понравилась статья? Поделить с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
  • Гта 5 будет работать на windows 7
  • Как подключить дополнительный монитор к компьютеру windows 7
  • Хост окна консоли что это за процесс windows 10 грузит процессор
  • Не отображается смена языка windows 10
  • Эмулятор андроид для windows 10 portable