I keep getting a Newtonsoft.Json.JsonReaderException that says "Input string '0.64' is not a valid integer. I can't figure out how to fix the issue. I am following a C# tutorial on Treehouse, but it is from a few years ago and the instructions are outdated.
I am trying to use the Azure Cognitive Services Text Sentiment Analysis API.
ETA: NewsResult
class (added at end)
Here is my main method file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Newtonsoft.Json;
using System.Net;
using System.Net.Http.Headers;
using System.Net.Http;
namespace SoccerStats
{
class Program
{
static void Main(string[] args)
{
string currentDirectory = Directory.GetCurrentDirectory();
DirectoryInfo directory = new DirectoryInfo(currentDirectory);
var fileName = Path.Combine(directory.FullName, "SoccerGameResults.csv");
var fileContents = ReadSoccerResults(fileName);
fileName = Path.Combine(directory.FullName, "players.json");
var players = DeserializePlayers(fileName);
var topTenPlayers = GetTopTenPlayers(players);
foreach (var player in topTenPlayers)
{
var playerName = $"{player.FirstName} {player.SecondName}";
Console.WriteLine(playerName);
List<NewsResult> newsResults = GetNewsForPlayer(string.Format("{0} {1}", player.FirstName, player.SecondName));
SentimentResponse sentimentResponse = GetSentimentResponse(newsResults);
foreach (var sentiment in sentimentResponse.Docs)
{
foreach (var result in newsResults)
{
if (result.Headline == sentiment.Id)
{
double score;
if (double.TryParse(sentiment.Sentiment, out score))
{
result.SentimentScore = score;
}
break;
}
}
}
foreach (var result in newsResults)
{
Console.WriteLine(string.Format("Sentiment Score: {0} Date: {1:f}, Headline: {2}, Summary: {3} \r\n", result.SentimentScore, result.DatePublished, result.Headline, result.Summary));
Console.ReadKey();
}
}
fileName = Path.Combine(directory.FullName, "topten.json");
SerializePlayersToFile(topTenPlayers, fileName);
}
public static string ReadFile(string fileName)
{
using (var reader = new StreamReader(fileName))
{
return reader.ReadToEnd();
}
}
public static List<GameResult> ReadSoccerResults(string fileName)
{
var soccerResults = new List<GameResult>();
using (var reader = new StreamReader(fileName))
{
string line = "";
reader.ReadLine();
while ((line = reader.ReadLine()) != null)
{
var gameResult = new GameResult();
string[] values = line.Split(',');
DateTime gameDate;
if (DateTime.TryParse(values[0], out gameDate))
{
gameResult.GameDate = gameDate;
}
gameResult.TeamName = values[1];
HomeOrAway homeOrAway;
if (Enum.TryParse(values[2], out homeOrAway))
{
gameResult.HomeOrAway = homeOrAway;
}
int parseInt;
if (int.TryParse(values[3], out parseInt))
{
gameResult.Goals = parseInt;
}
if (int.TryParse(values[4], out parseInt))
{
gameResult.GoalAttempts = parseInt;
}
if (int.TryParse(values[5], out parseInt))
{
gameResult.ShotsOnGoal = parseInt;
}
if (int.TryParse(values[6], out parseInt))
{
gameResult.ShotsOnGoal = parseInt;
}
double possessionPercent;
if (double.TryParse(values[7], out possessionPercent))
{
gameResult.PosessionPercent = possessionPercent;
}
soccerResults.Add(gameResult);
}
}
return soccerResults;
}
public static List<Player> DeserializePlayers(string fileName)
{
var players = new List<Player>();
var serializer = new JsonSerializer();
using (var reader = new StreamReader(fileName))
using (var jsonReader = new JsonTextReader(reader))
{
players = serializer.Deserialize<List<Player>>(jsonReader);
}
return players;
}
public static List<Player> GetTopTenPlayers(List<Player> players)
{
var topTenPlayers = new List<Player>();
players.Sort(new PlayerComparer());
int counter = 0;
foreach (var player in players)
{
topTenPlayers.Add(player);
counter ;
if (counter == 10)
break;
}
return topTenPlayers;
}
public static void SerializePlayersToFile(List<Player> players, string fileName)
{
var serializer = new JsonSerializer();
using (var writer = new StreamWriter(fileName))
using (var jsonWriter = new JsonTextWriter(writer))
{
serializer.Serialize(jsonWriter, players);
}
}
public static string GetGoogleHomePage()
{
using (var webClient = new WebClient())
{
byte[] googleHome = webClient.DownloadData("https://www.google.com");
using (var stream = new MemoryStream(googleHome))
using (var reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
}
public static List<NewsResult> GetNewsForPlayer(string playerName)
{
var results = new List<NewsResult>();
using var webClient = new WebClient();
webClient.Headers.Add("Ocp-Apim-Subscription-Key", "#####");
byte[] searchResults = webClient.DownloadData(string.Format("https://api.bing.microsoft.com/v7.0/news/search?q={0}&mkt-en-us", playerName));
var serializer = new JsonSerializer();
using (var stream = new MemoryStream(searchResults))
using (var reader = new StreamReader(stream))
using (var jsonReader = new JsonTextReader(reader))
{
results = serializer.Deserialize<NewsSearch>(jsonReader).NewsResults;
}
return results;
}
public static SentimentResponse GetSentimentResponse(List<NewsResult> newsResults)
{
var sentimentResponse = new SentimentResponse();
var sentimentRequest = new SentimentRequest();
sentimentRequest.Documents = new List<Document>();
foreach (var result in newsResults)
{
sentimentRequest.Documents.Add(new Document { Id = result.Headline, Text = result.Summary });
}
using var webClient = new WebClient();
webClient.Headers.Add("Ocp-Apim-Subscription-Key", "########");
webClient.Headers.Add(HttpRequestHeader.ContentType, "application/json");
string requestJson = JsonConvert.SerializeObject(sentimentRequest);
byte[] requestBytes = Encoding.UTF8.GetBytes(requestJson);
byte[] response = webClient.UploadData("https://<endpoint>.cognitiveservices.azure.com/text/analytics/v3.1/sentiment", requestBytes);
string sentiments = Encoding.UTF8.GetString(response);
sentimentResponse = JsonConvert.DeserializeObject<SentimentResponse>(sentiments);
return sentimentResponse;
}
}
}
Here is my SentimentResponse class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace SoccerStats
{
// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
public class ConfidenceScores
{
[JsonProperty("negative")]
public int Negative { get; set; }
[JsonProperty("neutral")]
public int Neutral { get; set; }
[JsonProperty("positive")]
public int Positive { get; set; }
}
public class Relation
{
[JsonProperty("ref")]
public string Ref { get; set; }
[JsonProperty("relationType")]
public string RelationType { get; set; }
}
public class Target
{
[JsonProperty("confidenceScores")]
public ConfidenceScores ConfidenceScores { get; set; }
[JsonProperty("length")]
public int Length { get; set; }
[JsonProperty("offset")]
public int Offset { get; set; }
[JsonProperty("relations")]
public List<Relation> Relations { get; set; }
[JsonProperty("sentiment")]
public string Sentiment { get; set; }
[JsonProperty("text")]
public string Text { get; set; }
}
public class Assessment
{
[JsonProperty("confidenceScores")]
public ConfidenceScores ConfidenceScores { get; set; }
[JsonProperty("isNegated")]
public bool IsNegated { get; set; }
[JsonProperty("length")]
public int Length { get; set; }
[JsonProperty("offset")]
public int Offset { get; set; }
[JsonProperty("sentiment")]
public string Sentiment { get; set; }
[JsonProperty("text")]
public string Text { get; set; }
}
public class Sentence
{
[JsonProperty("targets")]
public List<Target> Targets { get; set; }
[JsonProperty("confidenceScores")]
public ConfidenceScores ConfidenceScores { get; set; }
[JsonProperty("length")]
public int Length { get; set; }
[JsonProperty("offset")]
public int Offset { get; set; }
[JsonProperty("assessments")]
public List<Assessment> Assessments { get; set; }
[JsonProperty("sentiment")]
public string Sentiment { get; set; }
[JsonProperty("text")]
public string Text { get; set; }
}
public class Doc
{
[JsonProperty("confidenceScores")]
public ConfidenceScores ConfidenceScores { get; set; }
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("sentences")]
public List<Sentence> Sentences { get; set; }
[JsonProperty("sentiment")]
public string Sentiment { get; set; }
[JsonProperty("warnings")]
public List<object> Warnings { get; set; }
}
public class SentimentResponse
{
[JsonProperty("documents")]
public List<Doc> Docs { get; set; }
[JsonProperty("errors")]
public List<object> Errors { get; set; }
[JsonProperty("modelVersion")]
public string ModelVersion { get; set; }
}
}
According to the Azure Cognitive Services docs, the Text Sentiment Analysis API should be returning the following JSON response:
{
"documents": [
{
"confidenceScores": {
"negative": 0,
"neutral": 0,
"positive": 1
},
"id": "1",
"sentences": [
{
"targets": [
{
"confidenceScores": {
"negative": 0,
"positive": 1
},
"length": 10,
"offset": 6,
"relations": [
{
"ref": "#/documents/0/sentences/0/assessments/0",
"relationType": "assessment"
}
],
"sentiment": "positive",
"text": "atmosphere"
}
],
"confidenceScores": {
"negative": 0,
"neutral": 0,
"positive": 1
},
"length": 17,
"offset": 0,
"assessments": [
{
"confidenceScores": {
"negative": 0,
"positive": 1
},
"isNegated": false,
"length": 5,
"offset": 0,
"sentiment": "positive",
"text": "great"
}
],
"sentiment": "positive",
"text": "Great atmosphere."
},
{
"targets": [
{
"confidenceScores": {
"negative": 0.01,
"positive": 0.99
},
"length": 11,
"offset": 37,
"relations": [
{
"ref": "#/documents/0/sentences/1/assessments/0",
"relationType": "assessment"
}
],
"sentiment": "positive",
"text": "restaurants"
},
{
"confidenceScores": {
"negative": 0.01,
"positive": 0.99
},
"length": 6,
"offset": 50,
"relations": [
{
"ref": "#/documents/0/sentences/1/assessments/0",
"relationType": "assessment"
}
],
"sentiment": "positive",
"text": "hotels"
}
],
"confidenceScores": {
"negative": 0.01,
"neutral": 0.86,
"positive": 0.13
},
"length": 52,
"offset": 18,
"assessments": [
{
"confidenceScores": {
"negative": 0.01,
"positive": 0.99
},
"isNegated": false,
"length": 15,
"offset": 18,
"sentiment": "positive",
"text": "Close to plenty"
}
],
"sentiment": "neutral",
"text": "Close to plenty of restaurants, hotels, and transit!"
}
],
"sentiment": "positive",
"warnings": []
}
],
"errors": [],
"modelVersion": "2020-04-01"
}
Here is my NewsSearch class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace SoccerStats
{
// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
public class QueryContext
{
[JsonProperty("originalQuery")]
public string OriginalQuery { get; set; }
[JsonProperty("adultIntent")]
public bool AdultIntent { get; set; }
}
public class Sort
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("isSelected")]
public bool IsSelected { get; set; }
[JsonProperty("url")]
public string Url { get; set; }
}
public class Thumbnail
{
[JsonProperty("contentUrl")]
public string ContentUrl { get; set; }
[JsonProperty("width")]
public int Width { get; set; }
[JsonProperty("height")]
public int Height { get; set; }
}
public class Image
{
[JsonProperty("thumbnail")]
public Thumbnail Thumbnail { get; set; }
}
public class Provider
{
[JsonProperty("_type")]
public string Type { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("image")]
public Image Image { get; set; }
}
public class About
{
[JsonProperty("readLink")]
public string ReadLink { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
}
public class Mention
{
[JsonProperty("name")]
public string Name { get; set; }
}
public class NewsResult
{
[JsonProperty("name")]
public string Headline { get; set; }
[JsonProperty("url")]
public string Url { get; set; }
[JsonProperty("description")]
public string Summary { get; set; }
[JsonProperty("provider")]
public List<Provider> Provider { get; set; }
[JsonProperty("datePublished")]
public DateTime DatePublished { get; set; }
[JsonProperty("about")]
public List<About> About { get; set; }
[JsonProperty("category")]
public string Category { get; set; }
[JsonProperty("image")]
public Image Image { get; set; }
[JsonProperty("mentions")]
public List<Mention> Mentions { get; set; }
public string Sentiment { get; set; }
}
public class NewsSearch
{
[JsonProperty("_type")]
public string Type { get; set; }
[JsonProperty("readLink")]
public string ReadLink { get; set; }
[JsonProperty("queryContext")]
public QueryContext QueryContext { get; set; }
[JsonProperty("totalEstimatedMatches")]
public int TotalEstimatedMatches { get; set; }
[JsonProperty("sort")]
public List<Sort> Sort { get; set; }
[JsonProperty("value")]
public List<NewsResult> NewsResults { get; set; }
}
}
CodePudding user response:
fix ConfidenceScores class
public class ConfidenceScores
{
[JsonProperty("negative")]
public double Negative { get; set; }
[JsonProperty("neutral")]
public double Neutral { get; set; }
[JsonProperty("positive")]
public double Positive { get; set; }
}
and I can see this code that looks as a bug for me
if (result.Headline == sentiment.Id)
{
double score;
if (double.TryParse(sentiment.Sentiment, out score))
{
result.SentimentScore = score;
}
break;
}
sentiment is a string "positive" and you can not convert it to double. You will always have a default value 0;
you can try this
if (result.Headline == sentiment.Id)
{
if (sentiment.Sentiment=="positive")
result.SentimentScore = sentiment.ConfidenceScores.Positive;
else if (sentiment.Sentiment=="negative")
result.SentimentScore = sentiment.ConfidenceScores.Negative;
else result.SentimentScore = sentiment.ConfidenceScores.Neutral;
break;
}
and change Sentiment of NewsResult
public class NewsResult
{
.....
public double SentimentScore { get; set; }
}