redis-om-dotnet
redis-om-dotnet copied to clipboard
`FirstOrDefault` throws `JsonException` when field contains a JSON String
Currently, If one were to retrieve a Hash document that contains a string field with JSON data, FindById
or Where(...).FirstOrDefault
will throw a JsonException
.
Code to reproduce bug:
using Redis.OM;
using Redis.OM.Modeling;
using System.Text.Json;
var connectionProvider = new RedisConnectionProvider("redis://127.0.0.1:6379");
connectionProvider.Connection.CreateIndex(typeof(Dummy));
var dummyContext = connectionProvider.RedisCollection<Dummy>();
var inputData = new Dictionary<string, string>();
inputData.Add("test", "item");
string serializedDict = JsonSerializer.Serialize(inputData);
dummyContext.Insert(new Dummy() { id = "hello", dictAsJson = serializedDict });
var item = dummyContext.Where(x => x.id == "hello").FirstOrDefault(); // Throws JSONException
[Document]
public class Dummy
{
[RedisIdField]
[Indexed]
public string id { get; set; } = String.Empty;
public string dictAsJson { get; set; } = String.Empty;
}
Reported Exception:
System.Text.Json.JsonException: ''t' is invalid after a value. Expected either ',', '}', or ']'. Path: $ | LineNumber: 0 | BytePositionInLine: 30.'
Proof that data is stored in Redis:
Is this a bug, or did I make a mistake along the way?
Thanks and Regards
No this looks like a bug, the Hash serializer/deserializer is meant to work on very flat objects, it's not really anticipating the insertion of json data in the fields, and under the covers, all the hash deserializer is doing is building a JSON object in memory from the hash and using that construction to deserialize it back into the object. This is something I can look into, but I think my recommendation would be to try to change the type to JSON, unless there's some compelling reason not to, the serializers json uses are more sophisticated than the serializer I wrote for hashes for sure. If I change the storage type to JSON, it seems to work.
Thanks for the reply.
Swapping to a DocumentType of JSON works.
This seems like quite a dangerous bug--taking into consideration that Hash is the default DocumentType and JSON strings may easily be injected.
Thanks for the reply.
Swapping to a DocumentType of JSON works.
This seems like quite a dangerous bug--taking into consideration that Hash is the default DocumentType and JSON strings may easily be injected.
Json is your best bet. If you want to use the older hash tables to store json, maybe you can look at StackExchange.Redis.Extensions which has various serialization packages that allow the seemless serialization / deserialization to the redis HashSet types.
Going to close this one out - IMO if you have JSON, using JSON serialization is your best bet.