Napotkano nieoczekiwany znak podczas analizowania wartości

113

Obecnie mam kilka problemów. Używam języka C # z Json.NET. Problem w tym, że zawsze dostaję:

{"Napotkano nieoczekiwany znak podczas analizowania wartości: e. Ścieżka '', wiersz 0, pozycja 0"}

Więc sposób, w jaki używam Json.NET, jest następujący. Mam klasę, którą należy ocalić. Klasa wygląda następująco:

public class stats
{
    public string time { get; set; }
    public string value { get; set; }
}

public class ViewerStatsFormat
{
    public List<stats> viewerstats { get; set; }
    public String version { get; set; }

    public ViewerStatsFormat(bool chk)
    {
        this.viewerstats = new List<stats>();
    }
}

Jeden obiekt tej klasy zostanie wypełniony i zapisany:

 File.WriteAllText(tmpfile, JsonConvert.SerializeObject(current), Encoding.UTF8);

Część do zapisu działa poprawnie, a plik istnieje i jest wypełniony. Następnie plik zostanie wczytany z powrotem do klasy z:

    try 
{ 

    ViewerStatsFormat current = JsonConvert.DeserializeObject<ViewerStatsFormat>(tmpfile);
    //otherstuff        

}
catch(Exception ex)
{
    //error loging stuff
}

Teraz w linii current = pojawia się wyjątek:

{"Napotkano nieoczekiwany znak podczas analizowania wartości: e. Ścieżka '', wiersz 0, pozycja 0"}

Nie wiem, dlaczego tak się dzieje. Plik json jest następujący -> Kliknij mnie im łącze JSON

Czy ktoś ma jakieś pomysły?

zAfLu
źródło
2
Zmieniłem twój tytuł. Zobacz: „ Czy pytania powinny zawierać„ tagi ”w tytułach? ”, Gdzie konsensus brzmi „nie, nie powinny”.
John Saunders,
Czy zawsze masz do czynienia z tym problemem bez względu na dane? Kiedyś, gdy miałem taki problem, powodem było to, że usługa wysyłała nieprawidłowe znaki UTF-8.
ankhuri
@JohnSaunders przepraszam za to. zachowam to w moim na dalsze pytania :).
zAfLu
1
@ankhuri właśnie zapomniałem przeczytać w plikach ... moja wina
zAfLu
zakładając, że to nie jest problem, co jeszcze? recv Wyjątek-> {"topic": "robot1 / Log", "Msg": "Pilot Running"} Napotkano nieoczekiwany znak podczas analizy wartości: o. Path '', wiersz 0, pozycja 0.
Spiked3

Odpowiedzi:

149

Prawdopodobnie nie przekazujesz JSON do DeserializeObject.

Wygląda na to, ze File.WriteAllText(tmpfile,...tego typu tmpfileIs stringktóre zawierają ścieżkę do pliku. JsonConvert.DeserializeObjectprzyjmuje wartość JSON, a nie ścieżkę do pliku - więc nie udaje się przekonwertować czegoś podobnego @"c:\temp\fooo"- co oczywiście nie jest JSON.

Alexei Levenkov
źródło
75

Rozwiązałem problem za pomocą tych narzędzi online:

  1. Aby sprawdzić, czy struktura Json jest OK: http://jsonlint.com/
  2. Aby wygenerować moją klasę Object z mojej struktury Json: https://www.jsonutils.com/

Prosty kod:

RootObject rootObj= JsonConvert.DeserializeObject<RootObject>(File.ReadAllText(pathFile));
Edu Pelais
źródło
2
Jak to check if the Json structure jest w porządku w C #?
Kiquenet
1
Może tutejsi aswers mógłby pomóc: stackoverflow.com/questions/14977848/...
Edu Pelais
2
Dziękuję Ci. json2csharp.com uratowało mi życie. Używając go, możesz odtworzyć kod źródłowy do tego, jak powinna wyglądać właściwa klasa. Dzięki jeszcze raz!
Aamir
1
Link json2csharp.com już nie działa. Zamiast tego polecam korzystanie z jsonutils.com .
Stijn
Zmieniłem uszkodzony adres URL na nowy jako Twoja sugestia @Stijn.
Edu Pelais
14

Wystąpił ten sam błąd w moim rozwiązaniu Xamarin.Android.

Sprawdziłem, czy mój kod JSON jest poprawny i zauważyłem, że błąd pojawił się tylko wtedy, gdy uruchomiłem aplikację jako kompilację wydania.

Okazało się, że Linker usuwał bibliotekę z Newtonsoft.JSON, powodując niepoprawne parsowanie JSON.

Naprawiłem błąd, dodając Newtonsoft.Json do ustawienia Ignoruj ​​zestawy w konfiguracji kompilacji systemu Android (zrzut ekranu poniżej)

Kod analizy JSON

static readonly JsonSerializer _serializer = new JsonSerializer();
static readonly HttpClient _client = new HttpClient();

static async Task<T> GetDataObjectFromAPI<T>(string apiUrl)
{
    using (var stream = await _client.GetStreamAsync(apiUrl).ConfigureAwait(false))
    using (var reader = new StreamReader(stream))
    using (var json = new JsonTextReader(reader))
    {
        if (json == null)
            return default(T);

        return _serializer.Deserialize<T>(json);
    }
}

Zrzut ekranu programu Visual Studio dla komputerów Mac

wprowadź opis obrazu tutaj

Zrzut ekranu programu Visual Studio

wprowadź opis obrazu tutaj

Brandon Minnick
źródło
jak mogę to zrobić w aplikacji driod w programie Visual Studio for xamarin.forms?
Mike Darwish
1
@MikeDarwish Dodałem zrzut ekranu pokazujący, jak to zrobić w Visual Studio
Brandon Minnick
9

Napotkałem również ten błąd w przypadku akcji internetowego interfejsu API (.Net Core 3.0), która była powiązana z a stringzamiast tego z objectlub JObject. JSON był poprawny, ale spinacz próbował pobrać ciąg ze struktury JSON i nie powiodło się.

Więc zamiast:

[HttpPost("[action]")]
public object Search([FromBody] string data)

Musiałem użyć bardziej szczegółowych:

[HttpPost("[action]")]
public object Search([FromBody] JObject data)
Alexei
źródło
To mnie
załatwiło
Dla mnie też był to ból głowy, ale ma to sens, ponieważ każdy plik json jest parą klucz-wartość i powinieneś podać klasę z właściwościami jako kluczami, aby poprawnie zmapować json do instancji tej klasy
Eugene Zakharov
8

W moim przypadku plik zawierający ciąg JSON miał BOM . Po usunięciu BOM problem został rozwiązany.

wprowadź opis obrazu tutaj

Aleksei Mialkin
źródło
5

Ten problem jest związany ze znacznikiem kolejności bajtów w pliku JSON. Plik JSON nie jest kodowany jako dane kodowania UTF8 podczas zapisywania. Korzystanie z File.ReadAllText(pathFile)rozwiązania tego problemu.

Kiedy operujemy na danych Byte i konwertujemy je na łańcuch, a następnie przekazujemy do JsonConvert.DeserializeObject, możemy użyć kodowania UTF32, aby uzyskać ciąg.

byte[] docBytes = File.ReadAllBytes(filePath);

string jsonString = Encoding.UTF32.GetString(docBytes);

Praveen
źródło
3

Miałem ten sam problem z webapi w ASP.NET core, w moim przypadku było tak, ponieważ moja aplikacja wymaga uwierzytelnienia, wtedy przypisuje adnotację [AllowAnonymous]i zadziałało.

[AllowAnonymous]
public async Task <IList <IServic >> GetServices () {
        
}
Celso Xavier Luz
źródło
Spóźniłem się na imprezę w tej sprawie, ale to też był mój problem. Podczas badania „json” wchodzącego do mojej metody Deserialize wykazało, że próbuje ona uwierzytelnić się za pomocą interfejsu API.
Ben
1

Załóżmy, że to jest twój plik json

{
  "date":"11/05/2016",
  "venue": "{\"ID\":12,\"CITY\":Delhi}"
}

jeśli ponownie chcesz deserializować miejsce, zmodyfikuj json jak poniżej

{
  "date":"11/05/2016",
  "venue": "{\"ID\":\"12\",\"CITY\":\"Delhi\"}"
}

następnie spróbuj deserializacji do odpowiedniej klasy, przyjmując wartość miejsca

Hrishikesh TT
źródło
1
Cześć, używam JsonConvert.SerializeObject, który wygeneruje pierwszy wynik ode mnie, jak mogę uzyskać drugi?
user123456
To nie odpowiada na zadane pytanie.
Brian Rogers
1

W moim scenariuszu miałem nieco inny komunikat, w którym linia i pozycja nie były zerowe.

E. Ścieżka „job [0] .name”, wiersz 1, pozycja 12.

To była najlepsza odpowiedź Google na zacytowaną przeze mnie wiadomość.

Stało się tak, ponieważ wywołałem program z wiersza poleceń systemu Windows, przekazując JSON jako parametr.

Kiedy przejrzałem argumenty w moim programie, wszystkie podwójne cudzysłowy zostały usunięte. Musisz je odtworzyć.

Tutaj zamieściłem rozwiązanie . Chociaż prawdopodobnie można by go ulepszyć za pomocą Regex.

JGFMK
źródło
1

Miałem podobny błąd i pomyślałem, że odpowiem na wypadek, gdyby ktoś miał coś podobnego. Przeglądałem katalog plików json i deserializowałem je, ale otrzymywałem ten sam błąd.

Problem polegał na tym, że próbował również złapać ukryte pliki. Upewnij się, że przesyłany plik jest plikiem .json. Zgaduję, że poradzi sobie również z tekstem. Mam nadzieję że to pomoże.

Ibaeni
źródło
1

W moim przypadku otrzymywałem błąd w JsonConvert.PopulateObject () . Moja prośba zwróciła kod JSON, który został zawinięty w dodatkową parę nawiasów „[]”, dzięki czemu wynik był tablicą jednego obiektu, a nie tylko obiektu. Oto, co zrobiłem, aby dostać się do tych nawiasów (tylko dla tego typu modelu):

           T jsonResponse = new T();
                var settings = new JsonSerializerSettings
                {
                    DateParseHandling = DateParseHandling.DateTimeOffset,
                    NullValueHandling = NullValueHandling.Ignore,
                };
                var jRslt = response.Content.ReadAsStringAsync().Result;
                if (jsonResponse.GetType() == typeof(myProject.Models.myModel))
                {
                    var dobj = JsonConvert.DeserializeObject<myModel[]>(jRslt);
                    var y = dobj.First();
                    var szObj = JsonConvert.SerializeObject(y);
                    JsonConvert.PopulateObject(szObj, jsonResponse, settings);
                }
                else
                {
                    JsonConvert.PopulateObject(jRslt, jsonResponse);
                }
pkucas
źródło
1

Jeśli korzystasz z pobierania danych przy użyciu adresu URL ... może być konieczne użycie

var result = client.DownloadData(url);
Taran
źródło
0

Sprawdź, czy model udostępniany między klientem a serwerem jest taki sam. czasami pojawia się ten błąd, gdy nie zaktualizowałeś wersji Api i zwraca zaktualizowany model, ale nadal masz stary. Czasami otrzymujesz to, co serializujesz / deserializujesz, nie jest prawidłowym plikiem JSON.

Nalan Madheswaran
źródło
-1

Napotkałem podobny komunikat o błędzie w formularzach Xamarin podczas wysyłania żądania do webApi w celu uzyskania tokena,

  • Upewnij się, że wszystkie klucze ( klucz : wartość) (np. „Nazwa użytkownika”, „hasło”, „grant_type”) w pliku Json są dokładnie tym, czego oczekuje webApi, w przeciwnym razie uruchomi ten wyjątek.

Nieobsługiwany wyjątek: Newtonsoft.Json.JsonReaderException: napotkano nieoczekiwany znak podczas analizowania wartości: <. Path '', wiersz 0, pozycja 0

A. Almazidi
źródło
-3

Kiedy napotkał podobny problem, naprawiłem go przez podstawienie &mode=xmlza &mode=jsonwe wniosku.

AlfredBauer
źródło