Form-Data array not being deserialized to request dto - json

I'm trying to do filtering function for KendoUI Grid.
Kendo sends data as form-data:
take:20
skip:0
page:1
pageSize:20
filter[filters][0][operator]:eq
filter[filters][0][value]:abc
filter[filters][0][field]:No
filter[logic]:and
I tried to deserialize it using dto:
public class FilteringRule
{
public string Field { get; set; }
public string Operator { get; set; }
public string Value { get; set; }
}
public class FilteringInfo
{
public string Logic { get; set; }
public FilteringRule[] Filters { get; set; }
}
public class FilteredQuery
{
FilteringInfo Filter { get; set; }
//...
}
but deserialization fails:
'filter[filters][0][operator]' does not exist on type 'FilteredQuery'
'filter[filters][0][value]' does not exist on type 'FilteredQuery'
'filter[filters][0][field]' does not exist on type 'FilteredQuery'
'filter[logic]' does not exist on type 'FilteredQuery'
How to make this work? When I manually send json instead of form-data it works.
Can kendo send json? Setting contentType: "application/json" in datasource doesn't help. Kendo still sends data as form-data, servicestack throws error: "unable to bind request".

ServiceStack allows sending complex objects via QueryStrings using the lightweight JSV Syntax which from your example would look something like:
?filter={filters:[{operator:eq,value:abc,field:no}],{logic:and}}
But since Kendo is unlikely to support this syntax, you would be better off sending JSON if it supports it which would naturally map to your DTOs.

Related

JSON as data type in ASP.Net Core 3.1 controller

I'm creating an Api using .Net Core 3.1 in which I need one property input as JSON in the controller, something like:
{
"name": "test",
"JSONData": { "roles": ["data1", "data2"] }
}
so that I can define the request something like:
public class MyRequest
{
public string Name { get; set;}
public JSON JSONData { get; set; }
}
I'm thinking of having it as a string and using Serialize/Deserialize it if we cannot have it as a "JSON" data type.
Is there a way to have a property as JSON type from both request and response?
I've just tried with JsonElement and could see it works; only one issue that the property is not showing up from the swagger UI. So the request is like:
public class MyRequest
{
public string Name { get; set;}
public JsonElement JSONData { get; set; }
}

Custom serialization in Service Stack using DeSerializeFn

In servicestack, I am trying to process a webhook which sends the following JSON body to a service stack endpoint:
{
"action": "actionType1",
"api_version": "1.00",
"data": {
"id": "a8d316b8-10a7-4440-a836-9bd354f656db",
//VARIABLE other properties / structure
}
}
Which I am trying to map to the following request object:
[Route("/public/Webhookhandler", HttpVerbs.Post)]
public class MyCustomRequst
{
public string action { get; set; }
public string api_version { get; set; }
public string data { get; set; } //Will be the remaining JSON
}
However, when the service stack framework processes this - the value in "data" is the correct part of the JSON body, but with all of the quotes removed - so it is no longer valid.
I have tried to override the serialization for the whole request object using something like this:
JsConfig<MyCustomRequst>.DeSerializeFn = DeserializeMyRequestDto;
public MyCustomRequst DeserializeMyRequestDto(string rawBody)
{
var result = rawBody.FromJson<MyCustomRequst>();
return result
}
But even in this case, the value of the "rawBody" variable is still the correct JSON data but with all the quotes removed, e.g.
{
action:actionType1,
api_version:1.00,
data:{id:a8d316b8-10a7-4440-a836-9bd354f656db}
}
Am I doing something wrong here? I am unsure whether I am trying to make service stack do something it is not intended to do, or whether I am missing something that would make this work.
Any help would be appreciated :-)
Your DTO should closely match the shape of the JSON, if it's always a flat object you can use a string Dictionary, e.g:
[Route("/public/Webhookhandler", HttpVerbs.Post)]
public class MyCustomRequst
{
public string action { get; set; }
public string api_version { get; set; }
public Dictionary<string,string> data { get; set; }
}
If it's a more nested object structure you can use a JsonObject for a more flexible API to parse dynamically.

Unable to retrieve Json data from remote server binding to object in asp.net mvc

I am developing an Asp.Net mvc application. In my application, I need to retrieve json object from remote server. I am using web client for it. But it is giving me error. My scenario is below.
I have this url
http://graph.facebook.com/{fb_id}/picture?width=200&height=200&redirect=false
When I access from browser, it return something like this
So I am trying to retrieve that data as json and then serialize them back. So I builds two classes like below to bind that data.
public class FacebookAvatarResponse
{
[JsonProperty("data")]
public FacebookAvatarData Data { get; set; }
}
public class FacebookAvatarData
{
[JsonProperty("height")]
public int Height { get; set; }
[JsonProperty("width")]
public int Width { get; set; }
[JsonProperty("is_silhouette")]
public bool IsSilhouette { get; set; }
[JsonProperty("url")]
public string Url { get; set; }
}
In controll, I built an action method
[AllowAnonymous]
public JsonResult Test(string avatarDataUrl)
{
using (WebClient webClient = new WebClient())
{
string data = webClient.DownloadString(avatarDataUrl);
return Json(JsonConvert.DeserializeObject<FacebookAvatarResponse>(data),JsonRequestBehavior.AllowGet);
}
}
As you can see I am getting that data as json and then return as action result. But when I request that action method passing correct url as parameter, it is giving me this error.
How can I retrieve JSON data from remote server binding to the specific classes?
Possibly your are not passing JSON to DeserializeObject.
JsonConvert.DeserializeObject takes JSON value.
Check your data should be in json format to deserialize.
Json(JsonConvert.DeserializeObject<FacebookAvatarResponse>(data),
JsonRequestBehavior.AllowGet);

JSON array is converting to a generic list, but not converting to a generic collection. Why?

I am sending a Json Array from the client web application to asp.net webapi.
For example,
{
"SurveyId":3423,
"CreatorId":4235,
"GlobalAppId":34,
"AssociateList":[
{"AssociateId":4234},
{"AssociateId":43},
{"AssociateId":23423},
{"AssociateId":432}
],
"IsModelDirty":false,
"SaveMode":null
}
Here Associate List is a JSON Array,
Usually it will automatically serialize to a List<> object.
Using the below code ,i am posting the response to the WebApi
public IEnumerable<Associate> Post(ResponseStatus responseStatus)
{
return this.responsestatusrepository.ResponseStatusCheck(responseStatus);
}
The ResponseStatus class is shown below.
public class ResponseStatus : AppBaseModel
{
public int SurveyId { get; set; }
public int CreatorId { get; set; }
public int GlobalAppId { get; set; }
public List<Associate> AssociateList { get; set; }
}
I have changed the List<> to Collection<> as a part of my code analysis correction.
ie, public Collection<Associate> AssociateList { get; set; }
But it is always getting a null value when we are using collection instead of List. Is there any specific reason for this?
Ok, I think I will have to answer this in an indirect way.
What you are passing on to the server is an array of objects (in JSON format), but once you start processing this in C# the array of objects is now treated as a single c# object. Inside this object, your model expects one of the fields to be a Collection of Associate.
Right, when I work with JSON data similar to whats mentioned in this case - I prefer to use Newtonsofts' JOject.
So here is how I made the C# object with the JSON data you provided:
Used your model:
public class ResponseStatus
{
public int SurveyId { get; set; }
public int CreatorId { get; set; }
public int GlobalAppId { get; set; }
public Collection<Associate> AssociateList { get; set; }
}
public class Associate
{
public int AssociateId { get; set; }
}
Made a routine which takes string (the JSON data), and returns an object of type ResponseStatus:
using System;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
---------------------------------------------------------------------
public static ResponseStatus GetResponseStatusObject(string jsonData)
{
JObject jObject = JObject.Parse(jsonData);
return jObject.ToObject<ResponseStatus>();
}
Now when I call this method and pass on the exact same JSON data which you provided, I get this:
This might not directly solve your problem, but hopefully guide you in the right direction in understanding array/object serialization when working with JavaScript/C#.
Best of luck!

WCF: Returning a complex object in JSON format

I'm writing a WCF web service which return data as JSON.
This has been working fine, but I wish to return a list of objects, each of which will contain another list of objects.
This results in no data being sent to the client.
How do I serialize this list of complex objects and return it as JSON.
Thanks.
You can create a custom class and with in the custom class you can create some properties with list datatype and return the list of custom class from service method. the below will code helps you
[OperationContract]
[WebGet(UriTemplate = "Get", ResponseFormat = WebMessageFormat.Json)]
List<StoreAndProductDetails> UpdateStoreProductPriceList();
public class StoreAndProductDetails
{
public StoreAndProductDetails();
public List<PriceFeed> listPriceFeed { get; set; }
public List<ProductFeed> listProductFeed { get; set; }
public List<StoreFeed> listStoreFeed { get; set; }
}