Как красиво распечатать (отформатировать) System.Text.JsonElement в строку - PullRequest
3 голосов
/ 04 мая 2020

Где находится API для форматирования существующей JsonElement в форматированную строку JSON. ToString() API не предоставляет никаких параметров форматирования.

Откат к использованию Newtonsoft довольно раздражает

Newtonsoft.Json.Linq.JValue.Parse(myJsonElement.GetRawText()).ToString(Newtonsoft.Json.Formatting.Indented)

Ответы [ 3 ]

2 голосов
/ 04 мая 2020

Вы должны иметь возможность использовать такой класс расширения, если не хотите использовать json. net:

public static class JsonElementExtension
{
    private static readonly JsonWriterOptions s_indentedOptions = new JsonWriterOptions()
    {
        Indented = true
    };

    public static string ToStringIndented(this JsonElement value)
    {
        using MemoryStream stream = new MemoryStream();
        using Utf8JsonWriter writer = new Utf8JsonWriter(stream, s_indentedOptions);
        value.WriteTo(writer);
        writer.Flush();
        string indented = Encoding.UTF8.GetString(stream.GetBuffer(), 0, (int)stream.Length);

        return indented;
    }
}

Кажется, что он работает нормально, и он должен быть довольно эффективным. :)

Тест

Я не мог с собой поделать

|                 Method |           TestObj |          Mean |         Error |        StdDev |        Median |      Gen 0 |     Gen 1 |   Gen 2 |   Allocated |
|----------------------- |------------------ |--------------:|--------------:|--------------:|--------------:|-----------:|----------:|--------:|------------:|
|              IndentDbc | L | Length: 12728 |     64.677 us |     1.2955 us |     2.7327 us |     63.557 us |     9.1553 |    2.3193 |       - |    37.87 KB |
|          IndentJoelius | L | Length: 12728 |     57.765 us |     0.4019 us |     0.3563 us |     57.876 us |    23.8037 |         - |       - |    97.59 KB |
|     IndentDbcTimes1000 | L | Length: 12728 | 62,935.262 us |   580.6653 us |   543.1547 us | 63,025.312 us |  9250.0000 | 2250.0000 |       - | 37874.29 KB |
| IndentJoeliusTimes1000 | L | Length: 12728 | 58,882.179 us | 1,171.0801 us | 1,891.0761 us | 58,067.511 us | 23777.7778 |         - |       - | 97585.94 KB |
|              IndentDbc |  M | Length: 4282 |     28.480 us |     0.0503 us |     0.0393 us |     28.474 us |     4.4556 |    1.5259 |       - |    18.38 KB |
|          IndentJoelius |  M | Length: 4282 |     22.645 us |     0.1426 us |     0.1334 us |     22.678 us |     9.3384 |    0.0305 |       - |     38.3 KB |
|     IndentDbcTimes1000 |  M | Length: 4282 | 28,966.720 us |   563.5127 us |   752.2733 us | 28,607.184 us |  4468.7500 | 1468.7500 |       - |    18382 KB |
| IndentJoeliusTimes1000 |  M | Length: 4282 | 22,310.261 us |   131.5337 us |   123.0367 us | 22,322.828 us |  9343.7500 |   31.2500 |       - | 38304.69 KB |
|              IndentDbc |   S | Length: 360 |      9.929 us |     0.2096 us |     0.4468 us |      9.699 us |     1.4648 |    0.7324 |  0.0305 |     6.02 KB |
|          IndentJoelius |   S | Length: 360 |      2.375 us |     0.0138 us |     0.0129 us |      2.380 us |     1.6747 |         - |       - |     6.84 KB |
|     IndentDbcTimes1000 |   S | Length: 360 |  9,700.109 us |   190.5759 us |   187.1710 us |  9,701.489 us |  1468.7500 |  734.3750 | 31.2500 |  6017.83 KB |
| IndentJoeliusTimes1000 |   S | Length: 360 |  2,471.567 us |    48.7855 us |    74.5006 us |  2,432.958 us |  1671.8750 |         - |       - |  6843.75 KB |
Код
[MemoryDiagnoser]
public class PrettyPrintJson
{
    private const string SmallJsonString = "{\"glossary\":{\"title\":\"example glossary\",\"GlossDiv\":{\"title\":\"S\",\"GlossList\":{\"GlossEntry\":{\"ID\":\"SGML\",\"SortAs\":\"SGML\",\"GlossTerm\":\"Standard Generalized Markup Language\",\"Acronym\":\"SGML\",\"Abbrev\":\"ISO 8879:1986\",\"GlossDef\":{\"para\":\"A meta-markup language, used to create markup languages such as DocBook.\",\"GlossSeeAlso\":[\"GML\",\"XML\"]},\"GlossSee\":\"markup\"}}}}}";
    private const string MediumJsonString = "{\"web-app\":{\"servlet\":[{\"servlet-name\":\"cofaxCDS\",\"servlet-class\":\"org.cofax.cds.CDSServlet\",\"init-param\":{\"configGlossary:installationAt\":\"Philadelphia, PA\",\"configGlossary:adminEmail\":\"ksm@pobox.com\",\"configGlossary:poweredBy\":\"Cofax\",\"configGlossary:poweredByIcon\":\"/images/cofax.gif\",\"configGlossary:staticPath\":\"/content/static\",\"templateProcessorClass\":\"org.cofax.WysiwygTemplate\",\"templateLoaderClass\":\"org.cofax.FilesTemplateLoader\",\"templatePath\":\"templates\",\"templateOverridePath\":\"\",\"defaultListTemplate\":\"listTemplate.htm\",\"defaultFileTemplate\":\"articleTemplate.htm\",\"useJSP\":false,\"jspListTemplate\":\"listTemplate.jsp\",\"jspFileTemplate\":\"articleTemplate.jsp\",\"cachePackageTagsTrack\":200,\"cachePackageTagsStore\":200,\"cachePackageTagsRefresh\":60,\"cacheTemplatesTrack\":100,\"cacheTemplatesStore\":50,\"cacheTemplatesRefresh\":15,\"cachePagesTrack\":200,\"cachePagesStore\":100,\"cachePagesRefresh\":10,\"cachePagesDirtyRead\":10,\"searchEngineListTemplate\":\"forSearchEnginesList.htm\",\"searchEngineFileTemplate\":\"forSearchEngines.htm\",\"searchEngineRobotsDb\":\"WEB-INF/robots.db\",\"useDataStore\":true,\"dataStoreClass\":\"org.cofax.SqlDataStore\",\"redirectionClass\":\"org.cofax.SqlRedirection\",\"dataStoreName\":\"cofax\",\"dataStoreDriver\":\"com.microsoft.jdbc.sqlserver.SQLServerDriver\",\"dataStoreUrl\":\"jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon\",\"dataStoreUser\":\"sa\",\"dataStorePassword\":\"dataStoreTestQuery\",\"dataStoreTestQuery\":\"SET NOCOUNT ON;select test='test';\",\"dataStoreLogFile\":\"/usr/local/tomcat/logs/datastore.log\",\"dataStoreInitConns\":10,\"dataStoreMaxConns\":100,\"dataStoreConnUsageLimit\":100,\"dataStoreLogLevel\":\"debug\",\"maxUrlLength\":500}},{\"servlet-name\":\"cofaxEmail\",\"servlet-class\":\"org.cofax.cds.EmailServlet\",\"init-param\":{\"mailHost\":\"mail1\",\"mailHostOverride\":\"mail2\"}},{\"servlet-name\":\"cofaxAdmin\",\"servlet-class\":\"org.cofax.cds.AdminServlet\"},{\"servlet-name\":\"fileServlet\",\"servlet-class\":\"org.cofax.cds.FileServlet\"},{\"servlet-name\":\"cofaxTools\",\"servlet-class\":\"org.cofax.cms.CofaxToolsServlet\",\"init-param\":{\"templatePath\":\"toolstemplates/\",\"log\":1,\"logLocation\":\"/usr/local/tomcat/logs/CofaxTools.log\",\"logMaxSize\":\"\",\"dataLog\":1,\"dataLogLocation\":\"/usr/local/tomcat/logs/dataLog.log\",\"dataLogMaxSize\":\"\",\"removePageCache\":\"/content/admin/remove?cache=pages&id=\",\"removeTemplateCache\":\"/content/admin/remove?cache=templates&id=\",\"fileTransferFolder\":\"/usr/local/tomcat/webapps/content/fileTransferFolder\",\"lookInContext\":1,\"adminGroupID\":4,\"betaServer\":true}}],\"servlet-mapping\":{\"cofaxCDS\":\"/\",\"cofaxEmail\":\"/cofaxutil/aemail/*\",\"cofaxAdmin\":\"/admin/*\",\"fileServlet\":\"/static/*\",\"cofaxTools\":\"/tools/*\"},\"taglib\":{\"taglib-uri\":\"cofax.tld\",\"taglib-location\":\"/WEB-INF/tlds/cofax.tld\"},\"widgets\":[{\"widget\":{\"debug\":\"on\",\"window\":{\"title\":\"Sample Konfabulator Widget\",\"name\":\"main_window\",\"width\":500,\"height\":500},\"image\":{\"src\":\"Images/Sun.png\",\"name\":\"sun1\",\"hOffset\":250,\"vOffset\":250,\"alignment\":\"center\"},\"text\":{\"data\":\"Click Here\",\"size\":36,\"style\":\"bold\",\"name\":\"text1\",\"hOffset\":250,\"vOffset\":100,\"alignment\":\"center\",\"onMouseUp\":\"sun1.opacity = (sun1.opacity / 100) * 90;\"}}},{\"widget\":{\"debug\":\"on\",\"window\":{\"title\":\"Sample Konfabulator Widget\",\"name\":\"main_window\",\"width\":500,\"height\":500},\"image\":{\"src\":\"Images/Sun.png\",\"name\":\"sun1\",\"hOffset\":250,\"vOffset\":250,\"alignment\":\"center\"},\"text\":{\"data\":\"Click Here\",\"size\":36,\"style\":\"bold\",\"name\":\"text1\",\"hOffset\":250,\"vOffset\":100,\"alignment\":\"center\",\"onMouseUp\":\"sun1.opacity = (sun1.opacity / 100) * 90;\"}}},{\"widget\":{\"debug\":\"on\",\"window\":{\"title\":\"Sample Konfabulator Widget\",\"name\":\"main_window\",\"width\":500,\"height\":500},\"image\":{\"src\":\"Images/Sun.png\",\"name\":\"sun1\",\"hOffset\":250,\"vOffset\":250,\"alignment\":\"center\"},\"text\":{\"data\":\"Click Here\",\"size\":36,\"style\":\"bold\",\"name\":\"text1\",\"hOffset\":250,\"vOffset\":100,\"alignment\":\"center\",\"onMouseUp\":\"sun1.opacity = (sun1.opacity / 100) * 90;\"}}},{\"widget\":{\"debug\":\"on\",\"window\":{\"title\":\"Sample Konfabulator Widget\",\"name\":\"main_window\",\"width\":500,\"height\":500},\"image\":{\"src\":\"Images/Sun.png\",\"name\":\"sun1\",\"hOffset\":250,\"vOffset\":250,\"alignment\":\"center\"},\"text\":{\"data\":\"Click Here\",\"size\":36,\"style\":\"bold\",\"name\":\"text1\",\"hOffset\":250,\"vOffset\":100,\"alignment\":\"center\",\"onMouseUp\":\"sun1.opacity = (sun1.opacity / 100) * 90;\"}}}]}}";
    private const string LargeJsonString = "[{\"_id\":\"5eb269d7e263a650fa521fce\",\"index\":0,\"guid\":\"7bd247fd-1cca-4bca-a11e-f08fefb2fd88\",\"isActive\":true,\"balance\":\"$1,661.65\",\"picture\":\"http://placehold.it/32x32\",\"age\":38,\"eyeColor\":\"brown\",\"name\":\"Vang Pruitt\",\"gender\":\"male\",\"company\":\"MEMORA\",\"email\":\"vangpruitt@memora.com\",\"phone\":\"+1 (941) 540-3024\",\"address\":\"981 Woodpoint Road, Lumberton, Georgia, 436\",\"about\":\"Adipisicing quis quis esse cillum do aliqua cupidatat. Veniam quis sint veniam consequat incididunt nostrud irure consectetur fugiat Lorem consectetur culpa. Eu nisi voluptate reprehenderit excepteur officia irure. Commodo et pariatur minim sit sunt voluptate in in consectetur.\\r\\n\",\"registered\":\"2019-05-26T06:33:18 -02:00\",\"latitude\":2.802999,\"longitude\":87.398184,\"tags\":[\"exercitation\",\"in\",\"minim\",\"ut\",\"ad\",\"amet\",\"ex\"],\"friends\":[{\"id\":0,\"name\":\"Fulton Booth\"},{\"id\":1,\"name\":\"Janice Raymond\"},{\"id\":2,\"name\":\"Leonard Guerra\"}],\"greeting\":\"Hello, Vang Pruitt! You have 9 unread messages.\",\"favoriteFruit\":\"strawberry\"},{\"_id\":\"5eb269d71d47d0aa8caf8e5d\",\"index\":1,\"guid\":\"6e25dc1e-b01d-462b-9bd3-f762601a70b5\",\"isActive\":true,\"balance\":\"$3,073.30\",\"picture\":\"http://placehold.it/32x32\",\"age\":24,\"eyeColor\":\"brown\",\"name\":\"Fuentes Wilkins\",\"gender\":\"male\",\"company\":\"QUONK\",\"email\":\"fuenteswilkins@quonk.com\",\"phone\":\"+1 (912) 409-3864\",\"address\":\"925 Seagate Avenue, Juntura, Tennessee, 7256\",\"about\":\"Laborum aute voluptate id aute ipsum. Aliqua proident cillum sit anim pariatur tempor sit non anim et. Anim adipisicing exercitation exercitation ad aliquip commodo.\\r\\n\",\"registered\":\"2019-10-12T01:23:03 -02:00\",\"latitude\":11.285935,\"longitude\":168.307644,\"tags\":[\"amet\",\"veniam\",\"eiusmod\",\"anim\",\"elit\",\"sit\",\"aliquip\"],\"friends\":[{\"id\":0,\"name\":\"Rebekah Hooper\"},{\"id\":1,\"name\":\"Luz Clay\"},{\"id\":2,\"name\":\"Briana Navarro\"}],\"greeting\":\"Hello, Fuentes Wilkins! You have 7 unread messages.\",\"favoriteFruit\":\"banana\"},{\"_id\":\"5eb269d7baa30b3c10c95ed1\",\"index\":2,\"guid\":\"fbdfd5e2-4be7-44aa-82e0-a8d629f2814e\",\"isActive\":true,\"balance\":\"$1,140.06\",\"picture\":\"http://placehold.it/32x32\",\"age\":20,\"eyeColor\":\"brown\",\"name\":\"Maryellen Barrera\",\"gender\":\"female\",\"company\":\"PRINTSPAN\",\"email\":\"maryellenbarrera@printspan.com\",\"phone\":\"+1 (972) 598-3416\",\"address\":\"254 Doughty Street, Loyalhanna, Oregon, 6496\",\"about\":\"Anim sunt pariatur amet adipisicing Lorem sint eu. Qui incididunt deserunt eu irure quis ea ipsum sit Lorem anim velit. Excepteur ex ex cillum dolor duis sunt est ad cupidatat nisi minim elit consectetur. Ullamco consequat velit magna minim.\\r\\n\",\"registered\":\"2019-12-01T11:32:41 -01:00\",\"latitude\":-82.018912,\"longitude\":58.634407,\"tags\":[\"enim\",\"tempor\",\"culpa\",\"magna\",\"qui\",\"minim\",\"aliquip\"],\"friends\":[{\"id\":0,\"name\":\"Molly Wilder\"},{\"id\":1,\"name\":\"Marci Owen\"},{\"id\":2,\"name\":\"Brooke Walsh\"}],\"greeting\":\"Hello, Maryellen Barrera! You have 7 unread messages.\",\"favoriteFruit\":\"apple\"},{\"_id\":\"5eb269d7d540e816e540b786\",\"index\":3,\"guid\":\"fc338dab-0efa-4042-b606-15ec5bd90b3a\",\"isActive\":true,\"balance\":\"$3,485.52\",\"picture\":\"http://placehold.it/32x32\",\"age\":25,\"eyeColor\":\"blue\",\"name\":\"Hattie Roman\",\"gender\":\"female\",\"company\":\"REVERSUS\",\"email\":\"hattieroman@reversus.com\",\"phone\":\"+1 (920) 519-2691\",\"address\":\"875 Story Court, Veguita, Maine, 3325\",\"about\":\"Non excepteur Lorem ex veniam. Cillum eu laboris proident tempor dolore quis pariatur in culpa excepteur elit id duis. Tempor tempor laborum nisi aliquip.\\r\\n\",\"registered\":\"2015-03-27T09:41:39 -01:00\",\"latitude\":-77.496931,\"longitude\":-1.023251,\"tags\":[\"cillum\",\"aliqua\",\"cillum\",\"occaecat\",\"amet\",\"fugiat\",\"dolor\"],\"friends\":[{\"id\":0,\"name\":\"Dale Weiss\"},{\"id\":1,\"name\":\"Prince Tran\"},{\"id\":2,\"name\":\"Pamela Wise\"}],\"greeting\":\"Hello, Hattie Roman! You have 3 unread messages.\",\"favoriteFruit\":\"banana\"},{\"_id\":\"5eb269d766574e33d43c73d7\",\"index\":4,\"guid\":\"2a7c5444-3c37-4ca2-b528-1df3cb0efab5\",\"isActive\":true,\"balance\":\"$2,654.88\",\"picture\":\"http://placehold.it/32x32\",\"age\":33,\"eyeColor\":\"green\",\"name\":\"Yvette Mooney\",\"gender\":\"female\",\"company\":\"CANDECOR\",\"email\":\"yvettemooney@candecor.com\",\"phone\":\"+1 (923) 589-2519\",\"address\":\"881 Kay Court, Dowling, Palau, 1405\",\"about\":\"Elit eu voluptate veniam laborum ea proident occaecat nulla Lorem ex sint ex. Labore id fugiat dolor ut anim tempor occaecat. Ad aute esse Lorem reprehenderit qui id sunt exercitation laborum.\\r\\n\",\"registered\":\"2015-12-13T06:40:16 -01:00\",\"latitude\":44.69473,\"longitude\":-109.342104,\"tags\":[\"amet\",\"cupidatat\",\"minim\",\"veniam\",\"deserunt\",\"anim\",\"sit\"],\"friends\":[{\"id\":0,\"name\":\"Claudine Love\"},{\"id\":1,\"name\":\"Sharlene Lang\"},{\"id\":2,\"name\":\"Webb Fletcher\"}],\"greeting\":\"Hello, Yvette Mooney! You have 9 unread messages.\",\"favoriteFruit\":\"strawberry\"},{\"_id\":\"5eb269d71a1100165255375d\",\"index\":5,\"guid\":\"755d3011-34da-4774-aaff-0d7615d0e4fe\",\"isActive\":false,\"balance\":\"$3,882.18\",\"picture\":\"http://placehold.it/32x32\",\"age\":30,\"eyeColor\":\"green\",\"name\":\"Head Montgomery\",\"gender\":\"male\",\"company\":\"BULLJUICE\",\"email\":\"headmontgomery@bulljuice.com\",\"phone\":\"+1 (978) 584-3910\",\"address\":\"664 George Street, Motley, Illinois, 8776\",\"about\":\"Sunt minim non eiusmod reprehenderit nulla veniam officia nulla sunt ullamco cillum Lorem et. Reprehenderit eu duis fugiat sunt tempor aliquip commodo nostrud. In deserunt et exercitation tempor exercitation sint elit aliquip tempor est consectetur. Duis sunt eu laboris nostrud aliqua mollit magna. Nostrud anim labore cupidatat consectetur eu sint reprehenderit cillum voluptate id consectetur pariatur consequat minim.\\r\\n\",\"registered\":\"2016-12-02T07:39:43 -01:00\",\"latitude\":35.628237,\"longitude\":97.750618,\"tags\":[\"ex\",\"consectetur\",\"id\",\"officia\",\"cillum\",\"labore\",\"occaecat\"],\"friends\":[{\"id\":0,\"name\":\"Potter Cook\"},{\"id\":1,\"name\":\"Church Watts\"},{\"id\":2,\"name\":\"Kathy Olson\"}],\"greeting\":\"Hello, Head Montgomery! You have 5 unread messages.\",\"favoriteFruit\":\"strawberry\"},{\"_id\":\"5eb269d7147f54bbfd73a920\",\"index\":6,\"guid\":\"f757168b-660a-41ff-a410-2d7d4031f0ff\",\"isActive\":false,\"balance\":\"$2,641.71\",\"picture\":\"http://placehold.it/32x32\",\"age\":30,\"eyeColor\":\"blue\",\"name\":\"Carla Ware\",\"gender\":\"female\",\"company\":\"MEDCOM\",\"email\":\"carlaware@medcom.com\",\"phone\":\"+1 (914) 409-2524\",\"address\":\"482 Burnett Street, Courtland, Federated States Of Micronesia, 6331\",\"about\":\"Cillum ea enim nulla et voluptate in. Laborum voluptate sit ut cupidatat irure culpa in deserunt. Enim sit laborum sunt ex eu exercitation aliqua voluptate.\\r\\n\",\"registered\":\"2019-02-02T12:33:07 -01:00\",\"latitude\":61.206412,\"longitude\":-99.105565,\"tags\":[\"enim\",\"consectetur\",\"esse\",\"aliquip\",\"elit\",\"adipisicing\",\"anim\"],\"friends\":[{\"id\":0,\"name\":\"Wagner Collins\"},{\"id\":1,\"name\":\"Stephanie Terry\"},{\"id\":2,\"name\":\"Wilkerson Maddox\"}],\"greeting\":\"Hello, Carla Ware! You have 5 unread messages.\",\"favoriteFruit\":\"apple\"},{\"_id\":\"5eb269d72e5476f4153fb7f9\",\"index\":7,\"guid\":\"7fd3213c-65e3-4d30-859d-c666c6eb2231\",\"isActive\":false,\"balance\":\"$3,748.30\",\"picture\":\"http://placehold.it/32x32\",\"age\":25,\"eyeColor\":\"blue\",\"name\":\"Rebecca Sheppard\",\"gender\":\"female\",\"company\":\"EXPOSA\",\"email\":\"rebeccasheppard@exposa.com\",\"phone\":\"+1 (918) 449-3202\",\"address\":\"225 Vandervoort Place, Condon, North Dakota, 4941\",\"about\":\"Est magna consectetur ex elit esse. Deserunt consequat sint anim adipisicing eu labore ex ut amet. Eu velit duis sunt ipsum. Elit cupidatat et eu qui aliquip deserunt incididunt ex mollit consectetur ipsum. Esse non anim dolore minim magna amet velit exercitation velit.\\r\\n\",\"registered\":\"2017-05-31T08:20:38 -02:00\",\"latitude\":-64.19375,\"longitude\":-65.280295,\"tags\":[\"minim\",\"culpa\",\"commodo\",\"mollit\",\"dolore\",\"culpa\",\"velit\"],\"friends\":[{\"id\":0,\"name\":\"Dawson Gates\"},{\"id\":1,\"name\":\"Frost Jensen\"},{\"id\":2,\"name\":\"Weaver Burks\"}],\"greeting\":\"Hello, Rebecca Sheppard! You have 9 unread messages.\",\"favoriteFruit\":\"strawberry\"},{\"_id\":\"5eb269d7b6f75e7ab91f6133\",\"index\":8,\"guid\":\"9a867aa7-168b-4848-a8b6-2aedb0de6d83\",\"isActive\":false,\"balance\":\"$3,026.27\",\"picture\":\"http://placehold.it/32x32\",\"age\":31,\"eyeColor\":\"green\",\"name\":\"Jordan Franklin\",\"gender\":\"female\",\"company\":\"COMFIRM\",\"email\":\"jordanfranklin@comfirm.com\",\"phone\":\"+1 (852) 593-2144\",\"address\":\"270 Crawford Avenue, Wilmington, Arizona, 6180\",\"about\":\"Occaecat ut non anim consectetur excepteur exercitation do excepteur do quis eiusmod. Est minim sunt consequat exercitation minim cupidatat ea et. Ea ex excepteur eu tempor adipisicing Lorem duis. Culpa dolore ut sit ut consectetur pariatur dolore incididunt aliqua anim incididunt. Qui et proident commodo sit dolor veniam dolore culpa dolor nisi deserunt reprehenderit labore excepteur. Anim ad commodo aliquip laboris deserunt. Fugiat ea duis eiusmod in officia occaecat irure et.\\r\\n\",\"registered\":\"2019-01-17T09:53:56 -01:00\",\"latitude\":18.477444,\"longitude\":-26.502142,\"tags\":[\"cupidatat\",\"magna\",\"exercitation\",\"eu\",\"consequat\",\"aliquip\",\"adipisicing\"],\"friends\":[{\"id\":0,\"name\":\"Elsie Morrow\"},{\"id\":1,\"name\":\"Carmen Dennis\"},{\"id\":2,\"name\":\"Yang Frye\"}],\"greeting\":\"Hello, Jordan Franklin! You have 3 unread messages.\",\"favoriteFruit\":\"apple\"},{\"_id\":\"5eb269d7c37d3ea8eac1d92f\",\"index\":9,\"guid\":\"7820c5e9-9c39-4793-9384-b00f4d3fc9c6\",\"isActive\":false,\"balance\":\"$3,519.28\",\"picture\":\"http://placehold.it/32x32\",\"age\":36,\"eyeColor\":\"brown\",\"name\":\"Harmon Richardson\",\"gender\":\"male\",\"company\":\"BRAINCLIP\",\"email\":\"harmonrichardson@brainclip.com\",\"phone\":\"+1 (967) 408-3810\",\"address\":\"416 Wyona Street, Urbana, Oklahoma, 5317\",\"about\":\"Reprehenderit officia ex officia proident ipsum occaecat sit incididunt magna non exercitation quis. Et cupidatat minim sit irure nostrud ea esse. Enim aliqua occaecat exercitation cupidatat dolore qui excepteur fugiat nostrud do id ad. Irure amet dolor elit quis excepteur consectetur laborum aliqua esse ad laboris aliqua laboris elit. Esse dolor et incididunt reprehenderit sit ex anim minim commodo ex duis anim excepteur fugiat.\\r\\n\",\"registered\":\"2014-01-09T06:14:50 -01:00\",\"latitude\":-11.892063,\"longitude\":171.301135,\"tags\":[\"deserunt\",\"in\",\"mollit\",\"commodo\",\"fugiat\",\"in\",\"officia\"],\"friends\":[{\"id\":0,\"name\":\"Deloris Simmons\"},{\"id\":1,\"name\":\"Helena Decker\"},{\"id\":2,\"name\":\"Rodriquez Lowe\"}],\"greeting\":\"Hello, Harmon Richardson! You have 10 unread messages.\",\"favoriteFruit\":\"banana\"},{\"_id\":\"5eb269d7abe2360eb55c9238\",\"index\":10,\"guid\":\"bb224e15-c05e-42fc-aa4b-eb877b9caf83\",\"isActive\":false,\"balance\":\"$2,046.03\",\"picture\":\"http://placehold.it/32x32\",\"age\":31,\"eyeColor\":\"brown\",\"name\":\"Rutledge Holloway\",\"gender\":\"male\",\"company\":\"QUINTITY\",\"email\":\"rutledgeholloway@quintity.com\",\"phone\":\"+1 (812) 523-3577\",\"address\":\"924 Wakeman Place, Caroline, Florida, 448\",\"about\":\"Voluptate nostrud incididunt cupidatat occaecat nisi amet consectetur tempor commodo pariatur aute tempor eiusmod voluptate. Sint cillum labore ullamco consequat elit labore. In et ipsum officia exercitation sint exercitation minim laboris nisi Lorem ad. Exercitation duis magna exercitation ex aliquip elit sint amet fugiat tempor fugiat. Minim deserunt incididunt cupidatat occaecat ipsum ipsum dolore incididunt laboris. Aute cupidatat fugiat dolor est non. Consequat velit fugiat irure officia cillum mollit ad cillum aliqua in labore occaecat dolore.\\r\\n\",\"registered\":\"2019-04-11T03:15:57 -02:00\",\"latitude\":63.608152,\"longitude\":29.757405,\"tags\":[\"elit\",\"irure\",\"dolore\",\"labore\",\"ut\",\"dolor\",\"veniam\"],\"friends\":[{\"id\":0,\"name\":\"Darcy Wolf\"},{\"id\":1,\"name\":\"Bridget Rocha\"},{\"id\":2,\"name\":\"Garrison Ford\"}],\"greeting\":\"Hello, Rutledge Holloway! You have 6 unread messages.\",\"favoriteFruit\":\"apple\"},{\"_id\":\"5eb269d77706c5051bab9e2c\",\"index\":11,\"guid\":\"f814c8da-7104-4e30-b9bf-4e8ae02cd93f\",\"isActive\":false,\"balance\":\"$1,159.77\",\"picture\":\"http://placehold.it/32x32\",\"age\":25,\"eyeColor\":\"brown\",\"name\":\"Teri Farrell\",\"gender\":\"female\",\"company\":\"EVEREST\",\"email\":\"terifarrell@everest.com\",\"phone\":\"+1 (881) 437-3416\",\"address\":\"168 Ashford Street, Basye, Arkansas, 1990\",\"about\":\"Anim ut commodo elit eu. Esse eu sunt aute pariatur sunt in. Ea adipisicing ullamco sunt labore officia dolore aute incididunt. Ut id irure occaecat laborum cupidatat ut occaecat. Reprehenderit tempor consequat ullamco mollit nisi anim laboris culpa irure. Laboris cillum ut reprehenderit deserunt incididunt velit id dolor magna consectetur. Non voluptate irure deserunt aliqua officia cillum cillum excepteur nisi dolor excepteur sint esse.\\r\\n\",\"registered\":\"2017-12-09T07:59:34 -01:00\",\"latitude\":-58.989994,\"longitude\":155.72163,\"tags\":[\"nulla\",\"aliqua\",\"sunt\",\"est\",\"do\",\"aute\",\"quis\"],\"friends\":[{\"id\":0,\"name\":\"Kristin Goodman\"},{\"id\":1,\"name\":\"Mamie Short\"},{\"id\":2,\"name\":\"Cynthia Goodwin\"}],\"greeting\":\"Hello, Teri Farrell! You have 1 unread messages.\",\"favoriteFruit\":\"strawberry\"}]";

    private const int N = 1000;

    [ParamsSource(nameof(ValuesForTestObj))]
    public JsonTestObject TestObj { get; set; }

    public static IEnumerable<JsonTestObject> ValuesForTestObj() => new[]
    {
        new JsonTestObject(SmallJsonString, "S"),
        new JsonTestObject(MediumJsonString, "M"),
        new JsonTestObject(LargeJsonString, "L")
    };

    [Benchmark]
    public void IndentDbc()
    {
        JsonExtensions.ToString(TestObj.Element, true);
    }

    [Benchmark]
    public void IndentJoelius()
    {
        JsonElementExtension.ToStringIndented(TestObj.Element);
    }

    [Benchmark]
    public void IndentDbcTimes1000()
    {
        for (int i = 0; i < N; i++)
        {
            JsonExtensions.ToString(TestObj.Element, true);
        }
    }

    [Benchmark]
    public void IndentJoeliusTimes1000()
    {
        for (int i = 0; i < N; i++)
        {
            JsonElementExtension.ToStringIndented(TestObj.Element);
        }
    }

    public class JsonTestObject
    {
        private readonly string _jsonString;
        private readonly string _display;
        public JsonElement Element { get; }

        public JsonTestObject(string json, string display)
        {
            _jsonString = json;
            _display = display;
            Element = JsonSerializer.Deserialize<JsonElement>(_jsonString);
        }

        public override string ToString() =>
            $"{_display} | Length: {_jsonString.Length}";
    }
}

internal static class JsonElementExtension
{
    private static readonly JsonWriterOptions s_indentedOptions = new JsonWriterOptions()
    {
        Indented = true
    };

    public static string ToStringIndented(this JsonElement value)
    {
        using MemoryStream stream = new MemoryStream();
        using Utf8JsonWriter writer = new Utf8JsonWriter(stream, s_indentedOptions);
        value.WriteTo(writer);
        writer.Flush();
        string indented = Encoding.UTF8.GetString(stream.GetBuffer(), 0, (int)stream.Length);

        return indented;
    }
}

internal static class JsonExtensions
{
    public static string ToString(this JsonElement element, bool indent)
        => element.ValueKind == JsonValueKind.Undefined ? "" : JsonSerializer.Serialize(element, new JsonSerializerOptions { WriteIndented = indent });
}

public class Program
{
    public static void Main(string[] args)
    {
        var summary = BenchmarkRunner.Run<PrettyPrintJson>();
        Console.WriteLine(summary);
    }
}
1 голос
/ 04 мая 2020

Вы можете повторно сериализовать ваш JsonElement с помощью JsonSerializer и установить JsonSerializerOptions.WriteIndented = true, например, в методе расширения:

public static partial class JsonExtensions
{
    public static string ToString(this JsonElement element, bool indent)
        => element.ValueKind == JsonValueKind.Undefined ? "" : JsonSerializer.Serialize(element, new JsonSerializerOptions { WriteIndented = indent } );
}

И затем выполните:

var indentedJson = myJsonElement.ToString(true)

Примечания:

  • Проверка для JsonValueKind.Undefined состоит в том, чтобы избежать исключения со значением по умолчанию (неинициализированным) JsonElement struct; JsonElement.ToString() не выбрасывает по умолчанию JsonElement, поэтому не следует форматировать версию.

  • Запись с использованием Utf8JsonWriter при настройке JsonWriterOptions.Indented, как показано в других ответах, также будет работать.

Демонстрационная скрипка здесь .

1 голос
/ 04 мая 2020

Вы пробовали использовать метод WriteTo?

var stream = new MemoryStream();
var options = new JsonWriterOptions
{
    Indented = true
};
var writer = new Utf8JsonWriter(stream, options);
jsonElement.WriteTo(writer);
...