IPP .Net V2 CustomerQuery.ExecuteQuery wont return more than 500 items - intuit-partner-platform

I'm using version 2.1.12.0 of the IPP .Net Dev Kit, and having a problem where when I use ExecuteQuery to return a list of all of the customers for a QBD instance, it will only return the first 500.
In the IPP documentation, it talks about using the ChunkSize and StartPage, but the .net library only allows you to specify the ChunkSize.
Is there a way to make ExecuteQuery return more than 500 records when using this version of the .net library?
var cq = new CustomerQuery() { ActiveOnly = true };
var results = cq.ExecuteQuery<Ipp.Customer>(context);
// results will never contain more than 500.

I found a solution to the problem, the IPP .net SDK does let you specify the IteratorId. It turns out the Item property on the CustomerQuery/QueryBase represents the IteratorId XML field. If you don't specify the Item/IteratorId, then calling ExecuteQuery will always return the first 500 results.
Working code sample below:
var cq = new CustomerQuery() { ActiveOnly = true };
// this fills in the IteratorId that is documented on the IPP website
// if you leave this out, the loop below will run infinitely if there
// are >= 500 records returned.
cq.Item = Guid.NewGuid().ToString("N");
ReadOnlyCollection<Ipp.Customer> cqr = null;
do
{
cqr = cq.ExecuteQuery<Ipp.Customer>(context);
// do something with the results returned here.
}
while (cqr.Count == 500);

Related

"ResourceContainerAccessDenied" returned as value of CloudTask.ExecutionInformation.FailureInformation.Code but not in TaskFailureInformationCodes

I have a .net core 3.0 application using the Microsoft.Azure.Batch 12.0.0 C# nuget package.
I create a job containing one task with a resource file like this (pseudo codeish):
var source = ResourceFile.FromStorageContainerUrl(settings.Input.Container.GetAccessUrl());
var cloudTask = new CloudTask(_taskId, commandline)
{
...
ResourceFiles = new[] { source, },
...
}
await _batchClient.JobOperations.AddTaskAsync("jobid", cloudTask,
cancellationToken: cancellationToken);
when i now request the status of the task
var cloudJob = await _batchClient.JobOperations.GetJobAsync("jobId", cancellationToken:
cancellationToken);
var cloudTask = cloudJob.ListTasks().SingleOrDefault();
var code = cloudTask.ExecutionInformation.FailureInformation,Code
code can be of value "ResourceContainerAccessDenied" if indeed we do not have access to the ResourceCondainer - "ResourceContainerAccessDenied" is not
a member of Microsoft.Azure.Batch.Common.TaskFailureInformationCodes and not documented anywhere as far as i can see.
Is this a bug in the Azure Batch C# SDK? Am i overlooking something? Where can i get a list of all possible code values?
The fact that this error code is not included in the C# SDK is indeed a bug.
I will be fixing this bug as part of an upcoming SDK release (ETA ~1 week).

MSCRM Retrieve Multiple PlugIn limits the other Retrievemultiple uery

In my scenario, there is a plugin (Retrieve Multiple) on Annotation. This plugin is nothing just a part of BLOB Storage solution(used for Attachment Management solution provided by Microsoft). So, it is clear that in our CRM, MicrosoftlLabsAzureBlobstorage is being used.
Now, I am executing a console app which retrieves multiple annotations through Query Expression. When it tries to fetch records around 500 or 600, it throws below error.
{The plug-in execution failed because no Sandbox Hosts are currently
available. Please check that you have a Sandbox server configured and
that it is running.\r\nSystem.ServiceModel.CommunicationException:
Microsoft Dynamics CRM has experienced an error. Reference number for
administrators or support: #AFF51A0F"}
When I fetch specific records or very less records, it executes fine.
So, I my question is that is there any limitation in number for Rerieve Multiple Query ? if retrievemultiple PlugIn exists ?
Is there any other clue that I am not able to find ?
To work around this conflict, in your console application code you may want to try retrieving smaller pages of annotations, say 50 at a time, and loop through the pages to process them all.
This article provides sample code for paging a QueryExpression.
Here's the abridged version of that sample:
// The number of records per page to retrieve.
int queryCount = 3;
// Initialize the page number.
int pageNumber = 1;
// Initialize the number of records.
int recordCount = 0;
// Create the query expression
QueryExpression pagequery = new QueryExpression();
pagequery.EntityName = "account";
pagequery.ColumnSet.AddColumns("name", "emailaddress1");
// Assign the pageinfo properties to the query expression.
pagequery.PageInfo = new PagingInfo();
pagequery.PageInfo.Count = queryCount;
pagequery.PageInfo.PageNumber = pageNumber;
// The current paging cookie. When retrieving the first page,
// pagingCookie should be null.
pagequery.PageInfo.PagingCookie = null;
while (true)
{
// Retrieve the page.
EntityCollection results = _serviceProxy.RetrieveMultiple(pagequery);
if (results.Entities != null)
{
// Retrieve all records from the result set.
foreach (Account acct in results.Entities)
{
Console.WriteLine("{0}.\t{1}\t{2}", ++recordCount, acct.Name,
acct.EMailAddress1);
}
}
// Check for more records, if it returns true.
if (results.MoreRecords)
{
// Increment the page number to retrieve the next page.
pagequery.PageInfo.PageNumber++;
// Set the paging cookie to the paging cookie returned from current results.
pagequery.PageInfo.PagingCookie = results.PagingCookie;
}
else
{
// If no more records are in the result nodes, exit the loop.
break;
}
}
This page has more info and another sample.

Replace GET handler in TableController

In my table controller, I have:
public IQueryable<MyTable> GetAllMyTable()
I would like to replace the above with my own:
[HttpGet, Route("tables/MyTable")]
public IEnumerable<MyTable> GetAllMyTable()
But I get this response when I call it:
HTTP/1.1 405 Method Not Allowed
Somehow the Web API routing does not reach my method.
Why I'm doing this: the original method produces an inefficient Entity Framework SQL query that takes 3 seconds per call on my local test environment. This is running the query captured from SQL Profiler directly in SQL Mgt Studio. An equivalent query takes less than a second to run. Terrible.
Worse, the inefficient EF queries consumes lots of Azure SQL DTUs, tempting you to up your Azure subscription level if you want a quick fix.
Azure Mobile Apps is wonderful, but the multiple layers of abstraction makes it hard to really see what's going on under the hood, and therefore harder to tune.
Any help would be much appreciated.
HTTP/1.1 405 Method Not Allowed
Per my understanding, the error is obvious. You could send the GET HTTP verb to your endpoint tables/MyTable for retrieving the data. You need to check your request against your mobile app backend via fiddler.
Azure Mobile Apps is wonderful, but the multiple layers of abstraction makes it hard to really see what's going on under the hood, and therefore harder to tune.
For the common table controller, it would look like this:
public IQueryable<Message> GetAllMessage()
{
return Query();
}
The Query() method under EntityDomainManager.cs would equal as follows:
IQueryable<TData> query = this.Context.Set<TData>();
if (!includeDeleted)
{
query = query.Where(item => !item.Deleted);
}
return query;
If it deals with the ODATA queries (e.g. $top, $skip, $filter, etc.), the Nested SQL statement would be generated. We could modify the action to clarify it as follows:
public IEnumerable<Message> GetAllMessage(ODataQueryOptions opt)
{
var message = context.Set<Message>();
var query2=opt.ApplyTo(message, new ODataQuerySettings());
return query2.Cast<Message>().ToList();
}
Here's my rather crude attempt at bypassing the Entity Framework/OData plumbing and using direct SQL. (Wouldn't it be great if Dapper is supported!) This one works well, and is faster than the nested SQL that EF produces. The handling of OData is hacky; I have not had time to investigate using OData to extract the values for UpdatedAt, skip, and top.
I'm only using this approach for one method that needs optimisation. This is the method that the Azure Mobile App client calls when doing a pull.
public IEnumerable<MyTable> GetAllMyTable()
{
var qryValues = HttpUtility.ParseQueryString(Request.RequestUri.Query);
var updatedAtFilter = qryValues["$filter"];
var skip = qryValues["$skip"];
var top = qryValues["$top"];
if (updatedAtFilter != null)
{
var r = new Regex(#"^.+datetimeoffset'(?<time>.+)'.+$", RegexOptions.None);
var m = r.Match(updatedAtFilter);
if (m.Success)
{
var updatedAt = m.Groups["time"].Value.Replace("T", " ");
var sqlString = #"SELECT T0.*
FROM MyTable T0
WHERE T0.UpdatedAt >= #UpdatedAt
ORDER BY UpdatedAt, Id
OFFSET #Skip ROWS
FETCH NEXT #Top ROWS ONLY";
var updatedAtParam = new SqlParameter("UpdatedAt", SqlDbType.DateTimeOffset);
updatedAtParam.Value = updatedAt;
var skipParam = new SqlParameter("Skip", SqlDbType.Int);
skipParam.Value = int.Parse(skip);
var topParam = new SqlParameter("Top", SqlDbType.Int);
topParam.Value = int.Parse(top);
var data = _context.Database.SqlQuery<MyTable>(sqlString, new object[] { updatedAtParam, skipParam, topParam }).AsEnumerable<MyTable>();
return data;
}
}
return null;
}

How do you get a syncfusion custom adapter to work with the feathers socket.io client

feathers-client 2.3.0
syncfusion-javascript 15.3.29
I have been trying for awhile to create a syncfusion custom adapter for the feathers socket.io version of it's client. I know I can use rest to get data but in order for me to do offline sync I need to use the feathers-offline-realtime plugin.
Also I am using this in an aurelia project so I am using es6 imports with babel.
Here is a code snippet I have tried, I can post the whole thing if needed.
I am also not sure if just using the Adapter vs UrlAdapter is correct as I need sorting and paging to hit the server and not just to do it locally. I think I can figure that part out if I can at least get some data back.
Note: Per Prince Oliver I am adding a clarification to the question I need to be able to call any methods of the adapter as well besides just proccessQuery such as onSort. When the datagrid calls the onSort method I need to be able to call my api using the feathers socket.io client since it handles socket.io in a special manner for offline capabilities.
import io from 'socket.io-client';
import * as feathers from 'feathers-client';
const baseUrl = 'http://localhost:3030';
const socket = io.connect(baseUrl);
const client = feathers.default()
.configure(feathers.hooks())
.configure(feathers.socketio(socket));
const customers = client.service('customers');
export class FeathersAdapter {
feathersAdapter = new ej.Adaptor().extend({
processQuery: function (ds, query) {
let results
makeMeLookSync(function* () {
results = yield customers.find();
console.log(results);
});
The result is undefined. I have tried several other ways but this one seems like it should work.
REVISED CODE:
I am now getting data but also strange error as noted in the picture when I call
let results = await customers.find();
The process then continues and I get data but when the result variable is returned there is still no data in the grid.
async processQuery(ds, query) {
let baseUrl = 'http://localhost:3030';
let socket = io.connect(baseUrl);
let client = feathers.default()
.configure(feathers.hooks())
.configure(feathers.socketio(socket));
let customers = client.service('customers');
let results = await customers.find();
var result = results, count = result.length, cntFlg = true, ret, key, agg = {};
for (var i = 0; i < query.queries.length; i++) {
key = query.queries[i];
ret = this[key.fn].call(this, result, key.e, query);
if (key.fn == "onAggregates")
agg[key.e.field + " - " + key.e.type] = ret;
else
result = ret !== undefined ? ret : result;
if (key.fn === "onPage" || key.fn === "onSkip" || key.fn === "onTake" || key.fn === "onRange") cntFlg = false;
if (cntFlg) count = result.length;
}
return result;
The processQuery method in the DataManager is used to process the parameter which are set in the ej.Query like skip, take, page before fetching the data. Then the data is fetched asynchronously based on these parameters and fetched data is processed in processResponse method to perform operations like filtering or modifying. The processQuery function operates synchronously and it does not wait for the asynchronous process to complete. Hence the returned data from the API did not get bound on the Grid and throws undefined error.
So, if you are using the socket.io to fetch the data from the API, then the data can be directly bound to the Grid control using the dataSource property. Once the dataSource is updated with the result, it will be reflected in Grid automatically through two-way binding.
[HTML]
<template>
<div>
<ej-grid e-data-source.bind="gridData" e-columns.bind="cols"> </ej-grid>
</div>
</template>
[JS]
let baseUrl = 'http://localhost:3030';
let socket = io.connect(baseUrl);
let client = feathers.default()
.configure(feathers.hooks())
.configure(feathers.socketio(socket));
let customers = client.service('customers');
let results = await customers.find();
this.gridData = results; // bind the data to Grid

Is there a way to filter based on dates in Bing Webmaster API calls?

I am trying to fetch some page stats using GetPageStats method in IWebmasterApi for a url. It returns stats for all the dates. Is there a way to set filter on dates we want the date for? I am sending a GET request through Postman and not using c# program.
After some digging around, I found it is not possible to do a date filter in Bing API calls. Everytime, the entire data (3 months approx) of page stats is sent. The date filter has to be handled in client side.
Hi Not sure this is answering your question, I just start "digging" to develop some app for my use, normally first I read where people complain and fail.
there is some date filter...
You need to see what is the request in C# easy... then reverse engineering and build it in Postman
var oneMonthAgo = DateTime.Now.AddMonths(-1);
var stats = api.GetRankAndTrafficStats("http://yoursite.com/")
.Where(s => s.Date > oneMonthAgo)
.OrderBy(s => s.Date);
https://learn.microsoft.com/en-us/bingwebmaster/getting-started
namespace WebmasterApiExamples
{
using System;
using System.Linq;
using System.ServiceModel;
internal class Program
{
private static void Main(string[] args)
{
var api = new WebmasterApi.WebmasterApiClient();
try
{
var oneMonthAgo = DateTime.Now.AddMonths(-1);
var stats = api.GetRankAndTrafficStats("http://yoursite.com/")
.Where(s => s.Date > oneMonthAgo)
.OrderBy(s => s.Date);
Console.WriteLine("Date\tImpressions\tClicks");
foreach (var value in stats)
{
Console.WriteLine("{0}\t{1}\t{2}", value.Date.ToShortDateString(), value.Impressions, value.Clicks);
}
}
catch (FaultException<WebmasterApi.ApiFault> fault)
{
Console.WriteLine("Failed to add site: {0}", fault.Message);
}
}
}
}