Cannot set value for 2 fields at once using OData endpoint in CRM2011 - dynamics-crm-2011

I'm modifying 2 fields on my custom entity, the first field is a lookup field which links to systemuser entity, the second field is simply a two options field.
This is the JSON data I send to Odata end point:
{
"new_saleperson":
{
"__metadata": {"type":"Microsoft.Crm.Sdk.Data.Services.EntityReference"},
"Id":"<My ID>",
"LogicalName":"systemuser",
"Name":"<My Name>"
}
,"new_isenabled":true
}
And the header:
Content-Type: application/json
X-HTTP-Method: MERGE
However, I got the following error:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<error
xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<code>-2147220891</code>
<message xml:lang="ja-JP">The source was not found, but some or all event logs could not be searched. To create the source, you need permission to read all event logs to make sure that the new source name is unique. Inaccessible logs: Security.</message>
</error>
The strange thing is, if I update 1 field at a time, then everything goes as expected. In other word, the following JSON data can set new_saleperson field just fine:
{
"new_saleperson":
{
"__metadata": {"type": "Microsoft.Crm.Sdk.Data.Services.EntityReference"},
"Id": "<My ID>",
"LogicalName": "systemuser",
"Name": "<My Name>"
}
}
And the following JSON data can set new_isenabled to true without any problem:
{
"new_isenabled":true
}
I even tried setting both fields at once, but let new_saleperson be null, and it works:
{
"new_saleperson":
{
"__metadata": {"type":"Microsoft.Crm.Sdk.Data.Services.EntityReference"},
"Id":null,
"LogicalName":null,
"Name":null
}
,"new_isenabled":true
}
It just that setting both fields at the same time, with non-null value is causing error. What am I doing wrong here?
I'm using Dynamic CRM 2011 on-premise.

Is it possible that your SalesPerson Id is not a valid system user? The system will throw an error if you use a GUID that doesn't exist.

Related

Insert User through Sharepoint batch send HTTP Request Connector

I need to insert items into sharepoint by using SP connector - Send HTTP Request
I send body : "User": { "Key": "i:0#.f|membership|#{first(body('Get_by_mail')?['value'])['Email']}" },
Despite it having successfully created, the sharepoint shows the field without value. Do you have any idea what could be going on?
After reproducing from my end, I could able to make this work using the below JSON in the body while sending the HTTP request.
{
"__metadata": { "type": "SP.Data.<YOUR_LIST_NAME>ListItem" },
"Title": "ccc",
"UserId": 6
}
UserId is the key which represents the column in my Sharepoint which is named as User. Consider if Person is the column in your Sharepoint then make sure you set the key value as PersonId.
Results:
If you look at your JSON:
"User":
{
"Key": "i:0#.f|membership|#{first(body('Get_by_mail')?['value'])['Email']}"
}
you'll notice that you're sending just a key to a key/value pair target. The item inserts because a Key is provided, but it doesn't display anything because you did not provide a Value that would be displayed. Try the following JSON instead:
"User":
{
"Key": "i:0#.f|membership|#{first(body('Get_by_mail')?['value'])['Email']}",
"Value": "i:0#.f|membership|#{first(body('Get_by_mail')?['value'])['Email']}"
}

Dynamically define csv table structure based on HTTP request body in Logic apps

So, I have a logic app that looks like below
enter image description here
The main idea of the app is to get the list items of a list and copy the contents in a csv file in blob storage.
The site name and list name are passed through the HTTP request body.
However, I would like to also define the Select operation column mapping dynamically.
The body looks like this
{
"listName" : "The list name",
"siteAddress" : "SharepointSiteAddress",
"columns" : {
"Email": " #item()?['Employee']?['Email']",
"Region": " #item()?['Region']?['Value']"
}
}
In the 'Map' section of the 'Select' Operation I use the 'columns' property as shown below
enter image description here
However, in the output stream of the 'Select' Operation, email and region column values are resolved with the string that is passed instead of retrieving the actual item value that I am trying to refer to.
Can I somehow create the csv table dynamically through the HTTP request while also being able to access the items' values?
Using expressions, you can create CSV file with Dynamic data. I have reproduced issue from my side and below are the stepts I followed.
Created Logic app as shown below,
In Http trigger, I have defined sample payload as shown below,
{
"listName" : "The list name",
"siteAddress" : "SharepointSiteAddress",
"columns" : {
"Email": " Email",
"DisplayName": "DisplayName"
}
}
In select action, from is taken from Get items value. In Map row, key is taken from Http trigger and value is from SharePoint item as shown below,
Map:
Key -triggerBody()?['columns']?['Email']
Value - item()?['Editor']?['Email']
Output of Get Items action in my case is like below. Hence written expression according to that.
"value": [
{
"#odata.etag": "\"1\"",
"ItemInternalId": "3",
"ID": 3,
"Modified": "2022-11-15T10:49:47Z",
"Editor": {
"#odata.type": "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
"Claims": "i:0#.f|membership|xyzt.com",
"DisplayName": "Test",
"Email": "v#mail.com",
"JobTitle": ""
}
Tested logic app. It ran successfully and csv file is generated like below,
Csv file:

Associated PXSelect/PXSelectReadOnly Returns Nothing on Sales Order Through OpenAPI

I've introduced a new DAC and a new field on the Sales Order associated to the new DAC key. When trying to retrieve the information through OpenAPI it comes back empty. I'd like to know why and how I can adjust my code to return the information. I've tried both PXSelect and PXSelectReadOnly
Declaring Statement on SOOrderEntry(extension):
public PXSelect<IOCSCompanyBrand, Where<IOCSCompanyBrand.companyBrandNbr,
Equal<Current<SOOrderExt.usrCompanyBrand>>>> CompanyBranding;
When I hit the URL: http://localhost/Acumatica21/entity/AcumaticaExtended21R1/20.200.001/SalesOrder?$select=OrderNbr,CompanyBranding,OrderType,CompanyBrand&$expand=CompanyBranding&$filter=OrderNbr%20eq%20'SO-030003'
This is the data that is returned:
[
{
"id": "f827cb43-9b8a-ec11-a481-747827c044c8",
"rowNumber": 1,
"note": {
"value": ""
},
"CompanyBrand": {
"value": "IO"
},
"CompanyBranding": null,
"OrderNbr": {
"value": "SO-030003"
},
"OrderType": {
"value": "SO"
},
"custom": {}
}
]
Acumatica Version: 21.205.0063
Here's the definition for SalesOrder in the endpoint (which was populated via the GUI)
I ended up opening a Acumatica Developer case and here is their response.
Hi Kyle,
Thanks for your time yesterday.
Endpoint mapping is valid but the fields in the view isn't fetch due the limitation of the filter parameter in the request. Filter parameter optimizes the data that are being fetch. In the case, the customer view isn't fetched. To workaround the limitation, instead of using filter, you can try something like below,
http://localhost/Acumatica/entity/AcumaticaExtended21R1/20.200.001/SalesOrder/SO/SO-030007?$expand=CompanyBranding
You can fetch the record and use expand to get the detail level fields. This way you can avoid the limitation of the filter.
Please check and let me know if you have any questions.
Regards,
Vignesh

Creating an B2C Identity Experience Framework Policy Key with Key Secret in a single Graph API call

I'm developing a console app that uploads a custom policy (that part is working) and the related policy key using the Graph API following this documentation https://learn.microsoft.com/en-us/graph/api/trustframework-post-keysets?view=graph-rest-beta&tabs=http#example-2-create-a-keyset-with-a-key
Request:
URL: https://graph.microsoft.com/beta/trustFramework/keySets
Headers: Content-Type = application/json, Authorization = Bearer eyJ0e...Mca9g
Payload: {
"id":"Test3AADSecret",
"keys":
[
{
"use":"sig",
"k":"A1B2C3D4E5F6G7H8I9J10K11L12M13N14O15P16Q17R18S19T20U21V22W23X24Y25Z26",
"nbf":1644941414,
"exp":4070908800
}
]
}
The request works if I set the keys property to an empty array. However when I try to include a key in the keys property (as in the example above) I get 400 Bad Request status returned with this response payload
{
"error":
{
"code":"AADB2C",
"message":"The 'keySet' field is invalid in request. Please check the request body and parameters.",
"innerError":
{
"correlationId":"ee3aa070-a5a7-4c52-96b7-f0a9471fba63",
"date":"2022-02-15T16:27:36",
"request-id":"ad5dba0f-595a-4f94-ade2-fec2357bcb55",
"client-request-id":"ad5dba0f-595a-4f94-ade2-fec2357bcb55"
}
}
}
The only issues I can find on github relates to using the GraphServiceClient C# class (not the Graph API) to create a keyset with key and that issue has been closed (resolved) https://github.com/microsoftgraph/msgraph-beta-sdk-dotnet/issues/67
I've tried installing the latest version of Microsoft.Graph nuget package (4.18.0) but I can't follow the C# example from here https://learn.microsoft.com/en-us/graph/api/trustframework-post-keysets?view=graph-rest-beta&tabs=csharp#request because there's no TrustFrameworkKeySet class and the GraphServiceClient doesn't contain a definition for TrustFramework. I've tried searching nuget and google for other nuget packages to fill these gaps but I've found nothing.
Yes, I could just call the https://graph.microsoft.com/beta/trustFramework/keySets API with an empty keys array and then make a second call to https://graph.microsoft.com/beta/trustFramework/keySets/{id}/uploadSecret to add the key to the ketset. But when I do this I end up with two policy keys, one of which has a .bak extension to the name.
So I have many questions
Am I doing something wrong when calling the Graph API with a key in the keys array
Am I missing a nuget package for the GraphServiceClient C# class. If so, where can I find them?
How can I prevent the second policy key from appearing (.bak file) when attempting to add the key in a separate API call after creating the empty keyset
Thanks in advance if you help me achieve at least one of these approaches.
I made some experiments here. I'm using REST API through PowerShell.
One interesting behavior is the usage of keySets updating (PUT method). The object you try to update must somehow match the existing one.
Assume you have a signature with no valid before (nbf) and expiration, then the following payload works:
{
"keys": [
{
"use": "sig",
"k": "$key",
"kty": "oct"
}
]
}
However, if one adds the exp and nbf fields like so it fails:
{
"keys": [
{
"use": "sig",
"k": "$key",
"kty": "oct",
"nbf": $now,
"exp": $exp
}
]
}
If these fields exists, you must provide values. It fails with the common message
400 Bad Request {"error":{"code":"AADB2C","message":"The 'keySet' field is invalid in request. Please check the request body and parameters."
In general, the API works but is very restrictive. It's a very good idea to go to the portal and check the manifest files.
Identity Experience Framework | Policy Keys | {your policy} | {click on name}
{
"metadata": {
"updatedUtc": "8/1/2022 4:07:42 PM",
"tenantID": "your-tenant.onmicrosoft.com",
"storageKeyId": "B2C_1A_Keyname"
},
"keys": [
{
"kid": "Q1fDF-jMoHeyr7gciaaWgXe3eVkjYdx8BLZoG3J_f1E",
"use": "sig",
"key_ops": [
"sign"
],
"kty": "oct"
}
]
}
Mostly the keys array shown is a valid body for the API call (while I found that you can strip the key_ops field). If you start just create few key variations by hand and try out to deal with these.

How to filter SharePoint list items by Created by in Microsoft Graph?

I'm trying to get a collection of list items from a SharePoint through Microsoft Graph, which I want to filter by CreatedBy.
Requesting: https://graph.microsoft.com/v1.0/sites/{siteid}/lists/TeamRequests/items
Returns:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#sites('{url}')/lists('TeamRequests')/items",
"value": [
{
"#odata.etag": "\"56ad787e-bd69-464a-b5da-dd953e40d7c4,13\"",
"createdDateTime": "2018-02-26T08:34:26Z",
"eTag": "\"56ad787e-bd69-464a-b5da-dd953e40d7c4,13\"",
"id": "11",
"lastModifiedDateTime": "2018-03-22T13:20:03Z",
"webUrl": "{url}/Lists/TeamRequests/11_.000",
"createdBy": {
"user": {
"email": "{email}",
"id": "9c9cbb67-c049-4a2d-845d-6c5ca2300041",
"displayName": "{Name}"
}
},
"lastModifiedBy": {
"user": {
"email": "{email}",
"id": "9c9cbb67-c049-4a2d-845d-6c5ca2300041",
"displayName": "{Name}"
}
},
"parentReference": {},
"contentType": {
"id": "0x01005F15F8133495554D834FF82F187AD0630002133A9CCDE4494D8CB2206D7D6453D6"
}
},
Now I'd like to filter this request for createdBy, either Id, displayName or email address. I tried ?$filter=createdBy/user/email eq '{email}' and similar requests for id or displayName. They all return
{
"error": {
"code": "generalException",
"message": "An unspecified error has occurred.",
"innerError": {
"request-id": "492e3bde-05fe-4484-a475-435ff0aa70b6",
"date": "2018-07-23T07:41:46"
}
}
}
So how to accomplish this filter? Is it even supported?
Even though it sounds like a straightforward query, i have not come up to anything more simple then the following solution:
It seems filtering by user field is not supported except the case when user id is provided, that's the reason why the solution consists of two steps:
1) First, we need to determine user Id by Email , for that purpose the following query could be utilized:
https://graph.microsoft.com/v1.0/sites/root/lists('User Information List')/items?expand=fields(select=Id,Email)
*where User Information List system list stores user properties including Id and Email properties *
2) Once the user Id is resolved, the final query to filter items by user id could be applied:
https://graph.microsoft.com/v1.0/sites/{site-id}/lists('list-name')/items?filter=fields/<user-field-name>LookupId eq '<user-id>'
where
<user-field-name>LookupId is a field which is getting exposed in addition to user field, in case of Created field the name should be AuthorLookupId
Example:
https://graph.microsoft.com/v1.0/sites/root/lists('TeamRequests')/items?filter=fields/AuthorLookupId eq '10'
Note
In some cases the following error is returned Field ''
cannot be referenced in filter or orderby as it is not indexed.
Provide the 'Prefer: HonorNonIndexedQueriesWarningMayFailRandomly'
header to allow this, but be warned that such queries may fail on
large lists.
In that case the following request header needs to be applied:
Prefer: HonorNonIndexedQueriesWarningMayFailRandomly
When I tried to access User Information List list. There is an error with list not found.
So since in my case, first I filtered list data based on status value and next step got the logged in user display name and filtered listitems based on display name.
I'm using #pnp/graph
Filter list data with status filter
let resultsList = await listItemsQuery.filter("fields/RequestStatus eq 'Approval Pending'").expand("fields").get<MicrosoftGraph.ListItem[]>();
Get Logged-In Profile:
const profileQueryEndPoint = new GraphQueryableCollection(graph.me, "/");
Select displayName property from above result
let profileData : User = await profileQueryEndPoint.select("displayName").get <User>();
console.log('displayName : ' + profileData['displayName']);
Filter ListItems with createdby Field by passing profileData['displayName']
let filterUserCreatedRequests: MicrosoftGraph.ListItem[] = resultsList.filter(ListItem => ListItem["createdBy"].user.displayName === profileData['displayName']);
Display filtered results
console.log('filterUserCreatedRequests : ' + JSON.stringify(filterUserCreatedRequests));
I'm giving all the steps for your reference. But above code can simplified more.
Hope this helps someone :)

Resources