NewtonSoft json converter "unterminated String, expected separator:"; "

I am trying to parse the json response that I get when I call the API to relax. The problem I am facing is that deserialization does not work every time, although I am making the same request. I do not know how to fix this, since try.catch does nothing better.

In addition, when I try to parse a very large answer (20+ json objects), the program never works.

I have a problem with googled myself, but I don't know a solution.

Unterminated string. Expected delimiter: "Path" drink [0] .strMeasure4 ', line 3, position 720.

- one of the mistakes that I get, it is never the same.

using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using ConsoleApplication1; namespace TCPclient { class Program { static void Main(string[] args) { TcpClient client = new TcpClient(); client.Connect("www.thecocktaildb.com", 80); // geen http string request = getRequestCoctail("margarita"); NetworkStream stream = client.GetStream(); byte[] buffer = Encoding.Default.GetBytes(request); stream.Write(buffer, 0, buffer.Length); StringBuilder message = new StringBuilder(); int numberOfBytesRead = 0; byte[] receiveBuffer = new byte[1024]; do { numberOfBytesRead = stream.Read(receiveBuffer, 0, receiveBuffer.Length); message.AppendFormat("{0}", Encoding.ASCII.GetString(receiveBuffer, 0, numberOfBytesRead)); } while (stream.DataAvailable); string response = message.ToString(); //Console.WriteLine("Response: \n" + response); response = response.Substring(response.IndexOf("\r\n\r\n")); try { dynamic jsonData = JsonConvert.DeserializeObject(response); List<Drink> drankjes = new List<Drink>(); for (int i = 0; i < jsonData.drinks.Count; i++) { try { string id = jsonData.drinks[i].idDrink; string drink = jsonData.drinks[i].strDrink; string category = jsonData.drinks[i].strCategory; string instructions = jsonData.drinks[i].strInstructions; string glass = jsonData.drinks[i].strGlass; Console.WriteLine(glass); var d = new Drink(id, drink, category, instructions); drankjes.Add(d); } catch (Exception) { Console.WriteLine("error"); } } } catch (Exception e) { Console.WriteLine(e.Message); } //Console.WriteLine(jsonData.drinks.Count); //Console.WriteLine(jsonData.drinks.Count); get ammount of drinks. Console.ReadKey(); } //www.thecocktaildb.com/api/json/v1/1/lookup.php?i=15679 private static string getRequestCoctail(string coctail) { ///api/json/v1/1/search.php?s=margarita return $"GET /api/json/v1/1/search.php?s=godfather HTTP/1.1\r\n" + "Host: www.thecocktaildb.com\r\n\r\n"; } private static string GetMetaDataCocktail(dynamic jsonData) { dynamic drink = jsonData.drinks[0]; return $"DrinkID : {drink.idDrink} \nDrinkName : {drink.strDrink} \nInstructions : {drink.strInstructions}"; } private static Drink GenerateNewDrink(dynamic jsonData) { Console.WriteLine(jsonData.idDrink, jsonData.strDrink, jsonData.strCategory, jsonData.strInstructions); return new Drink(jsonData.idDrink, jsonData.strDrink, jsonData.strCategory, "", jsonData.strInstructions); } } } 

edit:

I added a drink class:

 class Drink { public readonly string drinkId; public readonly string strDrink; public readonly string strCategory; public readonly string strInstructions; public readonly string strGlass; public Drink(string drinkId, string strDrink, string strCategory, string strInstructions) { this.drinkId = drinkId; this.strDrink = strDrink; this.strCategory = strCategory; this.strInstructions = strInstructions; } public Drink(string drinkId, string strDrink, string strCategory, string strGlass, string strInstructions) { this.drinkId = drinkId; this.strDrink = strDrink; this.strCategory = strCategory; this.strGlass = strGlass; this.strInstructions = strInstructions; } } } 

I tried:

http://www.thecocktaildb.com/api/json/v1/1/search.php?s=godfather

it went well 5 times, then i got this + json error i got. for the 6th time it was good.

http://pastebin.com/c0d29L0S (better format than insert below)

Unexpected end while deserializing an object. Path 'drinks [1] .strIngredient1', line 3, position 1243.

 {"drinks":[ {"idDrink":"11423", "strDrink":"Godfather", "strCategory":"Ordinary Drink", "strAlcoholic":"Alcoholic", "strGlass":"Old-fashioned glass", "strInstructions":"Pour ingredients into an old-fashioned glass over ice and serve. (Bourbon may be substituted for scotch, if preferred.)", "strDrinkThumb":null, "strIngredient1":"Scotch", "strIngredient2":"Amaretto", "strIngredient3":"", "strIngredient4":"", "strIngredient5":"", "strIngredient6":"", "strIngredient7":"", "strIngredient8":"", "strIngredient9":"", "strIngredient10":"", "strIngredient11":"", "strIngredient12":"", "strIngredient13":"", "strIngredient14":"", "strIngredient15":"", "strMeasure1":"1 1\/2 oz ", "strMeasure2":"3\/4 oz ", "strMeasure3":" ", "strMeasure4":" ", "strMeasure5":" ", "strMeasure6":" ", "strMeasure7":" ", "strMeasure8":"", "strMeasure9":"", "strMeasure10":"", "strMeasure11":"", "strMeasure12":"", "strMeasure13":"", "strMeasure14":"", "strMeasure15":"", "dateModified":null }, {"idDrink":"11538", "strDrink":"JR Godfather", "strCategory":"Ordinary Drink", "strAlcoholic":"Alcoholic", "strGlass":"Old-fashioned glass", "strInstructions":"In an old-fashioned glass almost filled with ice cubes, combine both of the ingredients. Stir to mix the flavors.", "strDrinkThumb":null, "strIngredient1": 

I understand why this is happening incorrectly right now, JSON is invalid, but this is the answer I received. Therefore, the code that I use to get the answer is incorrect. Right?

edit 3:

same request, good JSON response:

http://pastebin.com/e3WNxz0W

Now the program works, but it is incompatible.

+6
source share
3 answers

I assume the actual problem is that you are not evaluating the HTTP response headers.

The result is most likely sent in batches, i.e. the transmission encoding is "chunked", but your naive reader will only get the first piece and use it, rather than waiting anymore. This can change between requests (for example, using direct transfer, unmarked after caching, or vice versa). Therefore, in the end, do not reinvent the wheel, just use WebClient .

Read RFC 3.6.1 section:

3.6.1 Channel translation coding

Code coding changes the body of the message to transmit it as a series of pieces, each with its own size indicator, followed by an EXTRA trailer containing the object header fields. This allows you to transfer dynamically generated content along with the information needed by the recipient to verify that she received the full message.


When you encounter such a problem, try splitting your code into smaller parts and see if these details give the expected results.

In your case, your HTTP download clearly looks incomplete, so you cannot blame the JSON parser for spitting out errors (because they are valid).

+3
source

I reproduced your exception with the following unit test

 using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using NUnit.Framework; //using ConsoleApplication1; namespace TCPclient { [TestFixture] public class Program { [Test] public void Main1() { string response = GetCoctailString(); try { dynamic jsonData = JsonConvert.DeserializeObject(response); List<Drink> drankjes = new List<Drink>(); for (int i = 0; i < jsonData.drinks.Count; i++) { try { string id = jsonData.drinks[i].idDrink; string drink = jsonData.drinks[i].strDrink; string category = jsonData.drinks[i].strCategory; string instructions = jsonData.drinks[i].strInstructions; string glass = jsonData.drinks[i].strGlass; Console.WriteLine(glass); var d = new Drink(id, drink, category, instructions); drankjes.Add(d); } catch (Exception) { Console.WriteLine("error"); } } } catch (Exception e) { Console.WriteLine(e.Message); } Console.ReadKey(); } private static string GetCoctailString() { return "{ 'drinks':[{'idDrink':'15679','strDrink':'Midori Margarita','strCategory':'Ordinary Drink','strAlcoholic':'Alcoholic','strGlass':'Cocktail glass','strInstructions':'Moisten rim of cocktail glass with lime juice and dip in salt. Shake ingredients together, and pour into glass filled with crushed ice. Option: Mix above ingredients with one cup of ice in blender for a smooth, \"granita\" type drink.','strDrinkThumb':null,'strIngredient1':'Tequila','strIngredient2':'Triple sec','strIngredient3':'Lime juice','strIngredient4':'Midori melon liqueur','strIngredient5':'Salt','strIngredient6':'','strIngredient7':'','strIngredient8':'','strIngredient9':'','strIngredient10':'','strIngredient11':'','strIngredient12':'','strIngredient13':'','strIngredient14':'','strIngredient15':'','strMeasure1':'1 1/2 oz ','strMeasure2':'1/2 oz ','strMeasure3':'1 oz fresh ','strMeasure4':'1/2 oz ','strMeasure5':'\n','strMeasure6':'\n','strMeasure7':'\n','strMeasure8':'\n','strMeasure9':'\n','strMeasure10':'\n','strMeasure11':'','strMeasure12':'','strMeasure13':'','strMeasure14':'','strMeasure15':'','dateModified':null}]}"; } } internal class Drink { public Drink(string idDrink, string strDrink, string strCategory, string strInstructions){} public string idDrink { get; set; } public string strDrink { get; set; } public string strCategory { get; set; } public string empty { get; set; } public string strInstructions { get; set; } } } 

I have a value from the site you mentioned ( http://www.thecocktaildb.com/api/json/v1/1/lookup.php?i=15679 ) it seems that JSON is not valid even after changing the text "granite" To have different quotes, everything worked!

The manual string modification I created is similar:

 response = response.Replace("\"", "\\\""); 
+1
source

I reproduced your code with some minor changes, and it works great as far as I can tell. Pay attention to using using statements, which are good practice when using IDisposable objects and how to create an object (I used the wonderful json2csharp for it):

 internal class Program { private static void Main(string[] args) { RootObject root = new RootObject(); using (WebClient wc = new WebClient()) { var json = wc.DownloadString("http://www.thecocktaildb.com/api/json/v1/1/search.php?s=margarita"); root = JsonConvert.DeserializeObject<RootObject>(json); } Console.WriteLine(root.drinks.Count); Console.ReadLine(); } } public class Drink { public string idDrink { get; set; } public string strDrink { get; set; } public string strCategory { get; set; } public string strAlcoholic { get; set; } public string strGlass { get; set; } public string strInstructions { get; set; } public object strDrinkThumb { get; set; } public string strIngredient1 { get; set; } public string strIngredient2 { get; set; } public string strIngredient3 { get; set; } public string strIngredient4 { get; set; } public string strIngredient5 { get; set; } public string strIngredient6 { get; set; } public string strIngredient7 { get; set; } public string strIngredient8 { get; set; } public string strIngredient9 { get; set; } public string strIngredient10 { get; set; } public string strIngredient11 { get; set; } public string strIngredient12 { get; set; } public string strIngredient13 { get; set; } public string strIngredient14 { get; set; } public string strIngredient15 { get; set; } public string strMeasure1 { get; set; } public string strMeasure2 { get; set; } public string strMeasure3 { get; set; } public string strMeasure4 { get; set; } public string strMeasure5 { get; set; } public string strMeasure6 { get; set; } public string strMeasure7 { get; set; } public string strMeasure8 { get; set; } public string strMeasure9 { get; set; } public string strMeasure10 { get; set; } public string strMeasure11 { get; set; } public string strMeasure12 { get; set; } public string strMeasure13 { get; set; } public string strMeasure14 { get; set; } public string strMeasure15 { get; set; } public object dateModified { get; set; } } // used http://json2csharp.com/ to get an object from the json string public class RootObject { public List<Drink> drinks { get; set; } } 
0
source

All Articles