System.Text.Json.JsonException: The input does not contain any JSON tokens - c#

I'm just trying to use a Http POST method in a Blazor app through
public async Task CreateUnit(UnitEntity unit)
{
await _http.PostJsonAsync<UnitEntity>("api/units", unit);
}
_http and myObject have been defined elsewhere, but I'm getting this weird error. Can anyone help? This is the closest thing I could find elsewhere: https://github.com/dotnet/runtime/issues/30945.
The full error message is
System.Text.Json.JsonException: 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.
And it here's the stack

Another reason this error could pop up, as it did for me, is simply because the API endpoint doesn't exist because it was misspelled.

I got a similar error in Program.cs Main method CreateHostBuilder(args).Build();:
System.FormatException: 'Could not parse the JSON file.'
JsonReaderException: The input does not contain any JSON tokens.
Expected the input to start with a valid JSON token, when isFinalBlock
is true. LineNumber: 0 | BytePositionInLine: 0.
For me it turned out to be the local secrets.json file that not contained a valid json object.
https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-5.0&tabs=windows#secret-manager
Because of this I could not see any errors in Git or rollback to a working commit since the file is not checked in.
Solved by adding an empty object to the file via Visual Studio - right click the project in solution explorer and select Manage User Secrets:
{
}
https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-5.0&tabs=windows#manage-user-secrets-with-visual-studio

In my case the code was doing this:
var json = await response.Content.ReadAsStringAsync();
var result = JsonObject.Parse(json); // threw the exception mentioned in the question
Why did that happen? That's because json value was an empty string "". Parse fails with an empty string.
Fixed it doing this simple change:
var json = await response.Content.ReadAsStringAsync();
var result = string.IsNullOrEmpty(json) ? null : JsonObject.Parse(json);

i had similar issue and the problem to check if the json string you are readying is empty, null, or bad formatted. debug to the code line where you are reading data into string before deserialize or serialize call.

I got this error when communicating between two APIs.
request = await req.DeserializeRequestBodyAsync<MyDto>(jsonSerializerOptions);
Turned out the code below did not actually send any values:
httpRequestMessage.Content = JsonContent.Create(myDto);
var httpClient = _clientFactory.CreateClient();
var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage, cancellationToken);
I had to manually specify:
await httpRequestMessage.Content.LoadIntoBufferAsync();
Like this:
httpRequestMessage.Content = JsonContent.Create(myDto);
await httpRequestMessage.Content.LoadIntoBufferAsync();
var httpClient = _clientFactory.CreateClient();
var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage, cancellationToken);

For me, this error occurred when calling FindByNameAsync of UserManager.
Sounds silly, but the database connection string in the appsettings was wrong!

Late answer - but I ran into this using Blazor WebAssembly with Browser Link (trying to get Hot Reload to work). Turns out it's an issue loading the appsettings and Browser Link was expecting the secrets file. I fixed by right clicking the Server project and copy/pasting my appsettings values into the secrets file.

In my case, I was passing the id of my object along with the object itself in the url of the put request to an API and faced the same exception. It turned out that it was not necessary to pass the id (as it was retrieved from the object itself, in fact it was not present in the method signature). Removing the id solved the problem.

This error occurred when communicating between client and web API.
API code:
public async Task<IActionResult> PostAsync(object review)
{
return Ok();
}
Client code:
var res = await _client.PostAsJsonAsync("api/reviews", review);
if (res.IsSuccessStatusCode)
{
var myObject = await res.Content.ReadFromJsonAsync<MyObject>(); //this line threw mentioned error
}
Turned out that the API endpoint was returning something different compared to what I was trying to read from JSON i.e. I was trying to read MyObject but API was returning ActionResult

In my case database column was marked not null and I was passing null in API.

Related

Properly parsing through an XML file from an HTTP request

I am using Windows Forms .NET Framework and HTTPClient for web requests. I'm able so successfully get the response message. I'm now wanting to grab a specific attribute named 'special-price' from the 'item' elements. I only care about the first instance of a 'price-attribute' in an element. The following is a snippet of the code that is returning the error.
HttpResponseMessage request = await client.GetAsync($"url");
string result = request.Content.ReadAsStringAsync().Result;
XDocument xDocument = XDocument.Parse(result);
var query = from item in xDocument.Element("inv-balance").Elements("item")
select item.Attribute("special-price");
var answer = query.First();
rtxtResult.Text = answer.ToString();`
The error I keep getting is 'Object reference not set to an instance of an object'. I'm still relatively new to C# and this is the first major roadblock that I haven't been able to get past. Thank you.

Autodesk Forge Error trying to access the API online

I have a problem loading a 3D model on an online server, the error shown is related to accessing the Forge API, locally works smoothly however when mounted on the server or a website is made marks the following error "Failed to load resource: the server responded with a status of 404 (Not Found)", then "onDocumentLoadFailure() - errorCode:7".
As I comment, what I find stranger is that, locally, it works. Attached the segment of the code where it displays the error.
function getAccessToken() {
var xmlHttp = null;
xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", '/api/forge/toke', false); //Address not found
xmlHttp.send(null);
return xmlHttp.responseText;
}
Thank you very much in advance.
Are you sure the code you're running locally and the code you've deployed are really the same?
The getAccessToken function doesn't seem to be correct, for several reasons:
First of all, there seems to be a typo in the URL - shouldn't it be /api/forge/token instead of /api/forge/toke?
More importantly, the HTTP request is asynchronous, meaning that it cannot return the response immediately after calling xmlHttp.send(). You can find more details about the usage of XMLHttpRequest in https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest.
And finally, assuming that the function is passed to Autodesk.Viewing.Initializer options, it should return the token using a callback parameter passed to it (as shown in https://forge.autodesk.com/en/docs/viewer/v7/developers_guide/viewer_basics/initialization/#example).
With that, your getAccessToken should probably look more like this (using the more modern fetch and async/await):
async function getAccessToken(callback) {
const resp = await fetch('/api/forge/token');
const json = await resp.json();
callback(json.access_token, json.expires_in);
}
I've already found the issue. When I make the deploy I have to change the url where the request is made for the public or the name of the domain. For example: mywebsite.com/aplication-name/api/forge/token.

System.AggregateException on GetStringAsync in asp.net

I am trying to call an API like this:
var client = new HttpClient();
client.DefaultRequestHeaders.Add("apiKey", Token);
**var result = await client.GetStringAsync(GetUrl($"accounts/{accountID}/menu?skip=0&limit=1"));**
var menuList = JsonConvert.DeserializeObject<List<Menu>>(result);
but getting System.AggregateException on GetStringAsync, error CS0103: The name 'InnerExceptionCount' does not exist in the current context
and Exception Message
One or more errors occurred. (Response status code does not indicate success: 404 (Not Found).)
I see that this is returned in result
Status = WaitingForActivation, Method = "{null}", Result = "{Not yet computed}
I tried to make call using postman with same url and apikey in header and I see the results.
Can you please suggest what is wrong with above code. Api key expects only an apiKey in header.
Thanks.
Anytime that an async call fails you'll get an AggregateException, what's important is the inner exception within that.
It looks like your inner exception is 404 Not Found, which means that you're not calling the correct URL.
You said it's working in postman, that's great. To find the root cause I suggest the following:
Start Fiddler
Make the call through postman, view the request in Fiddler
Make the call through your C# code, view the request in Fiddler
Comparing the Postman request against the C# request should tell you where the error is.

JsonSerializationException from TFS REST API response

I am trying to use the new TFS/VSTS REST APIs with our on-prem TFS 2015 server, and cannot retrieve test runs as the response fails internal validation.
Using client code like the following:
var connection = new VssConnection(serverUri), credentials);
var client = connection.GetClient<TestManagementHttpClient>();
var runs = await client.GetTestRunsAsync("project", planId:183110);
throws a JsonSerializationException in line 3 with the following message:
Required property 'environmentName' not found in JSON. Pathvalue[0].testEnvironment', line 1, position 582.
which is accurate. Checking the response in Fiddler shows that the testEnvironment property only has an environmentId property, no name. I have uploaded a trimmed sample of the response to this gist.
My question is why does TFS not return this value or alternatively, is there a way to force the API SDK to ignore this validation error?
I can reproduce that issue if includeRunDetails parameter is true. I reported a bug here that you can vote it.
The workaround is that you could set includeRunDetails to false to get test runs without details include, then base on the result (test run id) to get a test run with details that you want.
client.GetTestRunByIdAsync

Web API call works but gives exception The view 'xxx' or its master was not found or no view engine supports

Strange one here, code calls the method, and the method grabacat is executed on the server (I debug it and step through right to the end). The code returns to the client, but the response it received was 500 Internal Server Error with the above message. So it's saying it couldn't find the web API method that it just called successfully.
using (var response = await client.PostAsXmlAsync("cats/grabacat", mycatprefs))
{
if (response.IsSuccessStatusCode) // 500 cats/grabacat not found
Controller code:
[Route("~/api/cats/grabacat")]
[HttpPost]
public async Task GrabACat()
{
}
After debugging, if I change it to public async Task<SomeObject> GrabACat() then it works OK. This lets me return an object back to the client. However I don't want to return anything back; I want it to be equivelent to calling a void method. It will examine the status code to determine if it was successful.
I have got it working by changing GrabACat to Task and returning new object(); but I am not sure why this is required. It seems crude to return an empty object just to get it to work.
Any ideas?
The WebAPI method has a Route attribute like this:
[Route("~/api/cats/grabacat")]
Which means the URL is wrong in the POST request - you are missing the /api prefix:
using (var response = await client.PostAsXmlAsync("api/cats/grabacat", mycatprefs))
//snip

Categories