I'm not sure what you're asking for. It sounds like you want to use the JsonReader/JsonWriter approach, but you don't want to manually write 20,000 JSON-to-property assignments (e.g. if (token.Value == "prop1") result.prop1 = token.Value
). If that's the case, then you could generate source code that does what you want, and include the result in your project. There are many ways to do that. Here's one way:
using System;
using System.IO;
using System.Linq;
using System.Text;
namespace GetCustomAttribute
{
class MainClass
{
public static void Main(string[] args)
{
var sb = new StringBuilder();
sb.AppendLine(@"
namespace GetCustomAttribute
{
public static class PurchaseaOrderParser
{
public static void Parse(string jsonString, PurchaseOrder purchaseOrder)
{
var reader = new JsonTextReader(new StringReader(jsonString));
var currentProperty = string.Empty;
while (reader.Read())
{
if (reader.Value != null)
{
if (reader.TokenType == JsonToken.PropertyName)
currentProperty = reader.Value.ToString();");
var props = typeof(PurchaseOrder).GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(IdAttribute)));
foreach (var prop in typeof(PurchaseOrder).GetProperties())
{
var attribute = prop.GetCustomAttributes(typeof(IdAttribute), false).SingleOrDefault() as IdAttribute;
if (attribute != null)
{
var s = $"if (reader.TokenType == JsonToken.String && currentProperty == \"{attribute.Id}\") purchaseOrder.{prop.Name} = reader.Value.ToString();";
sb.AppendLine(s);
}
}
sb.Append("}}}}}}");
File.WriteAllText("PurchaseOrderParser.cs", sb.ToString());
}
}
class PurchaseOrder
{
[Id("id")]
public string Id { get; set; }
[Id("name")]
public string Name { get; set; }
}
class IdAttribute : Attribute
{
public string Id { get; set; }
public IdAttribute(string id) => Id = id;
}
}
which produces:
namespace GetCustomAttribute
{
public static class PurchaseaOrderParser
{
public static void Parse(string jsonString, PurchaseOrder purchaseOrder)
{
var reader = new JsonTextReader(new StringReader(jsonString));
var currentProperty = string.Empty;
while (reader.Read())
{
if (reader.Value != null)
{
if (reader.TokenType == JsonToken.PropertyName)
currentProperty = reader.Value.ToString();
if (reader.TokenType == JsonToken.String && currentProperty == "id") purchaseOrder.Id = reader.Value.ToString();
if (reader.TokenType == JsonToken.String && currentProperty == "name") purchaseOrder.Name = reader.Value.ToString();
}}}}}}
.NET also includes capabilities for runtime code generation. I'm not familiar with them, but you might be able to do the above at runtime, which would ensure the parser doesn't get out-of-sync with the PurchaseOrder
class.