質問

I am having difficulties getting data from a dictionary I created with an HTTP web service call. I get essentially the same error every time no matter what I have tried.

RequestorId: c378e2d0-e273-451a-0000-000000000000. Details: An unhandled exception occurred during the execution of the workflow instance. Exception details: System.InvalidOperationException: Looking up a value using a key is not supported on an instance of 'Microsoft.Activities.Dynamic.DynamicPrimitive'. at Microsoft.Activities.Dynamic.DynamicItem.TryGetValue(String key, DynamicItem& value) at Microsoft.Activities.Dynamic.DynamicValueBuilder.PathSegmentFactory.ObjectPathSegment.Get(DynamicItem obj) at Microsoft.Activities.GetDynamicValueProperty1.Execute(CodeActivityContext context) at System.Activities.CodeActivity1.InternalExecute(ActivityInstance instance, ActivityExecutor executor, BookmarkManager bookmarkManager) at System.Activities.Runtime.ActivityExecutor.ExecuteActivityWorkItem.ExecuteBody(ActivityExecutor executor, BookmarkManager bookmarkManager, Location resultLocation)

Here is my workflow: enter image description here

The url I am pulling from has data listed out like this:

enter image description here

I have tried a plethora of Get xx from xx output xx, but no luck.

d/key, d/results/key, d/results(0)/key, results/key, results(0)/key, key, (0)/key, [%Variable: index%]/key, nwServiceResponse/key, nmSerivceResponse(0)/key

I am at a complete loss at this point. I am pretty new to workflows, dictionaries, and the HTTP web service in Sharepoint. I have googled this quite a bit which is where I got all of the above attempts from. I appreciate any assistance anyone can provide.

役に立ちましたか?

解決

I have tried a plethora of Get xx from xx output xx, but no luck.

d/key, d/results/key, d/results(0)/key, results/key, results(0)/key, key, (0)/key, [%Variable: index%]/key, nwServiceResponse/key, nmSerivceResponse(0)/key

Because you say you are new to all this, lets take this step by step to help you understand what's going on, and how to figure out what you should be using to get the data you want from the web service response.

Based on the image you provided describing the structure of the data coming from the URL you are calling (which is cropped, so I can't see everything), I am guessing that some of it is structured like this:

{
    id$: "1",
    customerAccountStatus: null,
    billingSystem: null,
    relatedRecordId: 0,
    statusChanged: false,
    receivedByUserId: "",
    receivedByUserName: "",
    // other stuff
    customerAccountNumber: ""  // <-- not in that image, but looks like what you are trying to get in the workflow
}

This gives us an important clue, and based on that, I'd say it looks like you are calling a web service that is not SharePoint's built in REST web service. How do I know that? Because the screenshot of that data does not include a root d property. Which brings us to the first point:

When to use d

SharePoint has a built in web service, known as the REST API, that you can call to get data out of SharePoint itself. That root d property that you see so much when searching around for examples of SharePoint and web services is something that is added by SharePoint when you call SharePoint's REST service. For example, if you make a query for a single list item:

// a query to get (single) list item with ID 5 from the "My List" list
https://my.sharepoint.server/sites/MySite/_api/web/lists/getbytitle('My List')/items(5)

the response from SharePoint is going to be structured like:

{
    d: {
        Title: "My item's title",
        ID: 5,
        // other SharePoint fields on that list item
    }
}

A lot of people use the "Call HTTP Web Service" workflow action to call SharePoint's own REST service and get data out of SharePoint. In those cases, they need to account for the root d property in the response, and use that as part of the "Get item from a dictionary" action.

However - you are not limited to calling SharePoint's own web service from "Call HTTP Web Service" in a workflow. And if you are calling a web service outside SharePoint, you need to know how that web service in particular sends its data in its response.

When to use results / when to use (0)

These are kind of related, so I am putting them together. But lets start with results. You see results a lot in SharePoint examples because just like d, results is something that SharePoint itself adds to responses from its own web service. It adds results when the query that you send to SharePoint could potentially return more than one item. In the example in the d section above, the query is specifically asking for an item by its ID, so there is only ever going to be a single item returned. But lets say you did a query like this:

// a query to get any/all items from the "My List" list where the title is "Foo"

https://my.sharepoint.server/sites/MySite/_api/web/lists/getbytitle('My List')/items?$filter=Title eq 'Foo'

You don't know exactly how many items are going to match that query. Maybe it will be more than one, maybe it will be exactly one, or maybe it will be none. In all of those cases, the response from SharePoint is going to have a results array (as a sub-property under the root d property - don't forget about the root d!):

// more than one match
{
    d: {
        results: [
            {
                Title: "Foo",
                ID: 12
            },
            {
                Title: "Foo",
                ID: 31
            },
        ]
    }
}

// exactly one match
{
    d: {
        results: [  // <-- results is still an array, even though it only has one item in it
            {
                Title: "Foo",
                ID: 12
            }
        ]
    }
}

// no matches
{
    d: {
        results: []  // <-- results is still an array, but it's empty!
    }
}

This is where we get to using (0) - or, more specifically, using the syntax of: a number enclosed in parentheses (doesn't have to be zero, necessarily).

You use that syntax to access items in an array, by using their index in the array. So using that example where there was more than one match to the query, you get

{
    d: {
        results: [
            {                   // <-- first item is d/results(0) 
                Title: "Foo",
                ID: 12
            },
            {                   // <-- second item is d/results(1)
                Title: "Foo",
                ID: 31
            },
        ]
    }
}

A couple important things to note here

  • results is definitely used by SharePoint in responses from its own web service. It may or may not be used in responses from web services outside SharePoint - we can't really say without getting a result from that other web service and seeing how its data is structured, and whether or not that particular web service also includes a property called results.
  • The (number) syntax is used in the "Get item from a dictionary" workflow action to index into an array that's part of a web service response, whether or not that response is from SharePoint and whether or not the property that's holding the array is called results.

For example, if the response from the web service is structured like:

{
    all_the_things: [
        { Bar: "Do" },
        { Bar: "Re" },
        { Bar: "Mi" }
    ]
}

and you want to get the value of "Bar" from the third item, you would use

all_the_things(2)/Bar

Now, in your examples you also list [%Variable: index%]. Where you would use something like that is if you had an array of multiple items, and you wanted to loop through all of the items. Then you use the index variable inside the loop to refer to a specific item by its index number, but then increment the index variable inside the loop so that the next time through it is one higher, thus accessing the next item in the array. (Also note that in the example you posted, you actually put [%Variable: index%]/key, in which the variable index is not enclosed in parentheses, therefore it won't actually work as an indexer in the right way.)

So taking the above example again, let's say we set up a loop where we set index to 0 before the loop starts, then increment index each time through the loop, we would get:

all_the_things([%Variable: index%])/Bar // <-- first time through, index is 0, so "Bar" is "Do"

all_the_things([%Variable: index%])/Bar // <-- second time through, index is 1, so "Bar" is "Re"

all_the_things([%Variable: index%])/Bar // <-- third time through, index is 2, so "Bar" is "Mi"

Getting back to your specific situation

Going back to your original image of the data returned from the URL you call, I'm making the assumptions that

  • You are only getting a single item/object in your response. I don't see any square brackets [] indicating an array or collection of objects, so you don't need to use (0).
  • There doesn't seem to be a root property like SharePoint's d property, it looks like all the property keys are directly on the response object, so you won't need to use anything like d/FieldName (or root/property, or rootKey/subKey, however you want to refer to it conceptually). But again, your image there is cropped so I can't really be sure - this is where you need to understand how the data that's returned to you is structured.

If that's all true, then your "Get.." action should be as simple as

then Get propertyNameYouWant from Variable: yourResponseDictionary (Output to Variable: yourVariable)

which in your specific case looks like you want

then Get customerAccountNumber from Variable: nwServiceResponse (Output to Variable: accNum)

You should not have to use the name of your response dictionary variable (nwServiceResponse) in the "name or path" part of the "Get..." action, like you have it in the screen shot provided, you should just need the property key name only.

I know you listed using just key in the list of all the options you tried, but as far as I can tell from what it looks like the response data is, that should work.

One thing that might help: in order to understand how the response data is structured so you can construct your "Get" path correctly, you need to see it. Usually you can't just log that response dictionary variable to the history list because it's more than likely going to be more than 256 characters. So... email it to yourself!

Set up a step in the workflow right after the HTTP service call, send an email to yourself, and make the body of the email [%Variable: nwServiceResponse%]. It might be a little hard to figure out at first because it will all be crunched together on one line (which will wrap), but you can put it in a text editor and start to tease it out until you can see the structure. (Or you can put it in VS Code and have it auto-format the JSON in a couple keystrokes ;) )

ライセンス: CC-BY-SA帰属
所属していません sharepoint.stackexchange
scroll top