본문으로 건너뛰기
jsonbeautifiers
한국어
C# 보고된 사례에서 메시지 문구를 옮긴 것이며, 여기서 실행하지는 않았습니다.

Unexpected character encountered while parsing value: <. Path '', line 0, position 0.

JsonConvert.DeserializeObject에 JSON 값으로 시작하지 않는 무언가가 넘어갔습니다. line 0 position 0은 맨 첫 글자에서 실패했다는 뜻입니다. 메시지에 나온 문자가 실제로 무엇을 들고 있는지 알려 줍니다.

JSON을 붙여넣고 어디서 깨지는지 정확히 확인하기

입력

붙여 넣은 것은 여러분의 브라우저를 떠나지 않습니다. connect-src 허용 목록 덕분에 이는 약속이 아니라 브라우저가 강제하는 보장입니다. 직접 확인하기

실제 원인

어느 쪽이 답인 경우가 많은지, 그 순서대로 정리했습니다.

  1. 01 파일 내용 대신 파일 경로를 넘김

    DeserializeObject가 받는 건 JSON 문자열이지 파일 이름이 아닙니다. 경로를 넘기면 파서가 C:\...를 문서로 읽고 문자 C나 슬래시에서 실패합니다. 아주 흔한 실수인데 메시지는 그 점을 전혀 암시하지 않습니다.

    깨지는 예

    var data = JsonConvert.DeserializeObject<Model>(@"C:\data\input.json");

    되는 예

    var json = File.ReadAllText(@"C:\data\input.json");
    var data = JsonConvert.DeserializeObject<Model>(json);
  2. 02 응답이 HTML

    오류 페이지, 로그인 리다이렉트, 또는 IIS 오류입니다. 메시지의 문자는 < 가 됩니다. 역직렬화 전에 본문을 문자열로 읽어 확인하세요.

    깨지는 예

    var data = JsonConvert.DeserializeObject<Model>(await res.Content.ReadAsStringAsync());

    되는 예

    var body = await res.Content.ReadAsStringAsync();
    if (!res.IsSuccessStatusCode || !body.TrimStart().StartsWith("{"))
        throw new InvalidOperationException($"{(int)res.StatusCode}: {body[..Math.Min(300, body.Length)]}");
    var data = JsonConvert.DeserializeObject<Model>(body);
  3. 03 문자열 앞의 바이트 순서 표식

    인코딩 감지기가 BOM을 떼어 내게 하지 않은 채 파일을 읽으면 JSON 앞에 U+FEFF가 남습니다.

다른 런타임에서의 같은 실수

밑바탕의 문제는 똑같고, 다른 건 문구뿐입니다. 동료가 이 중 하나를 들고 왔다면, 그 사람이 보고 있는 건 여러분이 보는 것과 같습니다.

C# (System.Text.Json) '<' is an invalid start of a value. Path: $ | LineNumber: 0 | BytePositionInLine: 0.
JavaScript (V8) Unexpected token '<', "<!DOCTYPE "... is not valid JSON

자주 묻는 질문

System.Text.Json으로 옮겨야 하나요?
.NET Core 3.0부터의 기본 선택지이고 더 빠릅니다. 다만 더 엄격하기도 합니다. 작은따옴표 문자열도, 끝쉼표도, 명시적으로 켜지 않는 한 주석도 받지 않습니다. Newtonsoft의 너그러움에 기대던 코드는 만들어 내는 쪽을 고쳐야 합니다.

지금 고치기

위의 도구에 페이로드를 붙여넣거나, 이 일을 위해 만들어진 도구로 바로 가세요.

페이로드 확인하기