Consume Web API By MVC In .NET Core (3), HttpWebRequest

This series of articles will give you ways to consume Web API by a ASP.NET MVC Client in .NET Core with diffirent methods.

In this article, we will repeat what we did in the series (2) , make the MVC app as a client to consume Web API while through HttpWebRequest, instead of through HttpClient.

Introduction

In the article (1) of the series,  we created a ASP.NET Core MVC app and associate a Web API service in it:

  •  MVC is a client/server app, with a web page as a client and SQL server as server, linked by Entity Framework;

  •  Web API is a Server side service, with a RESTful output for consumer, that is linked to database by entity framework.

For our test purposes, MVC and Web API are against two different database, MVC is against the database pubs, while Web API is against database DB_Demo_API.

In the article (2) of the series,  we first created an additonal ASP.NET Core MVC app and then made it to comsume Web API created in (1), by HttpClient:

  • The new MVC is pointing to StoresMVCCallWebAPI and against the same database as previous MVC module in (1), see above, the output is the same:

  • After changing the link to Web API through HttpClient, we got the result like this:

this is the Web API output:

In this article, we will repeat what we did in the series (2) , make the MVC app as a client to consume Web API while through HttpWebRequest, instead of through HttpClient.

Make a new MVC module

For the purposes of convenient analysis and comparison, we will make another MVC module (controller/view) that's exactly the same as the previous MVC module but with a different name:

  •  StoresWebRequestCallWebAPIController

see details from Part I, linked above, Part A, Step 1, 3, Add controller. The added Controller is like this:

Visual Studio Create

  • A StroesWebRequestCallWebAPI controller (Controllers/StoresWebRequestCallWebAPIController.cs)
  • Razor view files for Create, Delete, Details, Edit, and Index pages (Views/StoresWebRequestCallWebAPI/*.cshtml)

The behavior of the new controller,  StroesWebRequestCallWebAPI, is exactly the same as the old MVC controller, StroesMVC.

Run and Test the app

Modify the header of the file: Views/Shared/_layout.cshtml Views, shown below:

    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="StoresMVC" asp-action="Index">MVC app</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="StoresMVCCallWebAPI" asp-action="Index">HttpClient Call Web API</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="StoresWebRequestCallWebAPI" asp-action="Index">HttpWebRequest Call Web API</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Swagger" asp-action="Index">Web API</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    </header>

We add:

  • MVC app
  • HttpClient Call Web API --- added in the article (2) 
  • HttpWebRequest Call Web API --- added in this article
  • Web API

Then, we run the app,

We can see the two controller endpoints:

  • https://localhost:44350/StoresWebRequestCallWebAPI  --- above
  • https://localhost:44350/StoresMVC  --- below

exactly have the same results, because the are against the same database --- pubs,

While the Web API (Swagger),

 has a different data set, that is due the fact that it is against the different database: DB_Demo_API,

At the end of the article, the controller StoresWebRequestCallWebAPI will consume the Web API through HttpWebRequest, then these two will share the same database, and get the same result.

 

How to Consume RESTful APIs

We can see the most comprehensive list of ways to consume RESTful APIs in your C# projects from this article A Few Great Ways to Consume RESTful API in C#,we borrowed here,

"There are several ways to consume a RESTful API in C#,

  •     HttpWebRequest/Response Class
  •     WebClient Class
  •     HttpClient Class
  •     RestSharp NuGet Package
  •     ServiceStack Http Utils
  •     Flurl
  •     DalSoft.RestClient

Every one of these has pros and cons."

In this article, we will choose to use HttpWebRequest from Microsoft for our project. In practice or production, you may choose different ones.

Implementation

The database context is used in each of the CRUD methods in the both MVC Controller and Web API ApiController. They have the same methods, same signatures, and implementations.  For each action, we will use code to redirect the direct database pubs, to the Web API that is against database DB_Demo_API. 

We start from DELETE that demo the least change from the HttpClient method:

 DELETE

We use one line code: DeleteAsync to do the job by HttpClient:

​
// POST: StoresMVCCallAPI/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(string id)
{
    // Original Code in MVC Module
    //var store = await _context.Stores.FindAsync(id);
    //_context.Stores.Remove(store);
    //await _context.SaveChangesAsync();

    // Consume API by HttpClinet:
    await client.DeleteAsync(url + id);

    return RedirectToAction(nameof(Index));
}

​

where, the rul is defined in the Controller class:

string url = "https://localhost:44350/api/storesWebAPI/";

Now, we need thre line code to complete the job by HttpWebRequest:

        // POST: StoresMVCCallWebAPI/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> DeleteConfirmed(string id)
        {
            // Original Code in MVC module:
            //var store = await _context.Stores.FindAsync(id);
            //_context.Stores.Remove(store);
            //await _context.SaveChangesAsync();

            // Consume API by HttpClinet
            //await client.DeleteAsync(url + id);

            // Consume API by HtteWebRequest:

            // Create a request using a URL that can receive a post.
            WebRequest request = WebRequest.Create(url + id);
            // Set the Method property of the request to DELETE.
            request.Method = "DELETE";
            // Set the ContentType property of the WebRequest.
            //request.ContentType = "application/json";
            // Get the response --- delete the record in database
            WebResponse response = request.GetResponse();

            return RedirectToAction(nameof(Index));
        }

where, WebRequest is a abstract class, we need to use Create method to create a WebRequest to comsume HTTP request:

            // Create a request using a URL that can receive a post.
            WebRequest request = WebRequest.Create(url + id);

We need to define the request method, the VERB, as DELETE:

            // Set the Method property of the request to DELETE.
            request.Method = "DELETE";

Otherwise, the default value will be GET, while the ContentType is "application/json" by default, we can ignore it.

            // Set the ContentType property of the WebRequest.
            //request.ContentType = "application/json";

Finally, the GetRespoinse() method to get the action to be done:

            // Get the response --- delete the record in database
            WebResponse response = request.GetResponse();

POST

The Create method with an input Object Store, the following one-line code saves the object into the database (pubs) through entity framework by HttpClient:

public async Task<IActionResult> Create([Bind("Stor_Id,Stor_Name,Stor_Address,City,State,Zip")] Store store)
{
    if (ModelState.IsValid)
    {
        //_context.Add(store);
        //await _context.SaveChangesAsync();

        // Consume API by HttpClient
        await client.PostAsJsonAsync<Store>(url, store);

        return RedirectToAction(nameof(Index));
    }
    return View(store);
}

As DELETE, we need at least three line code to complete the action:

  • Create a request
  • Define the request Method as POST
  • Using GetResponse() method to get the action done --- writing data into database
       // POST: StoresMVCCallWebAPI/Create
        // To protect from overposting attacks, enable the specific properties you want to bind to.
        // For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create([Bind("Stor_Id,Stor_Name,Stor_Address,City,State,Zip")] Store store)
        {
            if (ModelState.IsValid)
            {
                // Original code in MVC Module:
                //_context.Add(store);
                //await _context.SaveChangesAsync();

                // Consume API by HttpClient
                //await client.PostAsJsonAsync<Store>(url, store);


                // Consume API by HttpWebRequest

                // Create a request using a URL that can receive a post.
                WebRequest request = WebRequest.Create(url);
                // Set the Method property of the request to POST.
                request.Method = "POST";              
                // Set the ContentType property of the WebRequest.
                request.ContentType = "application/json";             

                // Serialize input Object
                var input = JsonConvert.SerializeObject(store, Newtonsoft.Json.Formatting.Indented);
                byte[] byteArray = Encoding.UTF8.GetBytes(input);

                // Set the ContentLength property of the WebRequest.
                request.ContentLength = byteArray.Length;

                // Get the request stream.
                Stream dataStream = request.GetRequestStream();
                // Write the data to the request stream.
                dataStream.Write(byteArray, 0, byteArray.Length);
                // Close the Stream object.
                dataStream.Close();

                // Get the response --- write into database
                WebResponse response = request.GetResponse();


                return RedirectToAction(nameof(Index));
            }
            return View(store);
        }

Furthermore, we need one more step to serialize the data and Get the request stream and bring it into database:

                // Serialize input Object
                var input = JsonConvert.SerializeObject(store, Newtonsoft.Json.Formatting.Indented);
                byte[] byteArray = Encoding.UTF8.GetBytes(input);

                // Set the ContentLength property of the WebRequest.
                request.ContentLength = byteArray.Length;

                // Get the request stream.
                Stream dataStream = request.GetRequestStream();
                // Write the data to the request stream.
                dataStream.Write(byteArray, 0, byteArray.Length);
                // Close the Stream object.
                dataStream.Close();

PUT (Edit)

We need to bring two parameters, one is id, another is the object, and we use PutAsJsonAsync method by HttpClient:

try
{
    // Original code:
    //_context.Update(store);
    //await _context.SaveChangesAsync();

    // Consume API
    await client.PutAsJsonAsync<Store>(url + id, store);
}

​

Similar to DELETE, we need to give the id as an input parameter, and also need to bring the Object as input to database, as POST:

       // POST: StoresMVCCallWebAPI/Edit/5
        // To protect from overposting attacks, enable the specific properties you want to bind to.
        // For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(string id, [Bind("Stor_Id,Stor_Name,Stor_Address,City,State,Zip")] Store store)
        {
            if (id != store.Stor_Id)
            {
                return NotFound();
            }

            if (ModelState.IsValid)
            {
                try
                {
                    // Original code in MVC module:
                    //_context.Update(store);
                    //await _context.SaveChangesAsync();

                    // Consume API by HttpClient
                    //await client.PutAsJsonAsync<Store>(url + id, store);

                    // Consume API by HttpWebRequest

                    // Create a request using a URL that can receive a post.
                    WebRequest request = WebRequest.Create(url + id);
                    // Set the Method property of the request to PUT.
                    request.Method = "PUT";
                    // Set the ContentType property of the WebRequest.
                    request.ContentType = "application/json";

                    // Serialize input Object
                    var input = JsonConvert.SerializeObject(store, Newtonsoft.Json.Formatting.Indented);
                    byte[] byteArray = Encoding.UTF8.GetBytes(input);

                    // Set the ContentLength property of the WebRequest.
                    request.ContentLength = byteArray.Length;

                    // Get the request stream.
                    Stream dataStream = request.GetRequestStream();
                    // Write the data to the request stream.
                    dataStream.Write(byteArray, 0, byteArray.Length);
                    // Close the Stream object.
                    dataStream.Close();

                    // Get the response --- write into database
                    WebResponse response = request.GetResponse();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!StoreExists(store.Stor_Id))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
                return RedirectToAction(nameof(Index));
            }
            return View(store);
        }

GET/id

There are three places to use the GET method, but actually, they are the same. We use GetStringAsync by HttpClient. Here, due to getting data, we need to Deserialize the JSON into class, we use JsonConvert.DeserializeObject in Newtonsoft.Json namespace.

​// GET: StoresMVCCallAPI/Delete/5
public async Task<IActionResult> Delete(string id)
{
    if (id == null)
    {
        return NotFound();
    }

    // Original code in MVC module:
    //var store = await _context.Stores
    //    .FirstOrDefaultAsync(m => m.Stor_Id == id);

    // Consume API by HttpClient:
    var store = JsonConvert.DeserializeObject<Store>(await client.GetStringAsync(url + id));

    if (store == null)
    {
        return NotFound();
    }

    return View(store);
}

​

Similar to POST, but now we need to handle the output Object from response = request.GetResponse():

        // GET: StoresMVCCallWebAPI/Details/5
        public async Task<IActionResult> Details(string id)
        {
            if (id == null)
            {
                return NotFound();
            }

            // Original code in MVC Module:
            //var store = await _context.Stores
            //    .FirstOrDefaultAsync(m => m.Stor_Id == id);

            // Consume API by HttpClient
            //var store = JsonConvert.DeserializeObject<Store>(await client.GetStringAsync(url + id));

            // Consume API by HttpWebRequest

            // Create a request for the URL.
            request = WebRequest.Create(url + id);

            // If required by the server, set the credentials.
            request.Credentials = CredentialCache.DefaultCredentials;

            // Get the response.
            WebResponse response = request.GetResponse();

            string responseFromServer;

            // Get the stream containing content returned by the server.
            // The using block ensures the stream is automatically closed.
            using (Stream dataStream = response.GetResponseStream())
            {
                // Open the stream using a StreamReader for easy access.
                StreamReader reader = new StreamReader(dataStream);
                // Read the content.
                responseFromServer = reader.ReadToEnd();
            }

            var store = JsonConvert.DeserializeObject<Store>(responseFromServer);

            if (store == null)
            {
                return NotFound();
            }

            return View(store);

        }

GET

The same as Get/ID, but we use List<Store>, by HttpClient:

// GET: StoresMVCCallAPI
public async Task<IActionResult> Index()
{
    // Original code in MVC module:
    //return View(await _context.Stores.ToListAsync());

    // Consume API by HttpClient
    return View(JsonConvert.DeserializeObject<List<Store>>(await client.GetStringAsync(url)).ToList());
}

By HttpWebRequest:

        // GET: StoresMVCCallAPI
        public async Task<IActionResult> Index()
        {
            // Original code in MVC module:
            //return View(await _context.Stores.ToListAsync());

            // Consume API by HttpClient
            //var result1 = await client.GetStringAsync(url);

            // Consume API by HttpWebRequest

            // Create a request for the URL.
            request = WebRequest.Create(url);

            // If required by the server, set the credentials.
            //request.Credentials = CredentialCache.DefaultCredentials;

            // Get the response.
            WebResponse response = request.GetResponse();

            string responseFromServer;

            // Get the stream containing content returned by the server.
            // The using block ensures the stream is automatically closed.
            using (Stream dataStream = response.GetResponseStream())
            {
                // Open the stream using a StreamReader for easy access.
                StreamReader reader = new StreamReader(dataStream);
                // Read the content.
                responseFromServer = reader.ReadToEnd();
            }

            var result2 = JsonConvert.DeserializeObject<List<Store>>(responseFromServer);
            var result3 = result2.ToList();
            return View(result3);


            //return View(JsonConvert.DeserializeObject<List<Store>>(await client.GetStringAsync(url)).ToList());
        }

Finally, we got the full code:

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Xml;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using MVCCallWebAPI.Models.DB;
using Newtonsoft.Json;

namespace MVCCallWebAPI.Controllers
{
    public class StoresWebRequestCallWebAPIController : Controller
    {
        private readonly pubsContext _context;


        static string url = "https://localhost:44381/api/storesWebAPI/"; 

        public StoresWebRequestCallWebAPIController(pubsContext context)
        {
            _context = context;

        }


        // GET: StoresMVCCallAPI
        public async Task<IActionResult> Index()
        {
            // Original code in MVC:
            //return View(await _context.Stores.ToListAsync());

            // Consume API by HttpClient
            //var result1 = await client.GetStringAsync(url);
            //var result2 = JsonConvert.DeserializeObject<List<Store>>(result1); 
            //var result3 = result2.ToList();
            //return View(result3);

            // Consume API by HttpWebRequest

            // Create a request for the URL.
            request = WebRequest.Create(url);


            // Get the response.
            WebResponse response = request.GetResponse();

            string responseFromServer;

            // Get the stream containing content returned by the server.
            // The using block ensures the stream is automatically closed.
            using (Stream dataStream = response.GetResponseStream())
            {
                // Open the stream using a StreamReader for easy access.
                StreamReader reader = new StreamReader(dataStream);
                // Read the content.
                responseFromServer = reader.ReadToEnd();
            }

            var result2 = JsonConvert.DeserializeObject<List<Store>>(responseFromServer);
            var result3 = result2.ToList();
            return View(result3);


            //return View(JsonConvert.DeserializeObject<List<Store>>(await client.GetStringAsync(url)).ToList());
        }

        // GET: StoresMVCCallWebAPI/Details/5
        public async Task<IActionResult> Details(string id)
        {
            if (id == null)
            {
                return NotFound();
            }

            // Original code in MVC:
            //var store = await _context.Stores
            //    .FirstOrDefaultAsync(m => m.Stor_Id == id);

            // Consume API by HttpClient
            //var store = JsonConvert.DeserializeObject<Store>(await client.GetStringAsync(url + id));


            // Consume API by HttpWebRequest

            // Create a request for the URL.
            request = WebRequest.Create(url + id);

            // If required by the server, set the credentials.
            request.Credentials = CredentialCache.DefaultCredentials;

            // Get the response.
            WebResponse response = request.GetResponse();

            string responseFromServer;

            // Get the stream containing content returned by the server.
            // The using block ensures the stream is automatically closed.
            using (Stream dataStream = response.GetResponseStream())
            {
                // Open the stream using a StreamReader for easy access.
                StreamReader reader = new StreamReader(dataStream);
                // Read the content.
                responseFromServer = reader.ReadToEnd();
            }

            var store = JsonConvert.DeserializeObject<Store>(responseFromServer);

            if (store == null)
            {
                return NotFound();
            }

            return View(store);

        }

        // GET: StoresMVCCallWebAPI/Create
        public IActionResult Create()
        {
            return View();
        }

        // POST: StoresMVCCallWebAPI/Create
        // To protect from overposting attacks, enable the specific properties you want to bind to.
        // For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create([Bind("Stor_Id,Stor_Name,Stor_Address,City,State,Zip")] Store store)
        {
            if (ModelState.IsValid)
            {
                // Original code in MVC:
                //_context.Add(store);
                //await _context.SaveChangesAsync();

                // Consume API by HttpClient
                //await client.PostAsJsonAsync<Store>(url, store);

                // Consume API by HttpWebRequest

                // Create a request using a URL that can receive a post.
                WebRequest request = WebRequest.Create(url);
                // Set the Method property of the request to POST.
                request.Method = "POST";              
                // Set the ContentType property of the WebRequest.
                request.ContentType = "application/json";             

                // Serialize input Object
                var input = JsonConvert.SerializeObject(store, Newtonsoft.Json.Formatting.Indented);
                byte[] byteArray = Encoding.UTF8.GetBytes(input);

                // Set the ContentLength property of the WebRequest.
                request.ContentLength = byteArray.Length;

                // Get the request stream.
                Stream dataStream = request.GetRequestStream();
                // Write the data to the request stream.
                dataStream.Write(byteArray, 0, byteArray.Length);
                // Close the Stream object.
                dataStream.Close();

                // Get the response --- write into database
                WebResponse response = request.GetResponse();


                return RedirectToAction(nameof(Index));
            }
            return View(store);
        }

        // GET: StoresMVCCallWebAPI/Edit/5
        public async Task<IActionResult> Edit(string id)
        {
            if (id == null)
            {
                return NotFound();
            }

            // Original code in MVC:
            //var store = await _context.Stores.FindAsync(id);

            // Consume API by HttpClient
            //var store = JsonConvert.DeserializeObject<Store>(await client.GetStringAsync(url + id));

            // Consume API by HttpWebRequest

            // Create a request for the URL.
            request = WebRequest.Create(url + id);

            // If required by the server, set the credentials.
            request.Credentials = CredentialCache.DefaultCredentials;

            // Get the response.
            WebResponse response = request.GetResponse();

            string responseFromServer;

            // Get the stream containing content returned by the server.
            // The using block ensures the stream is automatically closed.
            using (Stream dataStream = response.GetResponseStream())
            {
                // Open the stream using a StreamReader for easy access.
                StreamReader reader = new StreamReader(dataStream);
                // Read the content.
                responseFromServer = reader.ReadToEnd();
            }

            var store = JsonConvert.DeserializeObject<Store>(responseFromServer);

            if (store == null)
            {
                return NotFound();
            }

            return View(store);
        }

        // POST: StoresMVCCallWebAPI/Edit/5
        // To protect from overposting attacks, enable the specific properties you want to bind to.
        // For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(string id, [Bind("Stor_Id,Stor_Name,Stor_Address,City,State,Zip")] Store store)
        {
            if (id != store.Stor_Id)
            {
                return NotFound();
            }

            if (ModelState.IsValid)
            {
                try
                {
                    // Original code in MVC:
                    //_context.Update(store);
                    //await _context.SaveChangesAsync();

                    // Consume API by HttpClient
                    //await client.PutAsJsonAsync<Store>(url + id, store);

                    // Consume API by HttpWebRequest

                    // Create a request using a URL that can receive a post.
                    WebRequest request = WebRequest.Create(url + id);
                    // Set the Method property of the request to PUT.
                    request.Method = "PUT";
                    // Set the ContentType property of the WebRequest.
                    request.ContentType = "application/json";

                    // Serialize input Object
                    var input = JsonConvert.SerializeObject(store, Newtonsoft.Json.Formatting.Indented);
                    byte[] byteArray = Encoding.UTF8.GetBytes(input);

                    // Set the ContentLength property of the WebRequest.
                    request.ContentLength = byteArray.Length;

                    // Get the request stream.
                    Stream dataStream = request.GetRequestStream();
                    // Write the data to the request stream.
                    dataStream.Write(byteArray, 0, byteArray.Length);
                    // Close the Stream object.
                    dataStream.Close();

                    // Get the response --- write into database
                    WebResponse response = request.GetResponse();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!StoreExists(store.Stor_Id))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
                return RedirectToAction(nameof(Index));
            }
            return View(store);
        }

        // GET: StoresMVCCallWebAPI/Delete/5
        public async Task<IActionResult> Delete(string id)
        {
            if (id == null)
            {
                return NotFound();
            }

            // Original code in MVC:
            //var store = await _context.Stores
            //    .FirstOrDefaultAsync(m => m.Stor_Id == id);

            // Consume API by HttpClient
            //var store = JsonConvert.DeserializeObject<Store>(await client.GetStringAsync(url + id));

            // Consume API by HttpWebRequest

            // Create a request for the URL.
            request = WebRequest.Create(url + id);

            // If required by the server, set the credentials.
            request.Credentials = CredentialCache.DefaultCredentials;

            // Get the response.
            WebResponse response = request.GetResponse();

            string responseFromServer;

            // Get the stream containing content returned by the server.
            // The using block ensures the stream is automatically closed.
            using (Stream dataStream = response.GetResponseStream())
            {
                // Open the stream using a StreamReader for easy access.
                StreamReader reader = new StreamReader(dataStream);
                // Read the content.
                responseFromServer = reader.ReadToEnd();
            }

            var store = JsonConvert.DeserializeObject<Store>(responseFromServer);

            if (store == null)
            {
                return NotFound();
            }

            return View(store);
        }

        // POST: StoresMVCCallWebAPI/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> DeleteConfirmed(string id)
        {
            // Original Code in MVC:
            //var store = await _context.Stores.FindAsync(id);
            //_context.Stores.Remove(store);
            //await _context.SaveChangesAsync();

            // Consume API by HttpClinet
            //await client.DeleteAsync(url + id);

            // Consume API by HttpWebRequest

            // Create a request using a URL that can receive a post.
            WebRequest request = WebRequest.Create(url + id);
            // Set the Method property of the request to DELETE.
            request.Method = "DELETE";
            // Set the ContentType property of the WebRequest.
            //request.ContentType = "application/json";

            // Get the response --- delete the record in database
            WebResponse response = request.GetResponse();

            return RedirectToAction(nameof(Index));
        }

        private bool StoreExists(string id)
        {
            return _context.Stores.Any(e => e.Stor_Id == id);
        }
    }
}

Run and Test the app

The MVC module,

The MVC module calls Web API: the data is different from the MVC module above, but the same as the Web API module.

The Web API module,

Conclusion

In this article, we used MVC, and Web API templates to build out four apps, one is MVC module, one is Web API, then we used HttpClient in MVC module to consume Web API with only one line of code written manually, and used HttpWebRequest to consume Web API. We will make the comparison for them on the next article.

Reference