cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1727
Views
0
Helpful
5
Replies

CUPI .NET - GetCallHandler failing because CUCN returns two items

stephan.steiner
Spotlight
Spotlight

Hi

I figure it's probably a CUCN error.. I'm trying to load a callhandler identified by its display name.

The REST response returned contains this:

{"@total":"2","Callhandler":[{"URI":"/vmrest/handlers/callhandlers/afffae55-51e1-4b91-a9b1-6687304cc36a","CreationTime":"2014-06-26T07:49:12Z","Language":"1033","Undeletable":"false","LocationObjectId":"c41c21a9-ee9f-4590-8958-0b6b79adc99c","LocationURI":"/vmrest/locations/connectionlocations/c41c21a9-ee9f-4590-8958-0b6b79adc99c","EditMsg":"true","IsPrimary":"true","OneKeyDelay":"1500","ScheduleSetObjectId":"6675f0af-eefd-4069-911f-5de01a2e7316","ScheduleSetURI":"/vmrest/schedulesets/6675f0af-eefd-4069-911f-5de01a2e7316","SendUrgentMsg":"0","MaxMsgLen":"300","IsTemplate":"false","ObjectId":"afffae55-51e1-4b91-a9b1-6687304cc36a","RecipientSubscriberObjectId":"bd4232b0-fda4-4595-8b0a-8453f7bc646a","RecipientUserURI":"/vmrest/users/bd4232b0-fda4-4595-8b0a-8453f7bc646a","DisplayName":"bbrauntest03","AfterMessageAction":"2","AfterMessageTargetConversation":"PHTransfer","AfterMessageTargetHandlerObjectId":"fae64789-66a5-4f0f-87f2-edfd12bc87b7","TimeZone":"110","UseDefaultLanguage":"true","UseDefaultTimeZone":"true","MediaSwitchObjectId":"174307b7-42b1-42fa-a116-74352d986705","PhoneSystemURI":"/vmrest/phonesystems/174307b7-42b1-42fa-a116-74352d986705","UseCallLanguage":"false","SendSecureMsg":"false","EnablePrependDigits":"false","DispatchDelivery":"false","CallSearchSpaceObjectId":"32844888-e20f-4928-98ef-a0f1dd5383f4","CallSearchSpaceURI":"/vmrest/searchspaces/32844888-e20f-4928-98ef-a0f1dd5383f4","InheritSearchSpaceFromCall":"true","PartitionObjectId":"9b6e9273-2125-48fb-be13-2f9fbec9904f","PartitionURI":"/vmrest/partitions/9b6e9273-2125-48fb-be13-2f9fbec9904f","GreetingsURI":"/vmrest/handlers/callhandlers/afffae55-51e1-4b91-a9b1-6687304cc36a/greetings","TransferOptionsURI":"/vmrest/handlers/callhandlers/afffae55-51e1-4b91-a9b1-6687304cc36a/transferoptions","MenuEntriesURI":"/vmrest/handlers/callhandlers/afffae55-51e1-4b91-a9b1-6687304cc36a/menuentries"},{"URI":"/vmrest/handlers/callhandlers/78283670-03a5-4805-b43e-821295a481e0","CreationTime":"2014-06-27T07:07:17Z","Language":"1033","Undeletable":"false","LocationObjectId":"c41c21a9-ee9f-4590-8958-0b6b79adc99c","LocationURI":"/vmrest/locations/connectionlocations/c41c21a9-ee9f-4590-8958-0b6b79adc99c","EditMsg":"true","IsPrimary":"false","OneKeyDelay":"1500","ScheduleSetObjectId":"cf662275-9cfb-4f9f-9c61-76b79a93dcc9","ScheduleSetURI":"/vmrest/schedulesets/cf662275-9cfb-4f9f-9c61-76b79a93dcc9","SendUrgentMsg":"0","MaxMsgLen":"300","IsTemplate":"false","ObjectId":"78283670-03a5-4805-b43e-821295a481e0","RecipientSubscriberObjectId":"bd4232b0-fda4-4595-8b0a-8453f7bc646a","RecipientUserURI":"/vmrest/users/bd4232b0-fda4-4595-8b0a-8453f7bc646a","DisplayName":"bbrauntest03","AfterMessageAction":"1","TimeZone":"110","UseDefaultLanguage":"true","UseDefaultTimeZone":"false","MediaSwitchObjectId":"174307b7-42b1-42fa-a116-74352d986705","PhoneSystemURI":"/vmrest/phonesystems/174307b7-42b1-42fa-a116-74352d986705","UseCallLanguage":"true","SendSecureMsg":"false","EnablePrependDigits":"false","DispatchDelivery":"false","CallSearchSpaceObjectId":"32844888-e20f-4928-98ef-a0f1dd5383f4","CallSearchSpaceURI":"/vmrest/searchspaces/32844888-e20f-4928-98ef-a0f1dd5383f4","InheritSearchSpaceFromCall":"true","PartitionObjectId":"9b6e9273-2125-48fb-be13-2f9fbec9904f","PartitionURI":"/vmrest/partitions/9b6e9273-2125-48fb-be13-2f9fbec9904f","GreetingsURI":"/vmrest/handlers/callhandlers/78283670-03a5-4805-b43e-821295a481e0/greetings","TransferOptionsURI":"/vmrest/handlers/callhandlers/78283670-03a5-4805-b43e-821295a481e0/transferoptions","MenuEntriesURI":"/vmrest/handlers/callhandlers/78283670-03a5-4805-b43e-821295a481e0/menuentries"}]}

As the parsing method only expects a single result, json parsing fails with the following error:

Failure populating class instance form JSON response:Newtonsoft.Json.JsonSerializationException: Cannot populate JSON array onto type 'Cisco.UnityConnection.RestFunctions.CallHandler'. Path '', line 1, position 1.

   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Populate(JsonReader reader, Object target)

   at Newtonsoft.Json.JsonSerializer.PopulateInternal(JsonReader reader, Object target)

   at Newtonsoft.Json.JsonSerializer.Populate(JsonReader reader, Object target)

   at Newtonsoft.Json.JsonConvert.PopulateObject(String value, Object target, JsonSerializerSettings settings)

   at Cisco.UnityConnection.RestFunctions.CallHandler.GetCallHandler(String pObjectId, String pDisplayName, Boolean pIsUserTemplateHandler)

Makes sense seeing that in Callhandler.cs we have the parsing code

                JsonConvert.PopulateObject(ConnectionServerRest.StripJsonOfObjectWrapper(res.ResponseText, "Callhandler"), this,

                    RestTransportFunctions.JsonSerializerSettings);

and JsonConvert is meant for a single object.

However, when experimenting, I found that in fact creating two call handlers with the same displayName is in fact supported (there's only a warning), so the parsing should be able to handle this case even if it's not recommended to use duplicate display names.

5 Replies 5

lindborg
Cisco Employee
Cisco Employee

The call that accepts the ObjectId or display name returns a single User object, not a list – so clearly it’s expecting the ObjectId or the display name in that case to be unique – even if I added code to handle a list there which one would I pass back? 

non unique display names are odd to be sure but legal.  If you’re working in a site that has non unique display names and you wish to find call handlers using that method anyway you’ll need to explicitly request a list and then check yourself if there’s 0, 1 or more returned and determine (somehow) which call handler it is you want out of the set.

Getting a list of call handlers with a query would look like this:

List<CallHandler> oHandlers;

res = CallHandler.GetCallHandlers(_cxn, out oHandlers, "query=(DisplayName is Opening Greeting)";

I don't know why I had the duplicate.. I think it was a DB error.. something that didn't get properly deleted (I'm creating and deleting the same thing over and over again until I have this complex setup working).

Either way.. is it correct behavior if you have a method that's supposed to return 0 or 1 items and it bombs out if there are two returned by the server? If I didn't have the source code, I wouldn't have known (except when looking at fiddler).

That's just my opinion but I would've designed a method that's supposed to return 0 or 1 items in an environment that can return more than 1 like FirstOrDefault() - with a check for the number of items (it's in the response).. it's a few lines of code switching between < 2 results and >= 2 results.

I'll take a look - I think my preference in that case would be to return an error and not the first entry just to avoid messy accidents - I guess returning false for success, a readable error message and the first item found wouldn't be horrible.  Given the different formats for single return and multiple returns it's not exactly a couple lines of code, but not the end of the world.

down side is technically I'd need to add that logic to all object classes and all search criteria (duplicate aliases are not legal but can and do happen in the field for instance mostly due to replication issues) - a fair amount of work, but I'll stick it on my to-do list.

Took a simpler approach after talking with a couple peers - returning the first object instance if multiple are found didn't fly for anyone - if the call is targeted around a single instance and that fetch fails (0 or more than 1) a readable error to that effect should be returned - the consensus was that it would be more appropriate to a "find first" type method.  Either way, I've implemented the more specific check with readable error changes for:

Call Handlers,CallHandlerTemplate,Directory Handlers,Interview handler,Location,User,Distribution Lists

Users are pushing it but since I've seen overlapping aliases due to replication failures between clusters I went ahead and made the check.The error is now explicit instead of the curious json parsing note.

will be part of 3.0.38 when I release it (probably tomorrow AM)

So I'm definitely not the only one working fast

Your approach sounds fine to me.. the main point is that if not using the source code version you have a chance to figure out what is going wrong. Of course you can activate tracing (I think I first saw in fiddler that I had two callhandlers using the same displayname), but if you get a result telling you the cause instead of some stacktrace that leaves you scratching your head, that's perfectly fine (I'm duping anything that is not a success in detail anyway so it all ends up in the logs... but as is, I got the exception that didn't tell me anything).

I went online with the self-compiled version for the time being as I needed the fix for the Html notification device.