SugarCrm REST .Net wrapper - c#

I am planning to write a simple SugarCrm .Net client.
Could anyone give me a pointer to a .Net wrapper/library for the SugarCrm REST api?
//lasse

Realize this is old, but in case anyone stumbles across this looking for a .NET wrapper for newer version of the web service (SugarCRM > 6.7), here is a wrapper I am currently building https://github.com/dlively1/SugarSharp

There is a wrapper that uses SOAP called CandyWrapper, which is a bit old but could help you with a starting point on building your own.
http://developers.sugarcrm.com/wordpress/2011/08/10/web-services-in-your-own-language-part-6-candywrapper-for-net/

I also realize this is old, but for SugarCRM CE 6.x I created SugarRestSharp. The sample I give below is in json, but the request would be in C# models. This implements get_entry_list SugarCrm Rest API method.
Passing request to RestSharp:
dynamic data = new
{
session = sessionId,
module_name = moduleName,
query = queryString,
order_by = string.Empty,
offset = 0,
select_fields = selectFields,
link_name_to_fields_array = string.Empty,
max_results = maxCountResult,
deleted = 0,
favorites = false
};
var client = new RestClient(url);
var request = new RestRequest(string.Empty, Method.POST);
string jsonData = JsonConvert.SerializeObject(data);
request.AddParameter("method", "get_entry_list");
request.AddParameter("input_type", "json");
request.AddParameter("response_type", "json");
request.AddParameter("rest_data", jsonData);
var response = client.Execute(request);
Request in json
{
"session": "olgg6hf5sqi6hk9u3tgpafbn66",
"module_name": "Accounts",
"query": "",
"order_by": "",
"offset": 0,
"select_fields": [
"name",
"industry",
"website",
"shipping_address_city",
"id"
],
"link_name_to_fields_array": "",
"max_results": 10,
"deleted": 0,
"favorites": false
}
Response in json
{
"result_count": 10,
"total_count": "58",
"next_offset": 10,
"entry_list": [
{
"id": "1e0eec64-8cc6-58ff-57f1-58533731b145",
"module_name": "Accounts",
"name_value_list": {
"name": {
"name": "name",
"value": "New SugarRestSharp Acccount 1 10397"
},
"industry": {
"name": "industry",
"value": "Manufacturing"
},
"website": {
"name": "website",
"value": "www.sugarrestsharp1.com"
},
"shipping_address_city": {
"name": "shipping_address_city",
"value": "Los Angeles"
},
"id": {
"name": "id",
"value": "1e0eec64-8cc6-58ff-57f1-58533731b145"
}
}
},
......... (other 9 items truncated)
],
"relationship_list": [
]
}
For more implementation and wiki check SugarRestSharp: https://github.com/mattkol/SugarRestSharp

Related

Elastic search count query based on field with value containing filesystem path

I asked this question earlier question here
However I realized my mistake very soon as I tried the solution with more data.
So I am back to square one. So I am hoping to ask this question again and get more insights.
My task is still the same but more precisely to get counts of documents based on multiple values including a path field that contains values like system file paths.
My example data look likes this:
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 3,
"relation": "eq"
},
"max_score": 15.9074545,
"hits": [
{
"_index": "stage-data-20210728115212095",
"_type": "_doc",
"_id": "fil.31c425766287497ec5a508d995d1ce36",
"_score": 15.9074545,
"_source": {
"header_action": "uploaded",
"partition": 7,
"offset": 11382619,
"volumeId": "vol.e144f0bc59914725528f08d995ebd8c3",
"lambdaLagMs": 0,
"id": "fil.31c425766287497ec5a508d995d1ce36",
"name": "sampleFile.txt",
"parentFolderId": "fol.6357e749063445b0c5a408d995d1ce36",
"volumeName": "test-vol-b2ee569932dd470788ebc70e6f15bf36",
"type": "text/plain",
"path": "/test_Folder-ed9cc1294ba841f98fa986be7ac38813/Folder1/sampleFile.txt",
"timeCreated": "2021-10-23T06:10:45.287Z",
"timeModified": "2021-10-23T06:10:45.287Z",
"sizeInBytes": 26,
"isUploaded": true,
"archiveStatus": "None",
"storageTier": "Standard",
"eTag": "ed6a6e795564952d4d9707e7dc91c6a6",
"format": "TXT",
"status": "Available",
"recordDateTime": "2021-10-23 06:10:47.268",
"recordTurnAroundTimeMs": 2629.375,
"dataType": "File"
}
},
{
"_index": "stage-data-20210728115212095",
"_type": "_doc",
"_id": "fil.6075863c66464a2cc5a608d995d1ce36",
"_score": 15.500043,
"_source": {
"header_action": "uploaded",
"partition": 15,
"offset": 11393012,
"volumeId": "vol.e144f0bc59914725528f08d995ebd8c3",
"lambdaLagMs": 0,
"id": "fil.6075863c66464a2cc5a608d995d1ce36",
"name": "testFile.txt",
"parentFolderId": "fol.230c9c8861fa40640cc808d995d1b210",
"volumeName": "test-vol-b2ee569932dd470788ebc70e6f15bf36",
"type": "text/plain",
"path": "/test_Folder-ed9cc1294ba841f98fa986be7ac38813/testFile.txt",
"timeCreated": "2021-10-23T06:10:45.286Z",
"timeModified": "2021-10-23T06:10:45.286Z",
"sizeInBytes": 23,
"isUploaded": true,
"archiveStatus": "None",
"storageTier": "Standard",
"eTag": "2b9f6fc56449eb68b4fa5c5da127c5be",
"format": "TXT",
"status": "Available",
"recordDateTime": "2021-10-23 06:10:47.284",
"recordTurnAroundTimeMs": 2628.936,
"dataType": "File"
}
},
{
"_index": "stage-data-20210728115212095",
"_type": "_doc",
"_id": "fil.27a781dc81554811576308d995d1ce3c",
"_score": 15.500043,
"_source": {
"header_action": "uploaded",
"partition": 6,
"offset": 11377991,
"volumeId": "vol.e144f0bc59914725528f08d995ebd8c3",
"lambdaLagMs": 0,
"id": "fil.27a781dc81554811576308d995d1ce3c",
"name": "smallfile.txt",
"parentFolderId": "fol.6ac9ecb11dae4ebd576208d995d1ce3c",
"volumeName": "test-vol-b2ee569932dd470788ebc70e6f15bf36",
"type": "text/plain",
"path": "/test_Folder-ed9cc1294ba841f98fa986be7ac38813/Folder1/Folder2/smallfile.txt",
"timeCreated": "2021-10-23T06:10:45.294Z",
"timeModified": "2021-10-23T06:10:45.294Z",
"sizeInBytes": 1249,
"isUploaded": true,
"archiveStatus": "None",
"storageTier": "Standard",
"eTag": "c6e9338f9e54e39b52dd853908a1aecd",
"status": "Available",
"recordDateTime": "2021-10-23 06:10:47.276",
"recordTurnAroundTimeMs": 2629.8689999999997,
"dataType": "File"
}
}
]
}
}
I am trying to get the count of documents using NEST c# library. Here is my sample code:
var elasticSettings = new ConnectionSettings(new Uri("https://myelasticurl/"))
.DefaultIndex("stage-data");
var client = new ElasticClient(elasticSettings);
var folderPrefix = "/test_Folder-ed9cc1294ba841f98fa986be7ac38813/Folder1/Folder2/";
Func<CountDescriptor<dynamic>, ICountRequest> countQueryFilter = q => q.Query(q =>
q.Match(m => m.Field("volumeId").Query("vol.e144f0bc59914725528f08d995ebd8c3"))
&& q.Match(m => m.Field("dataType").Query("File")) &&
q.Wildcard(m => m.Field("path").Value($"{folderPrefix}*")));
var countResponse= client.CountAsync(countQueryFilter);
Console.WriteLine(countResponse.Result.Count);
Here is the mapping of the path field
{
"stage-data-20210728115212095": {
"mappings": {
"path": {
"full_name": "path",
"mapping": {
"path": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
},
"rawlower": {
"type": "keyword",
"normalizer": "lowercase"
},
"tree": {
"type": "text",
"analyzer": "path_analyzer"
},
"tree_level": {
"type": "token_count",
"store": true,
"analyzer": "path_level_analyzer",
"enable_position_increments": false
}
},
"analyzer": "ngram_analyzer"
}
}
}
}
}
}
If I only search for volumeId and dataType, I can get the results just fine. Even for path field, for the dataset where I have files at the root folder for example /folder1/mytxt.txt etc, the query works.
Only when I have files under multiple level deep like in the above example when I try to search for path like this /test_Folder-ed9cc1294ba841f98fa986be7ac38813/Folder1/Folder2/, I get 0 result count.
At this point I am not sure if I need to tweak the mapping settings of this field to make it more search friendly something like suggested here or if I am just using the wrong method to search this.
Please note I did try following methods for the path searching:
WildCard
Term
Regexp
Match
I got the same results of 0 record returned.
Please suggest what I am missing, thanks for your help in advance.
I am using NEST 7.13.0 on .NET core 3.1.
Regards,
Vikas
One of my colleague helped with this and the solution works nicely.
Here is the sample code:
var elasticSettings = new ConnectionSettings(new Uri("https://myelasticurl/"))
.DefaultIndex("stage-data");
var client = new ElasticClient(elasticSettings);
var folderPrefix = "/test_Folder-ed9cc1294ba841f98fa986be7ac38813/Folder1/Folder2/";
Func<CountDescriptor<dynamic>, ICountRequest> countQueryFilter = q => q.Query(q =>
q.Match(m => m.Field("volumeId").Query("vol.e144f0bc59914725528f08d995ebd8c3"))
&& q.Match(m => m.Field("dataType").Query("File")) &&
q.Prefix(m => m.Field("path.raw").Value($"{folderPrefix}")));
var countResponse= client.CountAsync(countQueryFilter);
Console.WriteLine(countResponse.Result.Count);
So basically needed to use Prefix filter along with path.raw that is defined in the mapping.

Serializing FeatureCollection GEOJSON in .NET Core

I am trying to serialize a FeatureCollection so I can pass it as a request body. To do this I am using a NetTopologySuite.IO.GeoJSON package and using the instruction they provide on their github page. The problem is, when hitting the jsonSerializer.Serialize method, I get an error saying: {"At least one element in the source array could not be cast down to the destination array type."} System.Exception {System.InvalidCastException}.
My method looks like this:
private async Task<IEnumerable<VehicleArea>> GetVehiclesInAreas(FeatureCollection areas)
{
var uri = $"www.someurl/getByArea";
using var httpClient = new HttpClient();
string stringifiedAreas;
var jsonSerializer = GeoJsonSerializer.CreateDefault();
using (var stringWriter = new StringWriter())
using (var jsonwriter = new Newtonsoft.Json.JsonTextWriter(stringWriter))
{
jsonSerializer.Serialize(jsonwriter, areas);
stringifiedAreas = stringWriter.ToString();
}
StringContent content = new StringContent(stringifiedAreas, Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync(uri, content);
}
The GEOSJON object I am passing in the request body of my controller, that ends up being the areas FeatureCollection provided to the given method looks like this:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": 16,
"geometry": {
"type": "GeometryCollection",
"geometries": [
{
"type": "Polygon",
"coordinates": [
[
[
12.1234,
55.1234
],
[
12.7,
55.7],
[
12.8,
55.8
],
[
12.9,
55.9
],
[
12.1234,
55.1234
]
]
]
}
]
}
},
{
"type": "Feature",
"id": 16,
"geometry": {
"type": "GeometryCollection",
"geometries": [
{
"type": "Polygon",
"coordinates": [
[
[
12.1234,
55.1234
],
[
12.7,
55.7],
[
12.8,
55.8
],
[
12.9,
55.9
],
[
12.1234,
55.1234
]
]
]
}
]
}
}
]
}
Finally, here is a snippet of how the areas object looks like during runtime:
Thanks to #FObermaier's comment, I was able to implement a solution. As he mentioned, I am using a NetTopologySuite.IO.GeoJSON4STJ package which uses the System.Text.Json. By refactoring my code to use System.Text.Json.JsonSerializer, I was able to make it work. For anyone encountering the same issue, make sure to also pass the options object with the GeoJsonConverter factory added as a converter. Here is the code example:
var options = new JsonSerializerOptions();
options.Converters.Add(new NetTopologySuite.IO.Converters.GeoJsonConverterFactory());
var serialized = JsonSerializer.Serialize(areas, options);
var stringifiedAreas = serialized.ToString();

Sendgrid c# Template Substitution

I am unable to get word substitution to work consistently with sendgrid v3 api in c#. Sometimes the tags will be substituted, other times they will not. I am at a loss as to what causes this. Can anyone see any obvious errors in my code?
String apiKey = "KEY";
dynamic sg = new SendGridAPIClient(apiKey);
Email from = new Email("info#example.com");
String subject = "Hello World from the SendGrid CSharp Library";
Email to = new Email("example#gmail.com");
Content content = new Content("text/html", " ");
to.Name = "Joe";
Mail mail = new Mail(from, subject, to, content);
mail.TemplateId = "dfea45f3-d608-4860-9f38-c7d444qwrqwc1f";
Personalization subs = new Personalization();
subs.AddTo(to);
subs.AddSubstitution("*|url|*", "http://asdasdasd.com");
subs.AddSubstitution("*|username|*", "MrUsername");
mail.AddPersonalization(subs);
dynamic response = sg.client.mail.send.post(requestBody: mail.Get());
Remove the Personalization and add the following
mail.Personalization[0].AddSubstitution("*|url|*", "http://asdasdasd.com");
mail.Personalization[0].AddSubstitution("*|username|*", "MrUsername");
or see code samples here
I have found the issue my side. I think yours is the same. When you look at mail object before sending you will find there are 2 personification items in the array. You do this subs.AddTo(to); then later on mail.AddPersonalization(subs); This creates 2 email to in the personalization array - my example of the wrong payload was:
{
"from": {
"email": "no-reply#chromasports.com"
},
"subject": "",
"personalizations":
[
{
"to": [{
"email": "email#gmail.com"
}]
},
{
"to": [{
"email": "email#gmail.com"
}],
"substitutions": {
":token": "http://alabala.com/auth/reset-password#token=or514rqHTeLjtjlN6WRppOu53yJJ64nSzcK86GF6Ite2BaZRa58YPMfTmM0wzQs4tMLbHy8YlpieDVBae1aD99TKnMh7wYNOE2nmu8gWePQoZiWhbFLomVBvApHA1fuxIxQ1elui2QXAmGPtwDdvVOgvAiSF3HQteuvFwP5kXUnXXEeddYLIUHqJCDrATiOsSgxvcpKmhXhrhx78ns49f4hakGlLMncNgBuMGmL3wCduY9f22hjCs9tbIPq5h5V"
}
}
],
"content": [{
"type": "text/html",
"value": "\u003chtml\u003e\u003cbody\u003eHTML content\u003c/body\u003e\u003c/html\u003e"
}],
"template_id": "unique id"
}
'
Check your payload and to fix it try mail.AddPersonalization[0] = subs; Hope this solves your issue

How to post data in RestSharp?

How can I post data in RestSharp ? I am very new to RestSharp and dont quite understand the process.
I am familar with Get Requests, which I have written API tests for with no problems.
Using the below example I want to post the Order Qty:
"name": "PostToCurrentBasket",
"class": [
"PostToCurrentBasket"
],
"method": "POST",
"href": "*",
"title": "Add Product to Current Basket",
"type": "application/json",
"fields": [
{
"name": "ProductId",
"type": "text",
"value": 101112,
"title": "Product ID"
},
{
"name": "Quantity",
"type": "number",
"value": 0,
"title": "Order Qty"
}
]
}
],
What I have so far:
var request = new RestRequest("baskets/current/", Method.POST);
Do I need to be using .AddBody and if so how do I use this correctly?
request.RequestFormat = DataFormat.Json; // If you want it to be json
request.AddBody(new { Name = "Foo", LastName = "Bar" }); // Any object that can be serialized
client.Execute(request);

Deserialize complex JSON object using ASP.NET?

I've successfully created code that serializes a complex javascript object and posts it to an ASP.NET page. I can get the JSON string using Request.Form and the result looks like this (I've added indentation for readability):
{
"gasterPerStolPerVecka": {
"name": "gasterPerStolPerVecka",
"keyValue_id": "2",
"set_id": "1",
"containerElement": "#gasterPerStolPerVecka",
"keyValueComponents": [
{
"name": "gasterPerStolPerVecka_guestsPerWeek",
"value": "200"
},
{
"name": "gasterPerStolPerVecka_numberOfChairs",
"value": "100"
}
],
"keyValueUnitText": "gäster/stol per vecka",
"keyValueCalculationMethod": "divide",
"isValid": true,
"result": 2
},
"tillgangligaStolstimmarPerVecka": {
"name": "tillgangligaStolstimmarPerVecka",
"keyValue_id": "1",
"set_id": "1",
"containerElement": "#tillgangligaStolstimmarPerVecka",
"keyValueComponents": [
{
"name": "tillgangligaStolstimmarPerVecka_openHoursPerWeek",
"value": "35"
},
{
"name": "tillgangligaStolstimmarPerVecka_numberOfChairs",
"value": "100"
}
],
"keyValueUnitText": "stolstimmar/vecka",
"keyValueCalculationMethod": "multiply",
"isValid": true,
"result": 3500
},
"planeradIntaktPerTillgangligStolOchVecka": {
"name": "planeradIntaktPerTillgangligStolOchVecka",
"keyValue_id": "",
"set_id": "",
"containerElement": "#planeradIntaktPerTillgangligStolOchVecka",
"keyValueComponents": [
{
"name": "planeradIntaktPerTillgangligStolOchVecka_weeklyRevenue",
"value": ""
},
{
"name": "planeradIntaktPerTillgangligStolOchVecka_numberOfChairs",
"value": "100"
}
],
"keyValueUnitText": "kr",
"keyValueCalculationMethod": "divide",
"isValid": false,
"result": null,
"errorText": "Ofullständigt underlag för beräkning."
},
"planeradIntaktPerTillgangligaStolstimmar": {
"name": "planeradIntaktPerTillgangligaStolstimmar",
"keyValue_id": "",
"set_id": "",
"containerElement": "#planeradIntaktPerTillgangligaStolstimmar",
"keyValueComponents": [
{
"name": "planeradIntaktPerTillgangligaStolstimmar_weeklyRevenue",
"value": ""
},
{
"name": "planeradIntaktPerTillgangligaStolstimmar_openHoursPerWeek",
"value": "35"
},
{
"name": "planeradIntaktPerTillgangligaStolstimmar_numberOfChairs",
"value": "100"
}
],
"keyValueUnitText": "kr",
"keyValueCalculationMethod": "divide_divide",
"isValid": false,
"result": null,
"errorText": "Ofullständigt underlag för beräkning."
}
}
Now I try to deserialize this on the server side, but it's difficult. I keep getting the error:
[NullReferenceException: Object reference not set to an instance of an object.]
I don't know where to start looking for errors?
Thanks in advance!
/Thomas Kahn
use stringify instead serialization
You need to use a deserialization library for ASP.NET. See http://json.org/ for libraries that are available or maybe there is one built into ASP.NET. Either way, the code will look like:
String s = getAppropriateFormField();
Object o = JSONLibraryPackage.parse(s);
where obviously you'll have to fill in the blanks for how you get the form field and then what package and method does the parsing.

Categories