Async Web Api Action Returning Prematurely - c#

I am writing a nuget package that will consume a REST API I wrote. Im having some difficulty in calling it asynchronously using RestSharp.
I have the following controller method:
[HttpGet("{id}")]
public async Task<IActionResult> GetFeatureByIdAsync(string id)
{
if (string.IsNullOrWhiteSpace(id))
{
ModelState.AddModelError("id-Null", "The id parameter cannot be null.");
return BadRequest(ModelState);
}
var feature = await _director.GetFeatureById(id);
if (feature == null)
return NotFound();
var model = new ViewModel<Feature>(feature);
return Ok(model);
}
I have the follow class library in a seperate solution:
public async Task<bool> IsSwitchEnabledAsync(string name)
{
string fullyFormedUrl = $"{_url}/{name}";
var client = new RestClient(fullyFormedUrl) { Encoding = Encoding.UTF8 };
var request = new RestRequest(Method.GET) { RequestFormat = DataFormat.Json };
var result = await client.ExecuteTaskAsync<FeatureViewModel>(request);
var message = $"Response: {result.StatusCode}, {result.ResponseStatus}, " +
$"\n\nError: {result.ErrorException}, {result.ErrorMessage} " +
$"\n\nData: {result.Content}";
Debug.WriteLine(message);
return result.Data != null;
}
I have the following basic integration test sandbox:
[TestFixture]
public class Sandbox
{
private FeatureSwitch _sut;
[OneTimeSetUp]
public void Setup()
{
const string machineName = "localhost";
const int port = 5000;
_sut = new FeatureSwitch(machineName, port);
}
[Test]
public async Task ShouldReturnTrue()
{
var result = await _sut.IsSwitchEnabledAsync("Release_US501_AddUser");
result.Should().BeTrue();
}
}
I am looking for a little education on the best approach on how to call the API correctly? As my sandbox code is failing with an Internal Server 500 Error. This is because the api method is waiting for the nested async call to complete. So the initial request returns back to the sandbox code before the nested api call has a chance to complete.
The sandbox test code needs to wait for the API to return a result. At the moment it is not doing this.
So what is the correct approach here?
UPDATE: My issue was down to incorrect usage of a Mongo library method.

My issue came from a .chained method call on a Mongo library method:
I was trying to do the following:
Collection.Find(x => x.Name.ToLower().Equals(name.ToLower())
The code compiled but it was throwing an exception that VS studio 17 was not breaking on so i had no idea where the issue was occurring. With code lens turned on, I noticed that the failed requests highlighted in red. This opened an App Insights window which highlighted a break down of 4 InvalidOperationException() that had been thrown. That's how i discovered what the Internal Server Error 500 was about.
Anyways that's how i solved Async Web API problem - it was my first time using it on a web service so I had no idea what the expected default behaviour ought to be.

Related

How to test a controller POST method which returns no data in response content in .NET Core 3.1?

i am new to integration tests. I have a controller method which adds a user to the database, as shown below:
[HttpPost]
public async Task<IActionResult> CreateUserAsync([FromBody] CreateUserRequest request)
{
try
{
var command = new CreateUserCommand
{
Login = request.Login,
Password = request.Password,
FirstName = request.FirstName,
LastName = request.LastName,
MailAddress = request.MailAddress,
TokenOwnerInformation = User
};
await CommandBus.SendAsync(command);
return Ok();
}
catch (Exception e)
{
await HandleExceptionAsync(e);
return StatusCode(StatusCodes.Status500InternalServerError,
new {e.Message});
}
}
As you have noticed my method returns no information about the user which has been added to the database - it informs about the results of handling a certain request using the status codes. I have written an integration test to check is it working properly:
[Fact]
public async Task ShouldCreateUser()
{
// Arrange
var createUserRequest = new CreateUserRequest
{
Login = "testowyLogin",
Password = "testoweHaslo",
FirstName = "Aleksander",
LastName = "Kowalski",
MailAddress = "akowalski#onet.poczta.pl"
};
var serializedCreateUserRequest = SerializeObject(createUserRequest);
// Act
var response = await HttpClient.PostAsync(ApiRoutes.CreateUserAsyncRoute,
serializedCreateUserRequest);
// Assert
response
.StatusCode
.Should()
.Be(HttpStatusCode.OK);
}
I am not sure is it enough to assert just a status code of response returned from the server. I am confused because, i don't know, shall i attach to assert section code, which would get all the users and check does it contain created user for example. I don't even have any id of such a user because my application finds a new id for the user while adding him/her to the database. I also have no idea how to test methods like that:
[HttpGet("{userId:int}")]
public async Task<IActionResult> GetUserAsync([FromRoute] int userId)
{
try
{
var query = new GetUserQuery
{
UserId = userId,
TokenOwnerInformation = User
};
var user = await QueryBus
.SendAsync<GetUserQuery, UserDto>(query);
var result = user is null
? (IActionResult) NotFound(new
{
Message = (string) _stringLocalizer[UserConstants.UserNotFoundMessageKey]
})
: Ok(user);
return result;
}
catch (Exception e)
{
await HandleExceptionAsync(e);
return StatusCode(StatusCodes.Status500InternalServerError,
new {e.Message});
}
}
I believe i should somehow create a user firstly in Arrange section, get it's id and then use it in Act section with the GetUserAsync method called with the request sent by HttpClient. Again the same problem - no information about user is returned, after creation (by the way - it is not returned, because of my CQRS design in whole application - commands return no information). Could you please explain me how to write such a tests properly? Have i missed anything? Thanks for any help.
This is how I do it:
var response = (CreatedResult) await _controller.Post(createUserRequest);
response.StatusCode.Should().Be(StatusCodes.Status201Created);
The second line above is not necessary, just there for illustration.
Also, your response it's better when you return a 201 (Created) instead of the 200(OK) on Post verbs, like:
return Created($"api/users/{user.id}", user);
To test NotFound's:
var result = (NotFoundObjectResult) await _controller.Get(id);
result.StatusCode.Should().Be(StatusCodes.Status404NotFound);
The NotFoundObjectResult assumes you are returning something. If you are just responding with a 404 and no explanation, replace NotFoundObjectResult with a NotFoundResult.
And finally InternalServerErrors:
var result = (ObjectResult) await _controller.Get(id);
result.StatusCode.Should().Be(StatusCodes.Status500InternalServerError);
You can use integrationFixture for that using this NuGet package. This is an AutoFixture alternative for integration tests.
The documented examples use Get calls but you can do other calls too. Logically, you should test for the status code (OkObjectResult means 200) value and the response (which could be an empty string, that is no problem at all).
Here is the documented example for a normal Get call.
[Fact]
public async Task GetTest()
{
// arrange
using (var fixture = new Fixture<Startup>())
{
using (var mockServer = fixture.FreezeServer("Google"))
{
SetupStableServer(mockServer, "Response");
var controller = fixture.Create<SearchEngineController>();
// act
var response = await controller.GetNumberOfCharacters("Hoi");
// assert
var request = mockServer.LogEntries.Select(a => a.RequestMessage).Single();
Assert.Contains("Hoi", request.RawQuery);
Assert.Equal(8, ((OkObjectResult)response.Result).Value);
}
}
}
private void SetupStableServer(FluentMockServer fluentMockServer, string response)
{
fluentMockServer.Given(Request.Create().UsingGet())
.RespondWith(Response.Create().WithBody(response, encoding: Encoding.UTF8)
.WithStatusCode(HttpStatusCode.OK));
}
In the example above, the controller is resolved using the DI described in your Startup class.
You can also do an actual REST call using using Refit. The application is self hosted inside your test.
using (var fixture = new RefitFixture<Startup, ISearchEngine>(RestService.For<ISearchEngine>))
{
using (var mockServer = fixture.FreezeServer("Google"))
{
SetupStableServer(mockServer, "Response");
var refitClient = fixture.GetRefitClient();
var response = await refitClient.GetNumberOfCharacters("Hoi");
await response.EnsureSuccessStatusCodeAsync();
var request = mockServer.LogEntries.Select(a => a.RequestMessage).Single();
Assert.Contains("Hoi", request.RawQuery);
}
}

ASP .NET Core Integration Tests fails with corrupted body

I'm working on a project where we have to develop a web API with ASP .NET Core 3.x. So far, so good, it is running well. Now, I'm writing some integration tests for this web API and I have some trouble to get the tests for everything else than GET request to work.
We're using the Clean Architecture from Jason Taylor. This means we have a core project with all our request handler, a domain project with all database entities and a presentation project for the API controllers. We use MediatR and dependency injection for the communication between these projects.
Now, we have the problem that the body data of the reuqest doesn't reach the controller.
This is how the Update method in the controller looks like:
[ApiController]
[Route("api/[controller]/[action]")]
public abstract class BaseController : ControllerBase
{
private IMediator _mediator;
protected IMediator Mediator => _mediator ??= HttpContext.RequestServices.GetService<IMediator>();
}
public class FavoriteController : BaseController
{
[HttpPut("{id}")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> Update(long id, UpdateFavoriteCommand command)
{
if (command == null || id != command.Id)
{
return BadRequest();
}
// Sends the request to the corresponding IRequestHandler
await Mediator.Send(command);
return NoContent();
}
}
We use xUnit.net as test framework.
For the integration tests, we're using an InMemory SQLite database which is setup in a fixture class.
The test looks like the following:
public class UpdateFavoritesTestSqlite : IClassFixture<WebApplicationFactoryWithInMemorySqlite<Startup>>
{
private readonly WebApplicationFactoryWithInMemorySqlite<Startup> _factory;
private readonly string _endpoint;
public UpdateFavoritesTestSqlite(WebApplicationFactoryWithInMemorySqlite<Startup> factory)
{
_factory = factory;
_endpoint = "api/Favorite/Update/";
}
[Fact]
public async Task UpdateFavoriteDetail_WithFullUpdate_ShouldUpdateCorrectly()
{
// Arange
var client = _factory.CreateClient(); // WebApplicationFactory.CreateClient()
var command = new UpdateFavoriteCommand
{
Id = 5,
Caption = "caption new",
FavoriteName = "a new name",
Public = true
};
// Convert to JSON
var jsonString = JsonConvert.SerializeObject(command);
var httpContent = new StringContent(jsonString, Encoding.UTF8, "application/json");
var stringUri = client.BaseAddress + _endpoint + command.Id;
var uri = new Uri(stringUri);
// Act
var response = await client.PutAsync(uri, httpContent);
response.EnsureSuccessStatusCode();
httpContent.Dispose();
// Assert
response.StatusCode.ShouldBe(HttpStatusCode.NoContent);
}
}
If we run the test, we get an 400 Bad Request error.
If we run the test in Debug mode, we can see that the code throws a custom ValidationException because of a model state error. This is configured in the DependencyInjection of the presentation project:
services
.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
options.InvalidModelStateResponseFactory = context =>
{
var failures = context.ModelState.Keys
.Where(k => ModelValidationState.Invalid.Equals(context.ModelState[k].ValidationState))
.ToDictionary(k => k, k => (IEnumerable<string>)context.ModelState[k].Errors.Select(e => e.ErrorMessage).ToList());
throw new ValidationException(failures);
};
})
.AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining<IWebApiDbContext>());
The failures object contains one error which says:
The input does not contain any JSON tokens. Expected the input to start with a valid JSON token, when isFinalBlock is true. Path: $ | LineNumber: 0 | BytePositionInLine: 0.
Here is a screenshot: Visual Studio in Debugging mode with json error.
In one article in stackoverflow I've read, that removing the [ApiController] class attribute can result in a more detailed error description. During debugging again the test and setting a breakpoint int the Update method from the FavoriteController at the line with await Mediator.Send(command);, I was able to see, that the command object arriving the Update method contains only null or default values, except the id, which was 5.
command
Caption null string
FavoriteName null string
Id 5 long
Public false bool
The most confusing (and frustrating) part is, that a manual test with swagger or postman are both successfull. The way I understand it, there has to be a problem during the integration test.
I hope, someone can help me and see what I'm missing. Could it be possible that there is something wrong with the HttpClient of the Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory?
We've found the problem in our LoggingMiddleware of the web api presentation project.
Before writing this question, we already hat a look at another article on stackoverflow:
ASP.NET MVC Core 3.0 - Why API Request from body keeps returning !ModelState.IsValid?
But we already had the request.Body.Seek(0, SeekOrigin.Begin); in our code. So, we thought that's it and it couldn't be the problem.
But now, we've found this article:
.net core 3.0 logging middleware by pipereader
Instead of reading the request body like this:
await request.Body.ReadAsync(buffer, 0, buffer.Length);
... where the stream is closed after read, we're using now the BodyReader as a stream and leave the stream open:
var stream = request.BodyReader.AsStream(true); // AsStream(true) to let stream open
await stream.ReadAsync(buffer, 0, buffer.Length);
request.Body.Seek(0, SeekOrigin.Begin);

Debugging async controller with async service inside

It's MVC project. I've started making some heavy calls to remote api async, but I am having problems debugging this code, because it is not entering breakpoint after await. I am still learning the async/await. GetSearchResults method in used in ajax requests on frontend. Application is hosted in IIS.
Here is my controller:
[HttpGet]
public async Task<ActionResult> GetSearchResults(SearchRequest searchModel)
{
var result = await _apiSearchService.SearchAsync(searchModel);
return Json(result, JsonRequestBehavior.AllowGet);
}
And here is my method inside service:
public async Task<Search> SearchAsync(SearchRequest searchRequest)
{
var requestUrl = "api/search";
var request = new NewtonsoftRestRequest(requestUrl, Method.GET);
/*
...assigning params
*/
var response = await _apiClient.ExecuteTaskAsync(request);
var searchResults = _apiClient.ResolveResponse<Search>(response);
return searchResults;
}
When I hit line
await _apiSearchService.SearchAsync(searchModel);
I enter SearchAsync method and after line with ExecuteTaskAsync I am leaving debugging at all and get my page hit.
var response = await _apiClient.ExecuteTaskAsync(request);
Could someone tell me how can debugging be achieved here? Also, could someone do a quick code review, if I am using async/await well? Also maybe I should use Task.Run() ? Going deeper is really getting more and more confusing.
Thanks!
The problem was unhandled exception in my method. Thanks #bommelding

How to acquire HttpStatus Codes in ASP.Net Core?

I'm running through a list of both secure and unsecured domains (both http:// and https://) in an array and wish to return their status codes. How is this possible in ASP.Net Core 1.0?
so far, I have
foreach(var item in _context.URLs.ToList())
{
// Do something here with item.Domain to check for status
// For example, if item.Domain was https://example.com..
}
I tried it with regular ASP.Net syntax with this approach:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(item.Domain);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
The problem is, GetResponse doesn't work in ASP.Net Core
Can anyone help me out with an effecient solution so that the variable returned would be the status?
ex: 200, 500, 404..
EDIT - Here is my full controller AND SOLUTION:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using MyApp.Models;
using System.Threading.Tasks;
using System.Net;
using System.Net.Http;
namespace MyApp.Controllers.Api
{
public class URLsController : Controller
{
private MyAppDBContext _context;
public class newLink
{
public string Domain { get; set; }
public HttpStatusCode Status { get; set; }
}
public async Task<HttpStatusCode> GetStatusCodes(string url)
{
var client = new HttpClient();
var response = await client.GetAsync(url);
return response.StatusCode;
}
public URLsController(MyAppDBContext context)
{
_context = context;
}
[HttpPost("api/URLs")]
public async Task<IActionResult> Post(string url)
{
if (url != "")
{
// I pass a URL in through this API and add it to _context.URLs..
// I execute a status code check on the URLs after this if statement
}
List<newLink> list = new List<newLink> ();
foreach (var item in _context.URLs.ToList())
{
newLink t = new newLink();
t.Domain = item.Domain;
t.Status = await GetStatusCodes(item.Domain);
list.Add(t);
}
return Ok(list);
}
}
}
This returns an array back in this format:
[{"Domain":"https://example1.com/","Status":200},
{"Domain":"https://example2.com/","Status":200},
{"Domain":"https://example3.com/","Status":200}]
You could use HttpClient as it is easier to work with (you don't need to catch WebExceptions for the non success status codes like you would have to do with the plain HttpWebRequest and then extract the HTTP status code from the exception).
You could write a helper method that given a list of urls will return a list of corresponding status codes. This will make your code a little bit more decoupled. Do not violate the single responsibility principle. A method should not do more than 1 specific thing (in your example you were mixing some DB calls and HTTP calls into a single method which is bad practice).
public async Task<IList<HttpStatusCode>> GetStatusCodes(IList<string> urls)
{
var client = new HttpClient();
var result = new List<HttpStatusCode>();
foreach (var url in urls)
{
var response = await client.GetAsync(url);
result.Add(response.StatusCode);
}
return result;
}
Remark 1: If the url that you are trying to call is not DNS resolvable or your calling application doesn't have network access to the specified address on the target port you will not get any status code for obvious reasons. You will get a nice exception. Think about handling this case. It's up to you to decide what you want to return in the resulting collection in this case.
Remark 2: Making a GET request just for determining the HTTP status code might be a waste as you are throwing away the response body that you have already transported over the wire. If the remote resource responds to HEAD requests that might be more efficient way to determine if the server is alive. But consider this with caution as it will depend on the specifics of the web endpoint that you are calling.
Remark 3: You have undoubtedly noticed that this method is async. Well, if you intend to develop under .NET Core you'd better get accustomed to it. You could of course violate the built-in asynchronous patterns that the framework provides you by blocking the calling thread:
var urls = _context.URLs.ToList();
IList<HttpStatusCode> statusCodes = GetStatusCodes(urls).GetAwaiter().GetResult();
But this is an extremely bad practice. A more idiomatic way of working is to make all your methods asynchronous through the entire chain until you reach the main calling method which is usually provided by the framework itself and which can be asynchronous as well. For example if you are calling this inside a Web API action you could simply make it async:
[HttpGet]
[Route("api/foos")]
public async Task<IActionResult> Get()
{
var urls = _context.URLs.ToList();
IList<HttpStatusCode> statusCodes = await GetStatusCodes(urls);
return this.Ok(statusCodes);
}

WebException on HTTP request while debugging

I have a ASP.NET project which involves sending HTTP requests via the Web-API Framework. The following exception is only raised when debugging:
The server committed a protocol violation. Section=ResponseStatusLine
The project runs perfectly if I "Start Without Debugging".
How should I resolve this exception?
Any help is appreciated!
Update
The problem seems related to the ASP.NET MVC Identity Framework.
To access other Web-API methods, the client application has to first POST a login request (The login request does not need to be secure yet, and so I am sending the username and password strings directly to the Web-API POST method). If I comment out the login request, no more exception is raised.
Below are the relevant code snippets:
The Post method:
UserManager<ApplicationUser> UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
AccountAccess ac = new AccountAccess();
public async Task<HttpResponseMessage> Post()
{
string result = await Request.Content.ReadAsStringAsync();
LoginMessage msg = JsonConvert.DeserializeObject<LoginMessage>(result);
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
var user = UserManager.Find(msg.username, msg.password);
if (user == null)
return response;
if (user.Roles == null)
return response;
var role = from r in user.Roles where (r.RoleId == "1" || r.RoleId == "2") select r;
if (role.Count() == 0)
{
return response;
}
bool task = await ac.LoginAsync(msg.username, msg.password);
response.Content = new StringContent(task.ToString());
return response;
}
The Account Access class (simulating the default AccountController in MVC template):
public class AccountAccess
{
public static bool success = false;
public AccountAccess()
: this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
{
}
public AccountAccess(UserManager<ApplicationUser> userManager)
{
UserManager = userManager;
}
public UserManager<ApplicationUser> UserManager { get; private set; }
public async Task<bool> LoginAsync(string username, string password)
{
var user = await UserManager.FindAsync(username, password);
if (user != null)
{
await SignInAsync(user, isPersistent: false);
return true;
}
else
{
return false;
}
}
~AccountAccess()
{
if (UserManager != null)
{
UserManager.Dispose();
UserManager = null;
}
}
private IAuthenticationManager AuthenticationManager
{
get
{
return HttpContext.Current.GetOwinContext().Authentication;
}
}
private async Task SignInAsync(ApplicationUser user, bool isPersistent)
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}
}
Below are the relevant code snippets:
In client application:
public static async Task<List<T>> getItemAsync<T>(string urlAction)
{
message = new HttpRequestMessage();
message.Method = HttpMethod.Get;
message.RequestUri = new Uri(urlBase + urlAction);
HttpResponseMessage response = await client.SendAsync(message);
string result = await response.Content.ReadAsStringAsync();
List<T> msgs = JsonConvert.DeserializeObject<List<T>>(result);
return msgs;
}
In Web-API controller:
public HttpResponseMessage Get(string id)
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
if (id == "ItemA")
{
List<ItemAMessage> msgs = new List<ItemAMessage>();
// some code...
response.Content = new StringContent(JsonConvert.SerializeObject(msgs));
}
else if (id == "ItemB")
{
List<ItemBMessage> msgs = new List<ItemBMessage>();
// some code...
response.Content = new StringContent(JsonConvert.SerializeObject(msgs));
}
return response;
}
Some observations I have:
I thought that I may need to send the request asynchronously (with the async-await syntax), but the exception still persists that way.
If I step through the code, the request does enter the HTTP method, but the code breaks at random line (Why?!) before returning the response, so I assume no response is being sent back.
I have tried the following solutions, as suggested in answers to similar questions, none of which works for me:
Setting useUnsafeHeaderParsing to true
Adding the header Keep-Alive: false
Changing the port setting of Skype (I don't have Skype, and port 80 and 443 are not occupied)
Additional information, in case they matter:
Mac OS running Windows 8.1 with VMware Fusion
Visual Studio 2013
.NET Framework 4.5
IIS Express Server
Update 2
The exception is resolved, but I am unsure of which modification did the trick. AFAIK, either one or both of the following fixed it:
I have a checkConnection() method, which basically sends a GET request and return true on success. I added await to the HttpClient.SendAsync() method and enforced async all the way up.
I retracted all code in the MainWindow constructor, except for the InitializeComponent() method, into the Window Initialized event handler.
Any idea?
Below are relevant code to the modifications illustrated above:
the checkConnectionAsync method:
public static async Task<bool> checkConnectionAsync()
{
message = new HttpRequestMessage();
message.Method = HttpMethod.Get;
message.RequestUri = new Uri(urlBase);
try
{
HttpResponseMessage response = await client.SendAsync(message);
return (response.IsSuccessStatusCode);
}
catch (AggregateException)
{
return false;
}
}
Window Initialized event handler (retracted from the MainWindow constructor):
private async void Window_Initialized(object sender, EventArgs e)
{
if (await checkConnectionAsync())
{
await loggingIn();
getItemA();
getItemB();
}
else
{
logMsg.Content = "Connection Lost. Restart GUI and try again.";
}
}
Update 3
Although this may be a little off-topic, I'd like to add a side note in case anyone else falls into this – I have been using the wrong authentication approach for Web-API to start with. The Web-API project template already has a built-in Identity framework, and I somehow "replaced" it with a rather simple yet broken approach...
This video is a nice tutorial to start with.
This article provides a more comprehensive explanation.
In the Client Application you are not awaiting task. Accessing Result without awaiting may cause unpredictable errors. If it only fails during Debug mode, I can't say for sure, but it certainly isn't the same program (extra checks added, optimizations generally not enabled). Regardless of when Debugging is active, if you have a code error, you should fix that and it should work in either modes.
So either make that function async and call the task with the await modifier, or call task.WaitAndUnwrapException() on the task so it will block synchronously until the result is returned from the server.
Make sure URL has ID query string with value either as Item A or Item B. Otherwise, you will be returning no content with Http status code 200 which could lead to protocol violation.
When you use SendAsync, you are required to provide all relevant message headers yourself, including message.Headers.Authorization = new AuthenticationHeaderValue("Basic", token); for example.
You might want to use GetAsync instead (and call a specific get method on the server).
Also, are you sure the exception is resolved? If you have some high level async method that returns a Task and not void, that exception might be silently ignored.

Categories

Resources