https://stackoverflow.com/questions/46180408/configure-json-net-to-url-encode-certain-field

CSharp · Console

/Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
					
public class Program
{
	public static void Main()
	{
		var myObject = new MyModelClass("blablabla", "<>@%#^^@!%");
		
		var settings = new JsonSerializerSettings
		{
			ContractResolver = new CustomResolver(),
			Formatting = Formatting.Indented
		};
		
		string json = JsonConvert.SerializeObject(myObject, settings);
		
		Console.WriteLine(json);
	}
}


public class MyModelClass
{
    [JsonProperty("first_field")]
    public string FirstField { get; set; }

	[UrlEncode]
    [JsonProperty("second_field")]
    public string SecondField { get; set; }

    public MyModelClass(string first, string second)
    {
        FirstField = first;
        SecondField = second;
    }
}


public class UrlEncodeAttribute : Attribute { }

public class CustomResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        IList<JsonProperty> props = base.CreateProperties(type, memberSerialization);

        // Find all string properties that have a [UrlEncode] attribute applied
        // and attach an UrlEncodingValueProvider instance to them
        foreach (JsonProperty prop in props.Where(p => p.PropertyType == typeof(string)))
        {
            PropertyInfo pi = type.GetProperty(prop.UnderlyingName);
            if (pi != null && pi.GetCustomAttribute(typeof(UrlEncodeAttribute), true) != null)
            {
                prop.ValueProvider = new UrlEncodingValueProvider(pi);
            }
        }

        return props;
    }

    protected class UrlEncodingValueProvider : IValueProvider
    {
        PropertyInfo targetProperty;

        public UrlEncodingValueProvider(PropertyInfo targetProperty)
        {
            this.targetProperty = targetProperty;
        }

        // SetValue gets called by Json.Net during deserialization.
        // The value parameter has the original value read from the JSON;
        // target is the object on which to set the value.
        public void SetValue(object target, object value)
        {
            targetProperty.SetValue(target, (string)value);
        }

        // GetValue is called by Json.Net during serialization.
        // The target parameter has the object from which to read the string;
        // the return value is the string that gets written to the JSON
        public object GetValue(object target)
        {
            string value = (string)targetProperty.GetValue(target);
            return System.Web.HttpUtility.UrlEncode(value);
        }
    }
}



// System.Web is not accessible in .Net Fiddle, so this is a shim to stand in for the HttpUtility class.
// This is for demonstration purposes only.  Do not use this in production code; use the real System.Web.HttpUtility class instead.
namespace System.Web
{
	public static class HttpUtility
	{
		public static string UrlEncode(string url)
		{
			StringBuilder sb = new StringBuilder();
			if (!string.IsNullOrEmpty(url))
			{
				foreach (char c in url)
				{
					if (IsUrlSafeChar(c))
						sb.Append(c);
					else
					{
						sb.Append('%');
						sb.Append(((int)c).ToString("X2"));
					}
				}
			}
			return sb.ToString();
		}
		
		private static bool IsUrlSafeChar(char c)
		{
			char[] safePunct = new char[] { '(', ')', '*', '-', '.', '!', '_' };
			return ((c >= 'a' && c <= 'z') ||
					(c >= 'A' && c <= 'Z') ||
					(c >= '0' && c <= '9') ||
					safePunct.Contains(c));
		}
	}
}
;