У меня есть проблема в котором я хочу, чтобы создать поле JSON, где имя поля, как известно, во время выполнения, например:Json.Net выдает ошибку при создании моего обычая JsonConverter
{ "known_at_run_time": ["test","test","test"] }
Так что я попытался реализации это так , но всякий раз, когда я запускаю свой модульный тест, я получаю сообщение о том, что мой пользовательский JsonConverter не может быть создан. Вот мой код:
TermFilter.cs
public enum ExecutionType { plain, fielddata, @bool, and, or }
[JsonObject(MemberSerialization.OptIn)]
public class TermFilter
{
#region PROPERTIES
private JsonTuple query;
private ExecutionType execution;
private string _execution;
private bool _cache;
#endregion
#region CONSTRUCTOR
public TermFilter()
{
try
{
this.query = null;
this.Execution = ExecutionType.plain;
this.Cache = true;
}
catch(Exception)
{
throw;
}
}
public TermFilter(ExecutionType execution)
: this()
{
try
{
this.Execution = execution;
}
catch (Exception)
{
throw;
}
}
public TermFilter(ExecutionType execution, bool cache)
: this(execution)
{
try
{
this.Cache = cache;
}
catch (Exception)
{
throw;
}
}
public TermFilter(string field, string[] terms)
:this()
{
try
{
this.Query = new JsonTuple(field, new HashSet<string>(terms));
}
catch (Exception)
{
throw;
}
}
#endregion
#region GET/SET
//[JsonProperty(ItemConverterType = typeof(JsonTupleConverter))]
//[JsonProperty]
[JsonConverter(typeof(JsonTupleConverter))]
public JsonTuple Query
{
get { return query; }
set { query = value; }
}
public ExecutionType Execution
{
get { return execution; }
set
{
execution = value;
_execution = value.ToString();
}
}
[JsonProperty(PropertyName = "execution")]
public string _Execution
{
get { return _execution; }
set { _execution = value; }
}
[JsonProperty(PropertyName = "_cache")]
public bool Cache
{
get { return _cache; }
set { _cache = value; }
}
#endregion
#region METHODS
public TermFilter AddTerm(string term)
{
try
{
if (!this.query.Data.Contains(term))
this.query.Data.Add(term);
return this;
}
catch (Exception)
{
throw;
}
}
public string ToJson()
{
try
{
var settings = new JsonSerializerSettings();
settings.TypeNameHandling = TypeNameHandling.Objects;
settings.Converters.Add(new JsonTupleConverter(new Type[] { typeof(JsonTuple) }));
settings.NullValueHandling = NullValueHandling.Ignore;
return JsonConvert.SerializeObject(this, settings);
//return JsonConvert.SerializeObject(this, Formatting.None, new JsonTupleConverter(typeof(JsonTuple)));
//return JsonConvert.SerializeObject(this, Formatting.None, new JsonConverter[] { new JsonTupleConverter(typeof(JsonTuple)), });
}
catch (Exception)
{
throw;
}
}
#endregion
}
JsonTuple.cs
public class JsonTuple
{
#region PROPERTIES
private string field;
private HashSet<string> data;
#endregion
#region CONSTRUCTOR
public JsonTuple()
{
try
{
this.field = null;
this.data = null;
}
catch (Exception)
{
throw;
}
}
public JsonTuple(string field, HashSet<string> data)
{
try
{
this.field = field;
this.data = data;
}
catch (Exception)
{
throw;
}
}
#endregion
#region GET/SET
public string Field
{
get { return field; }
set { field = value; }
}
public HashSet<string> Data
{
get { return data; }
set { data = value; }
}
#endregion
#region METHODS
public string ToJson()
{
try
{
return JsonConvert.SerializeObject(this, Formatting.None, new JsonTupleConverter(typeof(JsonTuple)));
}
catch (Exception)
{
throw;
}
}
#endregion
}
JsonTupleConverter.cs
public class JsonTupleConverter : JsonConverter
{
private readonly Type[] _types;
public JsonTupleConverter(params Type[] types)
{
try
{
_types = types;
}
catch (Exception)
{
throw;
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
try
{
JToken t = JToken.FromObject(value);
if (t.Type != JTokenType.Object)
{
t.WriteTo(writer);
}
else if (!_types.Any(_t => _t == value.GetType()))
{
serializer.Serialize(writer, value);
}
else
{
JsonTuple tuple = (JsonTuple)value;
if ((tuple != null) && (tuple.Field != null) && (tuple.Data != null))
{
JToken entityToken = null;
if (tuple.Data != null)
entityToken = JToken.FromObject(tuple.Data);
JObject o = new JObject();
o.AddFirst(new JProperty(tuple.Field, entityToken));
o.WriteTo(writer);
}
}
}
catch (Exception)
{
throw;
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
}
public override bool CanRead
{
get { return false; }
}
public override bool CanConvert(Type objectType)
{
return _types.Any(t => t == objectType);
}
}
Test.cs
[TestMethod]
public void TermFieldSertialization()
{
try
{
TermFilter filter = new TermFilter("test.field", new string[] {"test1", "test2", "test3"});
Assert.IsNotNull(filter);
string sampleJson = filter.ToJson();
Assert.IsNotNull(sampleJson);
}
catch (Exception)
{
throw;
}
}
Что я делаю неправильно? Любая информация поможет.
При отправке кода, создающего такую ошибку, лучше всего уменьшить код до минимума, необходимого для воспроизведения ошибки. Видя стену кода, вы сможете заставить многих потенциальных ответчиков игнорировать ваш вопрос. –
Выберите лучший заголовок вопроса. Просто повторяющиеся теги и/или имя класса без какой-либо другой информации обычно считаются неприемлемыми для SO.Заголовок вопроса должен быть однострочным * сводкой * его содержимого - так же, как и с темами электронной почты. –