Obtaining string (json) representation a PostData created out of a multiJson object - elasticsearch

The following works right:
var postDataJson = new
{
query = new
{
match_all = new { }
},
sort = new
{
_score = "desc"
}
};
var postData = PostData.MultiJson(new object[] { postDataJson });
Is there a way to obtain a json representation out of postData, out of the box ?

You can use the serializer on the client to get the JSON string representation. Note, you likely want to serialize just the anonymous type, and not PostData, which is used by the client to understand how to serialize the contained type.
var client = new ElasticLowLevelClient();
var postDataJson = new
{
query = new
{
match_all = new { }
},
sort = new
{
_score = "desc"
}
};
Console.WriteLine(client.Serializer.SerializeToString(postDataJson));
Which writes the following to the console
{"query":{"match_all":{}},"sort":{"_score":"desc"}}

Related

Error passing multiple input files, Design Automation Revit dot net core

I had asked my last question regarding this. I have one rfa file and a bigger JSon file as input. When I debug, it looks perfectly passing all values until last line:
WorkItemStatus workItemStatus = await _designAutomation.CreateWorkItemAsync(workItemSpec);
Looks like workItemSpec has some problem. Please have a look at these code fractions and please let me know what is wrong here.
code fraction from ForgeDesignAutomation.js as below:
{
var inputFileField = document.getElementById('inputFile');
if (inputFileField.files.length === 0) { alert('Please select an input file'); return; }
if ($('#activity').val() === null) { alert('Please select an activity'); return };
var file = inputFileField.files[0];
var inputFileField2 = document.getElementById('inputJsonFile');
if (inputFileField2.files.length === 0) { alert('Please select an input file'); return; }
var file2 = inputFileField2.files[0];
let activityId = $('#activity').val();
if (activityId == null)
{
alert('Please select an activity'); return
};
if (activityId.toLowerCase() === "_da4ractivity+dev")
{
startConnection(function () {
var formData = new FormData();
formData.append('inputFile', file);
formData.append('inputJsonFile', file2);
formData.append('data', JSON.stringify({
activityName: $('#activity').val(),
browerConnectionId: connectionId
}));
writeLog('Uploading input file...');
$.ajax({
url: 'api/forge/designautomation/workitems',
data: formData,
processData: false,
contentType: false,
type: 'POST',
success: function (res)
{
writeLog('Workitem started: ' + res.workItemId);
}
});
});
}
}```
code fraction from "CreateActivity" in DesignAutomationController.cs
``` Parameters = new Dictionary<string, Parameter>()
{
{ "inputFile", new Parameter() { Description = "input file", LocalName = "$(inputFile)", Ondemand = false, Required = true, Verb = Verb.Get, Zip = false } },
{ "inputJsonFile", new Parameter() { Description = "input Json file", LocalName = "$(inputJsonFile)", Ondemand = false, Required = true, Verb = Verb.Get, Zip = false } },
{ "outputFile", new Parameter() { Description = "output file", LocalName = "outputFile." + engineAttributes.extension, Ondemand = false, Required = true, Verb = Verb.Put, Zip = false } }
}```
code fraction from "StartWorkitem" in DesignAutomationController.cs
``` [HttpPost]
[Route("api/forge/designautomation/workitems")]
public async Task<IActionResult> StartWorkitem([FromForm]StartWorkitemInput input)
{
// basic input validation
JObject workItemData = JObject.Parse(input.data);
string activityName = string.Format("{0}.{1}", NickName, workItemData["activityName"].Value<string>());
string browerConnectionId = workItemData["browerConnectionId"].Value<string>();
// save the file on the server
var fileSavePath0 = Path.Combine(_env.ContentRootPath, Path.GetFileName(input.inputFile.FileName));
using (var stream0 = new FileStream(fileSavePath0, FileMode.Create)) await input.inputFile.CopyToAsync(stream0);
var fileSavePath1 = Path.Combine(_env.ContentRootPath, Path.GetFileName(input.inputJsonFile.FileName));
using (var stream1 = new FileStream(fileSavePath1, FileMode.Create)) await input.inputJsonFile.CopyToAsync(stream1);
//---------------------------------------------------------------------------------------------------------------------
// OAuth token
dynamic oauth = await OAuthController.GetInternalAsync();
// upload file to OSS Bucket
// 1. ensure bucket existis
string bucketKey = NickName.ToLower() + "-designautomation";
BucketsApi buckets = new BucketsApi();
buckets.Configuration.AccessToken = oauth.access_token;
try
{
PostBucketsPayload bucketPayload = new PostBucketsPayload(bucketKey, null, PostBucketsPayload.PolicyKeyEnum.Transient);
await buckets.CreateBucketAsync(bucketPayload, "US");
}
catch { };
// in case bucket already exists
// 2. upload inputFile
string inputFileNameOSS0 = string.Format("{0}_input_{1}", DateTime.Now.ToString("yyyyMMddhhmmss"), Path.GetFileName(input.inputFile.FileName)); // avoid overriding
string inputFileNameOSS1 = string.Format("{0}_inputJson_{1}", DateTime.Now.ToString("yyyyMMddhhmmss"), Path.GetFileName(input.inputJsonFile.FileName)); // avoid overriding
//string inputFileNameOSS = Path.GetFileName(input.inputFile.FileName); // avoid overriding
ObjectsApi objects = new ObjectsApi();
objects.Configuration.AccessToken = oauth.access_token;
using (StreamReader streamReader = new StreamReader(fileSavePath0))
await objects.UploadObjectAsync(bucketKey, inputFileNameOSS0, (int)streamReader.BaseStream.Length, streamReader.BaseStream, "application/octet-stream");
System.IO.File.Delete(fileSavePath0);// delete server copy
// prepare workitem arguments
// 1. input file
XrefTreeArgument inputFileArgument = new XrefTreeArgument()
{
Url = string.Format("https://developer.api.autodesk.com/oss/v2/buckets/{0}/objects/{1}", bucketKey, inputFileNameOSS0),
Headers = new Dictionary<string, string>()
{
{ "Authorization", "Bearer " + oauth.access_token }
}
};
using (StreamReader streamReader1 = new StreamReader(fileSavePath1))
await objects.UploadObjectAsync(bucketKey, inputFileNameOSS1, (int)streamReader1.BaseStream.Length, streamReader1.BaseStream, "application/octet-stream");
System.IO.File.Delete(fileSavePath1);// delete server copy
// 1. input Json file
XrefTreeArgument inputJsonArgument = new XrefTreeArgument()
{
Url = string.Format("https://developer.api.autodesk.com/oss/v2/buckets/{0}/objects/{1}", bucketKey, inputFileNameOSS1),
Headers = new Dictionary<string, string>()
{
{ "Authorization", "Bearer " + oauth.access_token }
}
};
// 3. output file
string outputFileNameOSS = string.Format("{0}_output_{1}", DateTime.Now.ToString("yyyyMMddhhmmss"), Path.GetFileName(input.inputFile.FileName)); // avoid overriding
XrefTreeArgument outputFileArgument = new XrefTreeArgument()
{
Url = string.Format("https://developer.api.autodesk.com/oss/v2/buckets/{0}/objects/{1}", bucketKey, outputFileNameOSS),
Verb = Verb.Put,
Headers = new Dictionary<string, string>()
{
{"Authorization", "Bearer " + oauth.access_token }
}
};
// prepare & submit workitem
string callbackUrl = string.Format("{0}/api/forge/callback/designautomation?id={1}&outputFileName={2}", OAuthController.GetAppSetting("FORGE_WEBHOOK_URL"), browerConnectionId, outputFileNameOSS);
WorkItem workItemSpec = new WorkItem()
{
ActivityId = activityName,
Arguments = new Dictionary<string, IArgument>()
{
{ "inputFile", inputFileArgument },
{ "inputJsonFile", inputJsonArgument },
{ "outputFile", outputFileArgument },
{ "onComplete", new XrefTreeArgument { Verb = Verb.Post, Url = callbackUrl } }
}
};
WorkItemStatus workItemStatus = await _designAutomation.CreateWorkItemAsync(workItemSpec);
return Ok(new { WorkItemId = workItemStatus.Id });
}```
```/// <summary>
/// Input for StartWorkitem
/// </summary>
public class StartWorkitemInput[![enter image description here][1]][1]
{
public IFormFile inputFile { get; set; }
public IFormFile inputJsonFile { get; set; }
public string data { get; set; }
} ```
[![enter image description here][1]][1]
[1]: https://i.stack.imgur.com/GktUC.png
I noticed your activity defines the "localName" of "inputFile"/"inputJsonFile" to be "$(inputFile)"/"$(inputJsonFile)"
Parameters = new Dictionary<string, Parameter>()
{
{ "inputFile", new Parameter() { Description = "input file", LocalName = "$(inputFile)", Ondemand = false, Required = true, Verb = Verb.Get, Zip = false } },
{ "inputJsonFile", new Parameter() { Description = "input Json file", LocalName = "$(inputJsonFile)", Ondemand = false, Required = true, Verb = Verb.Get, Zip = false } }
}
This could cause some issue when resolving the naming of inputs during the job process. I would suggest you provide a concrete filename as WorkItem argument's localname and try again. For example:
XrefTreeArgument inputJsonArgument = new XrefTreeArgument()
{
Url = string.Format("https://developer.api.autodesk.com/oss/v2/buckets/{0}/objects/{1}", bucketKey, inputFileNameOSS1),
Headers = new Dictionary<string, string>()
{
{ "Authorization", "Bearer " + oauth.access_token }
},
// Note: if your appbunldes(addin) uses this json, this is the name your addin should know
LocalName = "inputJson.json"
};

Bind mongodb json to kendo grid

I am very new to kendo UI and getting similar challenges as below(except I dont mind having a fixed data structure for grid):
How to pass MongoDb Json value to KendoUI grid using webservice method
$("#grid").kendoGrid({
dataSource: {
transport: {
read: {
url: "http://localhost:8080/urlPath",
dataType: "json",
}
},
schema: {
data: "score"
}
columns:[{
field: "physics"
},
{
field: "chemistry",
}],
});
Json looks like:
[{"score"[{"physics:99", "chemistry" :95}]},{"score"[{"physics:99", "chemistry" :95}]}]
I am struggling from last few days and have tried approaches like:
Convert dbcursor object into json
http://www.codeconfuse.com/2014/03/mongodb-convert-data-getting-from.html
Here's the related code from above URL:
while(cursor.hasNext()) {
BasicDBObject obj = (BasicDBObject) cursor.next();
jsonobj = new JSONObject();
BasicDBList name = (BasicDBList) obj.get("Name");
jsonobj.put("Incident Date", obj.getString("Incident Date"));
jsonarray.put(jsonobj);
}
return jsonarray;
JSON json =new JSON();
String serialize = json.serialize(cursor);
But the kendo Grid seems to be rejecting it. Please assist.
My issue got resolved by formatting the json returned in an appropriate format as below:
From:
[{"score"[{"physics:99", "chemistry" :95}]},{"score"[{"physics:99", "chemistry" :95}]**}]**
To:
[{"physics:99", "chemistry" :95}]},{"score"[{"physics:99", "chemistry" :95}]
So, basically I extracted the score object, put into my own hashmap and then returned the json object. See below for sample code:
*
DB db = mongoClient.getDB( "test" );
DBCollection coll = db.getCollection("mycol");
BasicDBObject fields = new BasicDBObject("score",true).append("_id",false);
BasicDBObject query = new BasicDBObject();
DBCursor cursor = coll.find(query,fields)
while (cursor.hasNext()) {
DBObject obj = cursor.next();
BasicDBList scoreList = (BasicDBList) obj.get("score");
for (int i = 0; i < scoreList.size(); i++) {
BasicDBObject scoreObj = (BasicDBObject) scoreList.get(i);
String physics = scoreObj.getString("physics");
String chemistry = scoreObj.getString("chemistry");
//ofcourse we need another innerloop here to iterate through
//all the rows of the returned list.
innerMap.add("physics",physics);
innerMap.add("chemistry",chemistry);
}
return new Gson().gson(map.values);
}
*

Import Parse class to algolia

I am trying to import my class (2500 records) from Parse.com into an Algolia index. There is a limit of 100 records by default which obviously is not working for me. Even if I use query.limit = 1000;
How can the below code be used to import my whole class?
Parse.Cloud.define("createIndex", function(request, response) {
var algoliasearch = require('cloud/algoliasearch.parse.js');
var client = algoliasearch('9PsdfsdWVU7', '3b24e897bfb4esdfsdfsdf209e25c28');
var index = client.initIndex('exercises');
console.log("running");
var objectsToIndex = [];
//Create a new query for Contacts
var query = new Parse.Query('Exercises');
query.limit = 1000;
// Find all items
query.find({
success: function(exercises) {
// prepare objects to index from contacts
objectsToIndex = exercises.map(function(exercise) {
// convert to regular key/value JavaScript object
exercise = exercise.toJSON();
// Specify Algolia's objectID with the Parse.Object unique ID
exercise.objectID = exercise.objectId;
return exercise;
});
// Add or update new objects
index.saveObjects(objectsToIndex, function(err, content) {
if (err) {
throw err;
}
console.log('Parse<>Algolia import done');
});
response.success("worked");
},
error: function(err) {
response.error("failed");
throw err;
}
});
});
Parse.com has a find limit, and all other limitations when you want to "get all the objects", you can find more information here: https://parse.com/docs/js/guide#performance-limits-and-other-considerations
For your current issue you could do this:
Parse.Cloud.define("createIndex", function(request, response) {
var algoliasearch = require('cloud/algoliasearch.parse.js');
var client = algoliasearch('9PsdfsdWVU7', '3b24e897bfb4esdfsdfsdf209e25c28');
var index = client.initIndex('exercises');
console.log("running");
//Create a new query for Contacts
var Exercises = Parse.Object.extend('Exercises');
var query = new Parse.Query(Exercises);
var skip = -1000;
var limit = 1000;
saveItems();
function saveItems() {
skip += limit;
query.skip(skip + limit);
query.limit(limit);
query.find({success: sucess, error: error});
}
function sucess(exercices) {
if (exercices.length === 0) {
response.success("finished");
return;
}
exercises = exercises.map(function(exercise) {
// convert to regular key/value JavaScript object
exercise = exercise.toJSON();
// Specify Algolia's objectID with the Parse.Object unique ID
exercise.objectID = exercise.objectId;
return exercise;
});
index.saveObjects(exercises, function(err) {
if (err) {
throw err;
}
console.log('Parse<>Algolia import done');
response.success("worked");
saveItems();
});
}
function error() {
response.error("failed");
throw err;
}
});

Cloud Code, complex query with adding a key-value pair before response

I want to get a batch of User objects using Cloud Code. And before collection of objects will send to client they have to take a unique number.
Now it's looking like this
Parse.Cloud.define("getUsers", function(request, response)
{
var query = new Parse.Query(Parse.User);
var mode = parseInt(request.params.mode);
var username = request.params.username;
var skip = parseInt(request.params.skip);
var limit = parseInt(request.params.limit);
if(mode==1)
{
query.notEqualTo("fbLogged",true)
.descending("score")
.notEqualTo("username",username)
.skip(skip)
.limit(limit);
query.find({
success: function(objects)
{
var i = 0;
objects.forEach(function(item)
{
item["rank"]=skip+i; //setting a unique number (position based on score)
});
response.success(objects);
},
error: function(error)
{
response.error(error);
}
});
}
});
And how I use it on client side...
void Start () {
IDictionary<string, object> dict = new Dictionary<string, object>();
dict.Add("username", "477698883");
dict.Add("skip", "300");
dict.Add("limit", "50");
dict.Add("mode", "1");
ParseCloud.CallFunctionAsync<IEnumerable<object>>("getUsers", dict).ContinueWith(t =>
{
if(t.IsCanceled || t.IsFaulted)
{
foreach (var e in t.Exception.InnerExceptions)
Debug.LogError(e.Message);
}
else
{
var r = t.Result;
List<ParseUser> users = new List<ParseUser>();
foreach(var o in r)
{
try {
ParseObject pu = (ParseObject)o;
foreach (var key in pu.Keys)
Debug.Log(key + " = " + pu[key]);
}
catch(Exception e)
{
Debug.LogError(e.Message);
}
break;
}
}
});
}
As you see I just display first of received objects.
And it gives me this data.
But where is the "rank" field?
I just found solution. Each ParseObject which will send to Client by response.success() have to be saved on Parse before sent.
Now my code looks like this and it works
Parse.Cloud.define("getUsers", function(request, response)
{
var query = new Parse.Query(Parse.User);
var mode = parseInt(request.params.mode);
var username = request.params.username;
var skip = parseInt(request.params.skip);
var limit = parseInt(request.params.limit);
if(mode==1)
{
query.notEqualTo("fbLogged",true)
.descending("score")
.notEqualTo("username",username)
.skip(skip)
.limit(limit);
query.find({
success: function(objects)
{
for(var i = 0; i<objects.length; i++)
{
objects[i].set("rank", skip+i);
objects[i].save();
}
response.success(objects);
},
error: function(error)
{
response.error(error);
}
});
}
});

Kendo UI grid databinding using mvvm pattern

I am new to Kendo UI, i want to bind kendo ui grid using MVVM pattern, and my datasource is sharepoint list. so i am calling sharepoint list data through CSOM javascript code. I tried different solution but nothing seems to working. I have collection of data from sharepoint list.
var divisionListData = [];
//var divisionsViewModel;
var viewModel = kendo.observable({
isVisible: true,
onSave: function (e) {
alert('hi');
kendoConsole.log("event :: save(" + kendo.stringify(e.values, null, 4) + ")");
},
divisions: new kendo.data.DataSource({
// schema: {
data: divisionListData,
schema: {
data: "rows",
model: {
fields:
{
ID: { type: "string" },
DivisionName: { type: "string" },
DivisionCode: { type: "string" },
OpenDate: { type: "datetime" },
CloseDate: { type: "datetime" },
Description: { type: "string" },
}
}
},
batch: true,
transport: {
read: function (e) {
return divisionListData;
}
})
})
function ReadList() {
//this.set("isDisabled", false);
var clientContext = new SP.ClientContext.get_current();
// denote that we will be performing operations on the current web
var web = clientContext.get_web();
// denote that we will be querying the "Business Divisions" custom SharePoint list
var divisionsList = web.get_lists().getByTitle("Divisions");
// create a CAML query (blank means just return all items)
var camlQuery = new SP.CamlQuery();
// denote that the operation we want to perform is getItems() on the list
var divisionsListItems = divisionsList.getItems(camlQuery);
var fields = 'Include(ID,DivisionCode, DivisionName, OpenDate, CloseDate, Description)';
clientContext.load(divisionsListItems, fields);
clientContext.executeQueryAsync(function () {
// get the list item enumerator
var listItemEnumerator = divisionsListItems.getEnumerator();
// loop through the items in our custom
// "Divisions" SharePoint list
var listItem;
while (listItemEnumerator.moveNext()) {
var division = new Division();
// get the list item we are on
listItem = listItemEnumerator.get_current();
// get the divisions
division.ID = listItem.get_item("ID");
// var lookup_DivisionCode = listItem.get_item("DivisionCode").get_lookupValue();
//lookup_DivisionCode.get_l
var divisionLookupField = new SP.FieldLookupValue();
divisionLookupField = listItem.get_item("DivisionCode");
//var test = divisionLookupField.$2d_1;
if (divisionLookupField != null)
division.DivisionCode = divisionLookupField.$2d_1;
division.DivisionName = listItem.get_item("DivisionName");
division.Description = listItem.get_item("Description");
division.OpenDate = listItem.get_item("OpenDate");
division.CloseDate = listItem.get_item("CloseDate");
divisionListData.push(division);
kendo.bind($("body"), viewModel);
}
})
}
You are pretty close, instead of returning the array inside the read: function(e), you need to call
e.success(yourArrayOfData);

Resources