Reputation: 305
I am trying to add schema to JSON that is returned from every controller and every endpoint inside it.
Let's say I have an endpoint "localhost/values/get", and it returns a JSON as below.
{
Filed1:'Field1Value',
Field2:'Field2Value',
Field3:3
}
I want to convert it to as follows
{
Schema:[{
Field:'Filed1',
DataType:'String'
},
{
Field:'Field2',
dataType:'String'
},
{
Field:'Field3',
DataType:'int'
}],
Data:{
Filed1:'Field1Value',
Field2:'Field2Value',
Field3:3
}
}
Is there a way to add this for every return object at one place instead of doing it for every controller?
something like the attributes does.
I have tried the WriteResponseBodyAsync using
Options.OutputFormatters.Insert(0, new OutputFormatter());
in the startup.cs, but I was unable to get the properties of the type that I am sending in the response. Can someone please help me with this.
Upvotes: 0
Views: 662
Reputation: 305
This is how I achieved the output formatting in my Web API.
My Startup.cs looks like below. Inside the ConfigureServices
services.AddMvc(Options =>
{
Options.OutputFormatters.Insert(0, new OutputFormatter());
});
Create an OutputFormatter.cs class as follows.
public OutputFormatter()
{
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json"));
SupportedEncodings.Add(Encoding.GetEncoding("iso-8859-1"));
}
public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
{
var response = context.HttpContext.Response;
var responseData = Encoding.UTF8.GetBytes(LoadSchema(context));
return response.Body.WriteAsync(responseData, 0, responseData.Length);
}
private string LoadSchema(OutputFormatterWriteContext context)
{
var schema = new List<SchemaModel>();
var returnData = new ReturnModel();
foreach (var Field in (context.Object as IEnumerable<dynamic>).FirstOrDefault().GetType().GetProperties())
{
schema.Add(new SchemaModel
{
FieldName = Field.Name,
DataType = Field.PropertyType.Name
});
}
returnData.Schema = schema;
returnData.ReturnData = context.Object;
return JsonConvert.SerializeObject(returnData);
}
You can make changes to the way the schema is generated by changing the logic in the above code. Write all your controllers as is, and return the model and this OutputFormatter will take care of adding the schema to the JSON.
The JSON data would look like below.
{
"Schema": [
{
"FieldName": "FirstProp",
"DataType": "String"
},
{
"FieldName": "SecondProp",
"DataType": "Int32"
},
{
"FieldName": "ThirdProp",
"DataType": "Decimal"
},
{
"FieldName": "FourthProp",
"DataType": "Boolean"
},
{
"FieldName": "FifithProp",
"DataType": "DateTime"
}
],
"ReturnData": [
{
"FirstProp": "value0",
"SecondProp": 0,
"ThirdProp": -0.9,
"FourthProp": true,
"FifithProp": "2018-03-06T15:26:08.8428651-06:00"
},
{
"FirstProp": "value1",
"SecondProp": 1,
"ThirdProp": 0.1,
"FourthProp": false,
"FifithProp": "2018-03-07T15:26:08.8428702-06:00"
},
{
"FirstProp": "value2",
"SecondProp": 2,
"ThirdProp": 1.1,
"FourthProp": true,
"FifithProp": "2018-03-08T15:26:08.8428713-06:00"
},
{
"FirstProp": "value3",
"SecondProp": 3,
"ThirdProp": 2.1,
"FourthProp": false,
"FifithProp": "2018-03-09T15:26:08.8428724-06:00"
},
{
"FirstProp": "value4",
"SecondProp": 4,
"ThirdProp": 3.1,
"FourthProp": true,
"FifithProp": "2018-03-10T15:26:08.8428735-06:00"
}
]
}
Upvotes: 0