I'm trying to get a JSON formatted like GeoJSON with API. I get something for GET and can DELETE but when i try to post or put i get this error System.NotSupportedException: Deserialization of reference types without parameterless constructor is not supported. Type 'System.Text.Json.JsonDocument'
Also I'm not getting exactly what I have in PostgreSQL. There is an extra "rootElement"
In PostgreSQL I have a table with columns ID(integer),type(string),properties(json),geometry(json).
I insert this
{
"id": 1,
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [23.2,23]
},
"properties": {
"name": "test2",
"type": "testing"
}
}
And this is my class
public class Test
{
public long ID { get; set; }
public string type { get; set; }
public System.Text.Json.JsonDocument geometry { get; set; }
public System.Text.Json.JsonDocument properties { get; set; }
}
What I get with GET is this
[
{
"id": 2,
"type": "test",
"geometry": {
"rootElement": {
"type": "point",
"coordinates": [
23.2,
23
]
}
},
"properties": {
"rootElement": {
"name": "test2",
"type": "testing"
}
}
}
]
Related
is it possible to change property names to camelCase in Swagger documentation? I'm using .NET Core 2.2 and Swashbuckle.AspNetCore 5.2.1.
I've tried to use DescribeAllParametersInCamelCase() method in Startup.cs but nothing has changed.
Help!
My model:
{
public int MyProperty1 { get; set; }
public int MyProperty2 { get; set; }
public int MyProperty3 { get; set; }
}
and swagger.json which was generated for it in POST method:
"components": {
"schemas": {
"TestModel": {
"type": "object",
"properties": {
"MyProperty1": {
"type": "integer",
"format": "int32"
},
"MyProperty2": {
"type": "integer",
"format": "int32"
},
"MyProperty3": {
"type": "integer",
"format": "int32"
}
}
}
}
}
How to change it to:
"components": {
"schemas": {
"testModel": {
"type": "object",
"properties": {
"myProperty1": {
"type": "integer",
"format": "int32"
},
"myProperty2": {
"type": "integer",
"format": "int32"
},
"myProperty3": {
"type": "integer",
"format": "int32"
}
}
}
}
}
?
I faced the same issue and here is my workaround :
I implemented a custom filter (ISchemaFilter) that does the following
public class CamelCasingPropertiesFilter : ISchemaFilter {
public void Apply(OpenApiSchema model, SchemaFilterContext context)
{
model.Properties =
model.Properties.ToDictionary(d => d.Key.Substring(0, 1).ToLower() + d.Key.Substring(1), d => d.Value);
}
}
There is maybe a more reliable solution I don't know. The matter is important as the openapi definition serves as a basis for generating api clients. openapi generator will build classes with PascalCase property names, which will be thrown by the api when used ...
Hope it helps !
I am new to this API. Trying to generate a class of 10-15 fields of different data type. But generated class has the 1st variable of the type I declared but remaining if type Object as below.
// Schema
{
"type":"object",
"properties": {
"foo": {
"type": "string"
},
"bar": {
"type": "String"
},
"baz": {
"type": "String"
}
}
}
//Generated Class
//...
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({
"foo",
"bar",
"baz"
})
public class Sample{
#JsonProperty("foo")
private String foo;
#JsonProperty("bar")
private Object bar;
#JsonProperty("baz")
private Object baz;
#JsonIgnore
....//
If you notice the 2nd and 3rd variable are declared String but result generated from class is of type object. Can someone help understand what the issue is?
{
"type":"object",
"properties": {
"length": {
"type": "string"
},
"width": {
"type": "string"
},
"height": {
"type": "string"
},
"dimensionalWeight": {
"type": "string"
}
}
}
I have the following JSON Data:
{
"0": {
"id": 0,
"type": "camera",
"option": [
{
"optionId": 1,
"optionValue": "",
"answered": "false",
"lastanswerd": "false"
}
]
},
"1": {
"id": 1,
"type": "checkCategory",
"option": [
{
"optionId": 1,
"optionValue": "",
"answered": "false",
"lastanswerd": "false"
},
{
"optionId": 2,
"optionValue": "",
"answered": "false",
"lastanswerd": "false"
}
]
}
}
How to pass JSON data into ASP.NET API request with which type of parameter in controller action?
Asp.net MVC automap and try to cast each key:value of json.
{"key1":"value", "key2":"value"}
You can access those values using params inside your function
public ActionResult Index(string key,string key2)
Or creating a class with public setter equal to your keys and a parameterless constructor.
public Class MyJson
{
public string key1 {get;set;}
public string key2 {get;set;}
}
public ActionResult Index(MyJson model)
In your specific case your passing a List of Object so you should use
public ActionResult Index(List<MyJson> model)
If you change your json to:
[
{
"id": 0,
"type": "camera",
"option": [
{
"optionId": 1,
"optionValue": "",
"answered": "false",
"lastanswerd": "false"
}
]
},
{
"id": 1,
"type": "checkCategory",
"option": [
{
"optionId": 1,
"optionValue": "",
"answered": "false",
"lastanswerd": "false"
},
{
"optionId": 2,
"optionValue": "",
"answered": "false",
"lastanswerd": "false"
}
]
}
]
json2csharp gives us:
public class Option
{
public int optionId { get; set; }
public string optionValue { get; set; }
public string answered { get; set; }
public string lastanswerd { get; set; }
}
public class RootObject
{
public int id { get; set; }
public string type { get; set; }
public List<Option> option { get; set; }
}
I have following java Object:
ProcessBean.java
import java.util.List;
import com.fasterxml.jackson.annotation.JsonRootName;
#JsonRootName(value = "process")
public class ProcessBean{
private Integer id;
private String name;
private String description;
private String user;
private String executePermissions;
private String createdDtm;
private String updatedDtm;
private Process tpProcess;
private List<ProcessParamBean> processParameters;
/* --------Getters and Setters ----------*/
}
I need to find the JSON schema for this object which is used to display these fields on UI. The order of fields in UI is determined by the order of properties in JSON schema generated.
I have generated the schema using following code:
DataSpec.java
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
import com.fasterxml.jackson.module.jsonSchema.factories.SchemaFactoryWrapper;
public class DataSpec {
public static <T> String getDataSpec(Class<T> clazz) {
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
SchemaFactoryWrapper visitor = new SchemaFactoryWrapper();
MetauiVisitorContext obj = new MetauiVisitorContext();
visitor.setVisitorContext(obj);
try {
mapper.acceptJsonFormatVisitor(clazz, visitor);
JsonSchema schema = visitor.finalSchema();
return mapper.writeValueAsString(schema);
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
}
}
MetauiVisitorContext.java
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.module.jsonSchema.factories.VisitorContext;
public class MetauiVisitorContext extends VisitorContext{
#Override
public String getSeenSchemaUri(JavaType aSeenSchema) {
return null;
}
}
The resultant schema looks like below:
{
"type": "object",
"id": "urn:jsonschema:com:restservices:api:jsonbeans:ProcessBean",
"properties": {
"updatedDtm": {
"type": "string"
},
"createdDtm": {
"type": "string"
},
"name": {
"type": "string"
},
"tpProcess": {
"type": "object",
"id": "urn:jsonschema:com:restservices:api:jsonbeans:Process",
"properties": {
"name": {
"type": "string"
},
"id": {
"type": "integer"
}
}
},
"description": {
"type": "string"
},
"id": {
"type": "integer"
},
"processParameters": {
"type": "array",
"items": {
"type": "object",
"id": "urn:jsonschema:com:restservices:api:jsonbeans:ProcessParamBean",
"properties": {
"updatedDtm": {
"type": "string"
},
"defaultValue": {
"type": "string"
},
"createdDtm": {
"type": "string"
},
"masterParam": {
"type": "object",
"id": "urn:jsonschema:com:restservices:api:jsonbeans:MasterParamBean",
"properties": {
"updatedDtm": {
"type": "string"
},
"createdDtm": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"id": {
"type": "integer"
}
}
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"processParamId": {
"type": "integer"
},
"id": {
"type": "integer"
},
"userPrompted": {
"type": "boolean"
},
"tags": {
"type": "string"
}
}
}
},
"executePermissions": {
"type": "string"
},
"user": {
"type": "string"
}
}
}
As it can be seen that the order of properties in JSON schema does not match the order of fields defined in Java object which is necessary in my case.
So how can I determine the sequence of the properties?
There is not an intrinsic order of properties in a JSON schema object, as it happens with a regular JSON or javascript object. Indeed, it does not change the validation semantics. The following schemas validate exactly the same collection of objects:
Schema 1:
{
"properties" : {
"prop1" : {
"type" : "string"
},
"prop2" : {
"type" : "number"
}
}
}
Schema 2:
{
"properties" : {
"prop2" : {
"type" : "number"
},
"prop1" : {
"type" : "string"
}
}
}
If you want to preserve some ordering you need to do it within and array. You could achieve this by using an array of objects instead of an object in the items clause. An example:
{
"type" : "array" :
"items" : [{
"properties" : {
"prop2" : {
"type" : "number"
}
}
}, {
"properties" : {
"prop1" : {
"type" : "string"
}
}
}
]
}
This way you get an ordered definition of UI items. Unfortunately, it forces you to nest each single property in an object.
Order is out of scope for json-schema. For that you need to look into json-forms https://jsonforms.io/, standards, which is extension of json-schema. It consist of three separate JSON data :
schema
values
ui-schema
The ui-schema contains the information about the ui and presentation, like order of properties (fields) and the their visual presentation, like "hidden", "read-only".
I have the following classes
[DataContract]
public class Video
{
[Key]
[DataMember(IsRequired = false)]
public int VideoId { get; set; }
[DataMember(IsRequired = false)]
public int UserId { get; set; }
[Required]
[DataMember ]
public string Title { get; set; }
[Required]
[DataMember]
public virtual IList<Tag> Tags { get; set; }
}
[DataContract]
public class Tag
{
[Key]
[Required]
[DataMember(IsRequired = false)]
public int? TagId { get; set; }
[DataMember(IsRequired = true)]
[Required]
public string Name { get; set; }
[IgnoreDataMember]
public virtual IList<Video> Videos { get; set; }
}
In my WebAPI controller, I call this:
var videos = _service.GetVideos();
return Request.CreateResponse(HttpStatusCode.OK, videos);
Which calls this:
public IList<Video> GetVideos()
{
using (var db = CreateContext())
{
return db.Videos.Include("Tags").ToList();
}
}
Yet over the wire, this is what I get:
[{
"$id": "8",
"tags": [
{
// CORRECT SERIALIZATION
"$id": "9",
"tagId": 1,
"name": "Example",
"count": 5
}
],
"videoId": 18,
"userId": 3,
"title": "Test Video",
"thumbnail": "http://i.imgur.com/gV3J2Uf.png",
"source": "test source"
},
{
"$id": "19",
"tags": [
{
// WTF?
"$ref": "9"
}
],
"videoId": 28,
"userId": 6,
"title": "Test Video",
"thumbnail": "http://i.imgur.com/gV3J2Uf.png",
"source": "test source"
},
{
"$id": "20",
"tags": [
{
// CORRECT AGAIN
"$id": "21",
"tagId": 10,
"name": "funny",
"count": 2
}
],
"videoId": 29,
"userId": 6,
"title": "TEST VID",
"thumbnail": "https://i.imgur.com/SWOQSOf.jpg",
"source": "test source"
},
{
"$id": "22",
"tags": [
{
// INCORRECT
"$ref": "9"
},
{
"$ref": "21"
}
],
"videoId": 30,
"userId": 6,
"title": "TEST VID",
"thumbnail": "https://i.imgur.com/R7lVobX.jpg",
"source": "test source"
}
For some reason - tags is sometimes serializing correctly, and sometimes not. Any idea what I'm doing wrong?
You have circular references in your object graph. They cannot be JSON serialized properly, the serializer detects this condition and automatically makes references ($ref). when you are loading the object graph using EF there are circular references between those objects in memory which cannot be represented correctly in JSON.
I would recommend you breaking the circular references graph by using a view model and then sending the view model over the wire instead of directly returning your autogenerated EF models.