Search code examples
jsonpostgresqlasp.net-coredapper

Net core dapper and postgres jsonb column


I want to POST some custom JSON to my postgres jsonb column via postman using the below request.

The custom part is sent in the "Settings" > "data" node. I don't want to apply the custom part to a model I just want to send in any kind of json and store it.

{
    "name": "Test",
    "settings": {
        "data": {
            "customdata": "hello",
            "custommore": "bye"
        }
    }
}

The "data" node is modelled - like this:

public string Data { get; set; } //I have tried JSONDocument and Jsonb types to no avail.

Postman errors with this:

"errors": {
        "$.settings.data": [
            "The JSON value could not be converted to System.String. Path: $.settings.data | LineNumber: 3 | BytePositionInLine: 17."
        ]
}

The request doesn't even hit my controller method. I think it is because the customdata and custommore is not mapped to a model.

Is there a way of sending in custom JSON data that is not fixed to a model of any kind - or must it be part of a model?

I'm struggling to find anything about this that doesn't relate to EF core which is not what I am using.


Solution

  • You can use custom model binding,and get json data from HttpContext.Request.Body,and then use sonConvert.DeserializeObject to get json object.You can set the data to the format you want.

    Here is a demo:

    DataBinder:

    public class DataBinder:IModelBinder
        {
            public Task BindModelAsync(ModelBindingContext bindingContext)
            {
                if (bindingContext == null)
                {
                    throw new ArgumentNullException(nameof(bindingContext));
                }
                var model1 = new Customer();
    
    
    
                using (var reader = new StreamReader(bindingContext.HttpContext.Request.Body))
                {
                    var body = reader.ReadToEndAsync();
    
                    var mydata = JsonConvert.DeserializeObject<JObject>(body.Result);
    
    
    
                    model1.Name = mydata["name"].ToString();
                    model1.Settings = new Settings
                    {
                        Data = mydata["settings"]["data"].ToString()
                    };
    
                }
    
                bindingContext.Result = ModelBindingResult.Success(model1);
                return Task.CompletedTask;
            }
        }
    

    Controller:

    public IActionResult TestCustomModelBinding([ModelBinder(BinderType = typeof(DataBinder))]Customer customer) {
                return Ok();
            }
    

    result: enter image description here