Skip to main content
Announcements
Have questions about Qlik Connect? Join us live on April 10th, at 11 AM ET: SIGN UP NOW
cancel
Showing results for 
Search instead for 
Did you mean: 
joshuapierlo
Partner - Contributor II
Partner - Contributor II

Rest API Deleting Sheets

Hi!

I've been working on a function that duplicates an app with a selection of sheets.

The way I do this is by simply duplicating the app, and going trough a list of sheets that have not been selected to make sure these sheets get deleted in the duplicated app.

I've tried using the following endpoints:

await _qrsClient.Delete("qrs/app/appcontent/"+ newAppSheet.ID +"/delete?xrfkey=(key)","");

await _qrsClient.Delete("/qrs/appcontent/newAppID/deletecontentexternalpath="+newAppSheet.Name+"&xrfkey=(key)");

await _qrsClient.Delete("qrs/appcontent/"+ newAppID +"/deleteexternalpath="+newAppSheet.Name+"&xrfkey=(key)");

await _qrsClient.Delete("qrs/appobject/(SheetIDOfSheetThatNeedsToBeDeleted)/delete?xrfkey=(key)");

Sadly to no avail as it keeps giving me "http request header is incorrect" on the first 2 request and "Object reference not set to an instance of an object" on the third & fourth.

I've also tracked the network activity on deleting sheets trough the QMC using the following endpoints:
await _qrsClient.Delete("qrs/selection/(sheetid)/app/object?xrfkey=(key)");

await _qrsClient.Delete("qrs/selection/(sheetid)?xrfkey=(key)");

but also to no avail.... (the http request header is incorrect).

https://help.qlik.com/en-US/sense-developer/June2018/apis/repositoryserviceapi/index.html#0bd3d491Ba...

I've looked trough the rest API endpoint documentation but I can't find any examples on how to actually delete a sheet trough rest API. Does anyone have a clue?

1 Solution

Accepted Solutions
joshuapierlo
Partner - Contributor II
Partner - Contributor II
Author

I have found the error.

The method is actually working fine, just the provided ID does not match the ID that should be sent.

After contact with the Qlik Support team we have made it work by re-writing the whole sheetID receiving process.

This is quoted directly from Qlik Support if anyone has the same problem:

1) Get the object (sheet) id via GET /qrs/app/object?xrfkey=somerandomstring&filter=app.name eq 'SomeApp' and objectType eq 'sheet' and name eq 'deleteMe'. Example response:

(returns 200 OK with json body below)

[

{

"id": "592184be-8691-4d89-9377-5859abab4486",

"engineObjectType": "",

"description": "",

"objectType": "sheet",

"publishTime": "1753-01-01T00:00:00.000Z",

"published": false,

"name": "deleteMe",

"engineObjectId": "b0cc25a5-2fc7-4c7c-934c-b1466770c8ee",

"contentHash": "IM4*K[9PGEY)QUGC'<Q\\A\"D^K#2CF0V\\K-#[:L9Y>OW",

"privileges": null

}

]

2) Delete via DELETE /qrs/app/object/592184be-8691-4d89-9377-5859abab4486?xrfkey=somerandomstring

(returns 204 No Content if successful)

View solution in original post

7 Replies
ErikWetterberg

Hi,

You need to include the xrfkey both as a URL parameter and as a http header.

Erik Wetterberg

https://extendingqlik.upper88.com/

balabhaskarqlik

joshuapierlo
Partner - Contributor II
Partner - Contributor II
Author

Hi Erik,

Thank you for your response.

The HTTP header is set in a different class that describes the _qrsClient.

I have taken a screenshot of the delete-class.

9e5abaae066f18ee6332742b5ff7fcf5.png

ErikWetterberg

‌How do you make sure the same xrfkey is used?

Erik Wetterberg

joshuapierlo
Partner - Contributor II
Partner - Contributor II
Author

Hi Erik, thanks for your response

It's only used a couple of times troughout the whole application, and it's predefined.

I double checked and I'm 100% positive that they're the same.

Also i'm using this delete task.

public async Task<string> Delete(string endpoint)

        {

            SetHeaders(_client);

            _client.QueryString = _queryStringCollection;

            try

            {

                while (_client.IsBusy)

                {

                    await Task.Delay(200);

                }

                return await _client.UploadStringTaskAsync(_serverURL + endpoint, "Delete", "").ConfigureAwait(false);

            }

            catch (WebException ex)

            {

                throw new Exception(await ParseWebException(ex).ConfigureAwait(false), ex);

            }

        }

-the SetHeaders takes care of adding the headers (including the xrfkey aswell),

-the server URL is our qliksense server (https://OurIP)

-the endpoint is /qrs/selection/{SHEET-ID}/app/object?xrfkey as shown in the screenshot above.

The exception thrown in the catch is:

"The remote server returned an error: (400) Bad Request."

Also, I've checked the networking activities when deleting a sheet trough the QMC and it included the port aswell (433).

I tried adding it to the endpoint (:433/qrs/selection/{SHEET-ID}/app/object?xrfkey) but it gives me an Unable to connect to the remote server. Checked the port listings and the proxy service is running on port 433 as usual....

ErikWetterberg

Hi,

Are you sure about the endpoint? I would expect it to be something like '/qrs/[type]/{id}' as described here. The type would be 'app/object' in your case. Delete app object is not described in the documentation, but compare to the URL described for publish.

Erik Wetterberg

https://extendingqlik.upper88.com/

joshuapierlo
Partner - Contributor II
Partner - Contributor II
Author

I have found the error.

The method is actually working fine, just the provided ID does not match the ID that should be sent.

After contact with the Qlik Support team we have made it work by re-writing the whole sheetID receiving process.

This is quoted directly from Qlik Support if anyone has the same problem:

1) Get the object (sheet) id via GET /qrs/app/object?xrfkey=somerandomstring&filter=app.name eq 'SomeApp' and objectType eq 'sheet' and name eq 'deleteMe'. Example response:

(returns 200 OK with json body below)

[

{

"id": "592184be-8691-4d89-9377-5859abab4486",

"engineObjectType": "",

"description": "",

"objectType": "sheet",

"publishTime": "1753-01-01T00:00:00.000Z",

"published": false,

"name": "deleteMe",

"engineObjectId": "b0cc25a5-2fc7-4c7c-934c-b1466770c8ee",

"contentHash": "IM4*K[9PGEY)QUGC'<Q\\A\"D^K#2CF0V\\K-#[:L9Y>OW",

"privileges": null

}

]

2) Delete via DELETE /qrs/app/object/592184be-8691-4d89-9377-5859abab4486?xrfkey=somerandomstring

(returns 204 No Content if successful)