Skip to content

Commit 10ee32e

Browse files
committed
Add JsonValue to skip unescaping of JSON strings
1 parent d12f6d8 commit 10ee32e

3 files changed

Lines changed: 56 additions & 3 deletions

File tree

src/ServiceStack.Text/Json/JsonTypeSerializer.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,8 @@ private static string UnEscapeJsonString(string json, ref int index)
381381
{
382382
if (string.IsNullOrEmpty(json)) return json;
383383
var jsonLength = json.Length;
384-
if (json[index] == JsonUtils.QuoteChar)
384+
var firstChar = json[index];
385+
if (firstChar == JsonUtils.QuoteChar)
385386
{
386387
index++;
387388

src/ServiceStack.Text/JsonObject.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.IO;
44
using System.Text.RegularExpressions;
5+
using ServiceStack.Text.Common;
56
using ServiceStack.Text.Json;
67

78
namespace ServiceStack.Text
@@ -124,7 +125,9 @@ public static void WriteValue(TextWriter writer, object value)
124125
if (!string.IsNullOrEmpty(strValue))
125126
{
126127
var firstChar = strValue[0];
127-
if (firstChar == '{' || firstChar == '['
128+
var lastChar = strValue[strValue.Length - 1];
129+
if ((firstChar == JsWriter.MapStartChar && lastChar == JsWriter.MapEndChar)
130+
|| (firstChar == JsWriter.ListStartChar && lastChar == JsWriter.ListEndChar)
128131
|| JsonUtils.True == strValue
129132
|| JsonUtils.False == strValue
130133
|| NumberRegEx.IsMatch(strValue))
@@ -145,4 +148,24 @@ public static JsonArrayObjects Parse(string json)
145148
}
146149
}
147150

151+
public struct JsonValue
152+
{
153+
private readonly string json;
154+
155+
public JsonValue(string json)
156+
{
157+
this.json = json;
158+
}
159+
160+
public T As<T>()
161+
{
162+
return JsonSerializer.DeserializeFromString<T>(json);
163+
}
164+
165+
public string ToString()
166+
{
167+
return json;
168+
}
169+
}
170+
148171
}

tests/ServiceStack.Text.Tests/JsonTests/JsonObjectTests.cs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,28 @@ public void Can_DeSerialize_TypedContainerDto_with_JsonObject()
104104
Assert.That(container.Source.Action.ElementId, Is.EqualTo(fromText.Action.ElementId));
105105
}
106106

107+
[Test]
108+
public void Can_DeSerialize_TypedContainerDto_into_JsonValueContainerDto()
109+
{
110+
var container = new TypedContainerDto {
111+
Source = text,
112+
Destination = image
113+
};
114+
115+
var json = container.ToJson();
116+
117+
var fromJson = json.FromJson<JsonValueContainerDto>();
118+
119+
var fromText = fromJson.Source.As<TextElementDto>();
120+
var fromImage = fromJson.Destination.As<ImageElementDto>();
121+
122+
Assert.That(container.Source.Action.ElementId, Is.EqualTo(fromText.Action.ElementId));
123+
Assert.That(container.Destination.ElementId, Is.EqualTo(fromImage.ElementId));
124+
125+
Assert.That(container.Destination.Action, Is.EqualTo(fromImage.Action));
126+
Assert.That(container.Destination.Content, Is.EqualTo(fromImage.Content));
127+
}
128+
107129
[Test]
108130
public void Can_Serialize_StringContainerDto()
109131
{
@@ -131,14 +153,21 @@ public class TypedContainerDto
131153
public TextElementDto Source { get; set; }
132154
public ImageElementDto Destination { get; set; }
133155
}
134-
156+
135157
// DTOs
136158
public class StringContainerDto // This is the request dto
137159
{
138160
public string Source { get; set; } // This will be some ElementDto
139161
public string Destination { get; set; } // This will be some ElementDto
140162
}
141163

164+
// DTOs
165+
public class JsonValueContainerDto // This is the request dto
166+
{
167+
public JsonValue Source { get; set; } // This will be some ElementDto
168+
public JsonValue Destination { get; set; } // This will be some ElementDto
169+
}
170+
142171
public class TextElementDto
143172
{
144173
public string ElementType { get; set; }

0 commit comments

Comments
 (0)