Web Api - Returning a Dictionary - asp.net-web-api

I am unable to successfully return a populated instance of List<StringDictionary>> from Web API Controller to a C# console app. Here are the details...
Web API Code:
[HttpPost]
public async Task<HttpResponseMessage> Get(IEnumerable<long> ids)
{
var results = [assume populated instance of List<StringDictionary>>]
return Request.CreateResponse<List<StringDictionary>>(HttpStatusCode.OK, results);
}
I have the following client side code:
using (var httpClient = new HttpClient { BaseAddress = new Uri(baseAddress) })
{
var httpResponse = httpClient.PostAsJsonAsync<long[]>("api/promotions", mockIds).Result;
if (httpResponse.IsSuccessStatusCode)
{
var content = httpResponse.Content.ReadAsAsync<List<StringDictionary>>().Result; ***** DOES NOT WORK ****
}
}
I get the following error:
{"Cannot create and populate list type System.Collections.Specialized.StringDictionary. Path '[0]', line 1, position 2."}
What obvious fact am I missing here?
UPDATE - what's interesting is if I change StringDictionary to Dictionary it works great.

The difference is because of DeSerialization. JSON deserializer is not able to deserialize the format you are sending. If you just try to send single object you will get this error: Cannot create and populate list type System.Collections.Specialized.StringDictionary.
This link can help you getting more understanding.
Here is the JSON representation of serialized Dictionary and String dictionary.
Dictionary
[
{
"1": "A",
"4": "G"
},
{
"1": "A",
"3": "B"
}
]
String Dictionary
[
[
{
"_key": "4",
"_value": "G"
},
{
"_key": "1",
"_value": "A"
}
],
[
{
"_key": "3",
"_value": "B"
},
{
"_key": "1",
"_value": "A"
}
]
]

Related

Painless scripting initialize new array

I'm trying to add or update a nested object in Elasticsearch using a script. Below script works fine if integrations is already an array, but when it is null, below script throws a null pointer exception. How do I initialize ctx._source.integrations to be an empty array if its value is null? (Something like the equivalent of JavaScript's myObject.integrations = myObject.integrations ?? [])
POST /products/_update/VFfrnQrKlC5bwdfdeaQ7
{
"script": {
"source": """
ctx._source.integrations.removeIf(i -> i.id == params.integration.id);
ctx._source.integrations.add(params.integration);
ctx._source.integrationCount = ctx._source.integrations.length;
""",
"params": {
"integration": {
"id": "dVTV8GjHj8pXFnlYUUlI",
"from": true,
"to": false,
"vendor": "sfeZWDpZXlF5Qa8mUsiF",
"targetProduct": {
"id": "nyILhphvCrGYm53cfaOx",
"name": "Test Product",
"categoryIds": []
}
}
}
}
}
ok i think this does the trick:
if (ctx._source.integrations == null) {
ctx._source.integrations = new ArrayList();
}
is there a short hand to this like in the JS example?

How do i connect two types in GraphQL?

So I have two types in GraphQL:
article.mdx
---
title: "Post n.1"
category: "Category"
---
Post Content
categories.json
[
{
"name": "Category",
"description": "This is a description",
"order": 1
}
]
I want to query my post type in order to have this kind of result:
{
"node": {
"title": Post n.1
"category": {
"name": "Category",
"description": "This is a description",
"order": 1
}
}
}
How can i do this? I'm currently using GatsbyJS! Thanks.
its pretty easy as you know you should use gatsby-transformer-remark to read md files , so for the json files you should use gatsby-transformer-json , add it in the gatsby-config.js file under plugins. then you need to query your data , unfortunatly i realy dont think you can combile two files to get data as you ask , but you can try this
first in gatsby-node.js file you need to reference the variables you gonna use for filter the query data , pass those fields in to the context
exports.createPages = async function({ actions, graphql }) {
const { data } = await graphql(`
query {
allMarkdownRemark {
edges {
node {
fields {
slug
}
}
}
}
}
`)
data.allMarkdownRemark.edges.forEach(edge => {
const slug = edge.node.fields.slug
actions.createPage({
path: slug,
component: require.resolve(`./src/templates/article.js`),
context: { category: category},
})
})
}
then in your page query you can accesss the filterd query by this read more in Creating Pages from Data Pro grammatically
export const pageQuery = graphql`
query MyQuery($category: String!) {
allMarkdownRemark(filter: {frontmatter: {category: {eq: $category}}}) {
edges {
node {
frontmatter {
title
}
}
}
}
allDataJson(filter: {name: {eq: $category}}) {
edges {
node {
nodes {
name,
description,
order
}
}
}
}
}`
then access you can access the your data by const {allMarkdownRemark , allDataJson} = data
then combine those two data as you prefer
const item = {node : { title: allMarkdownRemark.edges.node[0].frontmatter }};
item.node.category = allDataJson.edges.node[0].nodes
note this was assuming that edges.node is an array so we need to exact the 1st element of your data by node[0] , please check whether this method is working .
and the structure for the json data was
{ "nodes": [ {
"name": "Category",
"description": "This is a description",
"order": 1
}
]
}

GraphQL Mutation with JSON Patch

Are there any data types in GraphQL that can be used to describe a JSON Patch operation?
The structure of a JSON Patch operation is as follows.
{ "op": "add|replace|remove", "path": "/hello", "value": ["world"] }
Where value can be any valid JSON literal or object, such as.
"value": { "name": "michael" }
"value": "hello, world"
"value": 42
"value": ["a", "b", "c"]
op and path are always simple strings, value can be anything.
If you need to return JSON type then graphql have scalar JSON
which return any JSON type where you want to return it.
Here is schema
`
scalar JSON
type Response {
status: Boolean
message: String
data: JSON
}
type Test {
value: JSON
}
type Query {
getTest: Test
}
type Mutation {
//If you want to mutation then pass data as `JSON.stringify` or json formate
updateTest(value: JSON): Response
}
`
In resolver you can return anything in json format with key name "value"
//Query resolver
getTest: async (_, {}, { context }) => {
// return { "value": "hello, world" }
// return { "value": 42 }
// return { "value": ["a", "b", "c"] }
// return anything in json or string
return { "value": { "name": "michael" } }
},
// Mutation resolver
async updateTest(_, { value }, { }) {
// Pass data in JSON.stringify
// value : "\"hello, world\""
// value : "132456"
// value : "[\"a\", \"b\", \"c\"]"
// value : "{ \"name\": \"michael\" }"
console.log( JSON.parse(value) )
//JSON.parse return formated required data
return { status: true,
message: 'Test updated successfully!',
data: JSON.parse(value)
}
},
the only thing you need to specifically return "value" key to identify to get in query and mutation
Query
{
getTest {
value
}
}
// Which return
{
"data": {
"getTest": {
"value": {
"name": "michael"
}
}
}
}
Mutation
mutation {
updateTest(value: "{ \"name\": \"michael\" }") {
data
status
message
}
}
// Which return
{
"data": {
"updateTest": {
"data": null,
"status": true,
"message": "success"
}
}
}

kendo grid Filter not pass into method

I want to pass kendo grid DataSourceRequest to web api
my web api iS:
[HttpPost]
public HttpResponseMessage GetAll([FromBody] DataSourceRequest request)
{
try
{
var itemList = new JsonListFormat<ItemVm>
{
Data = new ItemCrud().GetItemList(request),
Total = new ItemCrud().GetItemTotalCount()
};
return Request.CreateResponse(HttpStatusCode.OK, itemList);
}
catch (Exception ex)
{
return HttpResponseController.HttpResponseException(Request, ex);
}
}
but request.Filters is always null.
for test I call my web api method with postman and this json data:
{
"page": 10,
"pageSize": 20,
"sorts": [
{
"member": "Title",
"sortDirection": 0
}
],
"filters": [
{
"convertedValue": "test",
"member": "Title",
"memberType": null,
"operator": 2,
"value": "test"
}
],
"groups": null,
"aggregates": []
}
everything pass to request parameter but rquest.Filters is null !!!
anyone can explain what's my problem.
thanks
Did you try this option?
dataSource.serverFiltering = true;
please check Server filtering

How to assign a single object to a list?

I'm working with an API rest and it returns me two types of json, object and array.
Object(When there is only one record in the database):
{ "complain": { "id": "1" , "description": "hello", "date": "2017-01-24 11:46:22", "Lat": "20.5204446", "Long": "-100.8249097" } }
Array(When there is more than one record in the database):
{ "complain": [ { "id": "1" , "description": "hello", "date": "2017-01-24 11:46:22", "Lat": "20.587446", "Long": "-100.8246490" }, { "id": "2" , "description": "hello 2", "date": "2017-01-24 11:50:12", "Lat": "20.529876", "Long": "-100.8249097" } ] }
The code I use to consume the json is as follows:
content = await response.Content.ReadAsStringAsync();
var token = JToken.Parse(content);
if (token["complain"] is JArray)
{
var jsonArray = JsonConvert.DeserializeObject<RootArray>(content);
}
else if (token["complain"] is JObject)
{
var jsonObject = JsonConvert.DeserializeObject<RootObject>(content);
}
When it comes to a json array if I can add it to a listview:
myList.ItemsSource = jsonArray.listArray;
But if it is an object I can not and I get the following error:
Cannot implicitly convert type Object to IEnumerable.
Finally I was able to solve my error, it was just a matter of creating a list and adding the deserialized json object.
var jsonObject = JsonConvert.DeserializeObject<RootObject>(content);
List<Complain> simpleList = new List<Complain>();
simpleList.Add(jsonObject.ComplainObject);
myList.ItemsSource = simpleList;
The class to deserialize the Json object:
public class RootObject
{
[JsonProperty("complain")]
public Complain ComplainObject { get; set; }
}

Resources