Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit c02c943

Browse files
committed
Add new IValueWriter for being able to write raw JsonValue
1 parent 110d8af commit c02c943

File tree

4 files changed

+135
-6
lines changed

4 files changed

+135
-6
lines changed

lib/ServiceStack.Interfaces.dll

512 Bytes
Binary file not shown.

src/ServiceStack.Text/Common/JsWriter.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,9 +237,12 @@ public WriteObjectDelegate GetValueTypeToStringMethod(Type type)
237237
? (WriteObjectDelegate)Serializer.WriteEnumFlags
238238
: Serializer.WriteEnum;
239239

240-
if (type.HasInterface(typeof (IFormattable)))
240+
if (type.HasInterface(typeof(IFormattable)))
241241
return Serializer.WriteFormattableObjectString;
242242

243+
if (type.HasInterface(typeof(IValueWriter)))
244+
return WriteValue;
245+
243246
return Serializer.WriteObjectString;
244247
}
245248

@@ -264,6 +267,12 @@ public WriteObjectDelegate GetWriteFn<T>()
264267
return GetCoreWriteFn<T>();
265268
}
266269

270+
public void WriteValue(TextWriter writer, object value)
271+
{
272+
var valueWriter = (IValueWriter)value;
273+
valueWriter.WriteTo(Serializer, writer);
274+
}
275+
267276
private WriteObjectDelegate GetCoreWriteFn<T>()
268277
{
269278
if ((typeof(T).IsValueType() && !JsConfig.TreatAsRefType(typeof(T))) || JsConfig<T>.HasSerializeFn)
@@ -341,6 +350,9 @@ private WriteObjectDelegate GetCoreWriteFn<T>()
341350
return WriteListsOfElements<TSerializer>.WriteIEnumerable;
342351
}
343352

353+
if (typeof(T).HasInterface(typeof (IValueWriter)))
354+
return WriteValue;
355+
344356
if (typeof(T).IsClass() || typeof(T).IsInterface() || JsConfig.TreatAsRefType(typeof(T)))
345357
{
346358
var typeToStringMethod = WriteType<T, TSerializer>.Write;
@@ -374,6 +386,5 @@ public void WriteType(TextWriter writer, object value)
374386
{
375387
Serializer.WriteRawString(writer, JsConfig.TypeWriter((Type)value));
376388
}
377-
378389
}
379390
}

src/ServiceStack.Text/JsonObject.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,12 @@ public static JsonArrayObjects Parse(string json)
151151
}
152152
}
153153

154-
public struct JsonValue
154+
public interface IValueWriter
155+
{
156+
void WriteTo(ITypeSerializer serializer, TextWriter writer);
157+
}
158+
159+
public struct JsonValue : IValueWriter
155160
{
156161
private readonly string json;
157162

@@ -169,6 +174,11 @@ public override string ToString()
169174
{
170175
return json;
171176
}
177+
178+
public void WriteTo(ITypeSerializer serializer, TextWriter writer)
179+
{
180+
writer.Write(json ?? JsonUtils.Null);
181+
}
172182
}
173183

174184
}

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

Lines changed: 111 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using NUnit.Framework;
1+
using System.Collections.Generic;
2+
using NUnit.Framework;
23

34
namespace ServiceStack.Text.Tests.JsonTests
45
{
@@ -147,13 +148,119 @@ public void Can_Serialize_StringContainerDto()
147148
Assert.That(src.Action.ElementId, Is.EqualTo(fromSrc.Action.ElementId));
148149
Assert.That(dst.Action, Is.EqualTo(fromDst.Action));
149150
}
150-
151+
152+
153+
readonly SimpleObj simple = new SimpleObj
154+
{
155+
value1 = "Foo",
156+
value2 = "Bar"
157+
};
158+
159+
[Test]
160+
public void Can_Deserialize_JsonValue()
161+
{
162+
var json = simple.ToJson();
163+
var jsonValue = new JsonValue(json);
164+
165+
var fromJson = jsonValue.As<SimpleObj>();
166+
167+
Assert.That(fromJson.value1, Is.EqualTo(simple.value1));
168+
Assert.That(fromJson.value2, Is.EqualTo(simple.value2));
169+
}
170+
171+
[Test]
172+
public void Can_Serialize_JsonValue_Multiple_Times()
173+
{
174+
var json = simple.ToJson();
175+
var jsonValue = new JsonValue(json);
176+
177+
var jsonAfter = jsonValue.ToJson();
178+
179+
Assert.That(jsonAfter, Is.EqualTo(json));
180+
}
181+
182+
[Test]
183+
public void Can_Deserialize_JsonValue_After_Multiple_Serialize()
184+
{
185+
var json = simple.ToJson();
186+
var jsonValue = new JsonValue(json);
187+
188+
jsonValue = new JsonValue(jsonValue.ToJson());
189+
190+
var fromJson = jsonValue.As<SimpleObj>();
191+
192+
Assert.That(fromJson.value1, Is.EqualTo(simple.value1));
193+
Assert.That(fromJson.value2, Is.EqualTo(simple.value2));
194+
}
195+
196+
[Test]
197+
public void Can_Deserialize_JsonValue_After_Multiple_Serialize_2()
198+
{
199+
var json = simple.ToJson();
200+
var jsonValue = new JsonValue(json);
201+
202+
json = jsonValue.ToJson();
203+
204+
var fromJson = json.FromJson<SimpleObj>();
205+
206+
Assert.That(fromJson.value1, Is.EqualTo(simple.value1));
207+
Assert.That(fromJson.value2, Is.EqualTo(simple.value2));
208+
}
209+
[Test]
210+
public void Can_Serialize_NestedJsonValueDto()
211+
{
212+
var scaffold = new List<JsonValue> { new JsonValue(text.ToJson()), new JsonValue(text.ToJson()) };
213+
214+
var container = new NestedJsonValueDto
215+
{
216+
ElementId = "container_1",
217+
ElementType = "container",
218+
// Raw nesting - won't be escaped
219+
Content = new ElementContentDto { ElementId = "container_1", Content = "container goes here" },
220+
Action = new ElementActionDto { ElementId = "container_1", Action = "action goes here" },
221+
Scaffolding = scaffold
222+
};
223+
224+
var json = container.ToJson();
225+
226+
var fromJson = json.FromJson<NestedJsonValueDto>();
227+
228+
foreach (var jsonValue in fromJson.Scaffolding)
229+
{
230+
var fromJsonValue = jsonValue.As<TextElementDto>();
231+
Assert.That(fromJsonValue.ElementId, Is.EqualTo(text.ElementId));
232+
Assert.That(fromJsonValue.Action.ElementId, Is.EqualTo(text.Action.ElementId));
233+
Assert.That(fromJsonValue.Content.ElementId, Is.EqualTo(text.Content.ElementId));
234+
}
235+
}
236+
237+
public class SimpleObj
238+
{
239+
public string value1 { get; set; }
240+
public string value2 { get; set; }
241+
}
242+
243+
public class NestedSimpleJsonValue
244+
{
245+
public JsonValue Simple { get; set; }
246+
}
247+
248+
public class NestedJsonValueDto
249+
{
250+
public string ElementType { get; set; }
251+
public string ElementId { get; set; }
252+
253+
public ElementContentDto Content { get; set; }
254+
public ElementActionDto Action { get; set; }
255+
256+
public List<JsonValue> Scaffolding { get; set; }
257+
}
258+
151259
public class TypedContainerDto
152260
{
153261
public TextElementDto Source { get; set; }
154262
public ImageElementDto Destination { get; set; }
155263
}
156-
157264
// DTOs
158265
public class StringContainerDto // This is the request dto
159266
{
@@ -199,5 +306,6 @@ public class ElementActionDto
199306
public string Action { get; set; }
200307
// There can be more nested objects in here
201308
}
309+
202310
}
203311
}

0 commit comments

Comments
 (0)