Implementing custom model binding 

Now, we are going to rework the implementation of the post question endpoint so that we have a naive implementation of custom model binding: 

  1. First, let's install Newtonsoft.Json via NuGet. We are going to use this library to deserialize the request body.
  2. Now, add the following using statements in QuestionsController.cs:
using System.IO; 
using Newtonsoft.Json;
  1. In the PostQuestion action method, remove the parameters and manually create the questionPostRequest model using JSON.NET:
[HttpPost]
public async Task<ActionResult<QuestionGetSingleResponse>> PostQuestion()
{
var json =
await new StreamReader(Request.Body).ReadToEndAsync();

var questionPostRequest =
JsonConvert.DeserializeObject<QuestionPostRequest>(json);


var savedQuestion = _dataRepository.PostQuestion(...);
...
}

We also need to flag the method as asynchronous with the async keyword and return Task because reading the response body is asynchronous. We should, of course, make the call to the data repository asynchronous as well, but the change we have made will be fine to demonstrate the garbage collection problem.

This implementation is inefficient for large requests. This is because it will be processing large string objects that could be placed on the large object heap, which will be expensive to collect.

  1. Start the REST API in Visual Studio.
  2. Set up a PerfView collection to collect garbage collection data, exactly like we did before.
  3. Start the same load test again in WebSurge and start the collection in PerfView.
  4. When the load test has finished, stop the collection and look at the data that was collected:

There were 65 objects added to generation 2 in this test, resulting in a total pause of 1,087 milliseconds. So, there was just over 1 second of a delay due to the garbage collection process.

  1. Before we finish this section, let's clean a few things up. First, let's revert the PostQuestion action method implementation to the previous version:
[HttpPost]
public ActionResult<QuestionGetSingleResponse>
PostQuestion(QuestionPostRequest questionPostRequest)
{
var savedQuestion =
_dataRepository.PostQuestion(new QuestionPostFullRequest
{
Title = questionPostRequest.Title,
Content = questionPostRequest.Content,
UserId = "1",
UserName = "[email protected]",
Created = DateTime.UtcNow
});
return CreatedAtAction(nameof(GetQuestion), new
{
questionId = savedQuestion.QuestionId
}, savedQuestion);
}
  1. Let's remove the System.IO and Newtonsoft.Json using statements, as well as the Newtonsoft.Json NuGet dependency.
  2. Let's also remove the questions that were generated by the load tests. Open SQL Server Management Studio, right-click on the QandA database in Object Explorer, and choose New Query. In the query window that opens, add the following command:
DELETE FROM dbo.Question WHERE QuestionId > 2
  1. Press F5 to run the command, which will take a few seconds to complete.

There are two morals to this story. The first is to avoid processing large strings to keep the garbage collection process nice and efficient. The second is to try to stick to the standard model binding process because it is very efficient!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.58.196.223