Important Update: Community URLs redirect issues are partially resolved. Learn More. .

cancel
Showing results for 
Search instead for 
Did you mean: 

RESTful API data deserialized as a StringWrapper

BradleyHanna
Contributor III

I am writing a function in C# to logout an Archer session using the RESTful API POST method.

public async Task PostLogoutAsync(string sessionToken)
{
    string logoutPath = "platformapi/core/security/logout";
    string logoutBody = "{\"Value\":\"" + sessionToken + "\"}";
    HttpResponseMessage httpResponseMessage = await this.httpClient.PostAsJsonAsync<string>(logoutPath, logoutBody);
}‍‍‍‍‍‍‍‍

 

The HttpClient object is configured like this:

httpClient = new HttpClient
{
    BaseAddress = new Uri(baseUrl)
};
httpClient.DefaultRequestHeaders.Add("Accept", "application/json,text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
httpClient.DefaultRequestHeaders.Add("Authorization", "Archer session-id=" + sessionToken);

 

The request method object looks like this in Visual Studio (The Uri is correct in the request message):

{Method: POST, RequestUri: 'https://Archer/RSAarcher/platformapi/core/security/logout', Version: 1.1, Content: System.Net.Http.ObjectContent`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], Headers:{  Accept: application/json  Accept: text/html  Accept: application/xhtml+xml  Accept: application/xml; q=0.9  Accept: */*; q=0.8  Authorization: Archer session-id=A8A190D5E8536E2D921CF1F23C77E36A  Content-Type: application/json; charset=utf-8  Content-Length: 46}}‍‍‍‍‍‍‍‍‍‍‍

 

The body content value is rendered like this in the request message object:

{"Value":"A8A190D5E8536E2D921CF1F23C77E36A"}

 

Everything looks correct in the request message.  However, I am receiving a 400: Bad Request when the logout function runs.  The w3wp log entry gives the following message, "The data in the request body could not be deserialized as a StringWrapper."

 

What does that mean?  I did not have this issue with the login function which serialized a custom type object into the request body.  This is simply stringified JSON.  What should I do?

1 ACCEPTED SOLUTION

Accepted Solutions

BradleyHanna
Contributor III

This is my solution:

public async Task<bool> PostLogoutAsync(string sessionToken)
{
    string logoutPath = "platformapi/core/security/logout";
    string logoutBody = @"{'Value':'" + sessionToken + "'}";
    JObject bodyValue = JObject.Parse(logoutBody);

    try
    {
        HttpResponseMessage httpResponseMessage = await httpClient.PostAsJsonAsync<JObject>(logoutPath, bodyValue);

        if (!httpResponseMessage.IsSuccessStatusCode)
        {
            throw new HttpClientRequestFailedException();
        }
        else
        {
            return true;
        }
    }
    catch (Exception exception)
    {
        throw exception;
    }
}

 

I parse the logoutBody string to a JObject and the body of the request is deserialized by the Archer API.  For some reason the formatting done on a plain string by PostAsJsonAsync could not be deserialized by the API.  The more complicated API requests will be easier to build as JObjects anyway, so I am going to use this solution going forward.

View solution in original post

5 REPLIES 5

DavidPetty
Archer Employee
Archer Employee

Bradley, I think you need quotes around the session token in the header, this line:

httpClient.DefaultRequestHeaders.Add("Authorization", "Archer session-id=" + sessionToken);

From the https://community.rsa.com/docs/DOC-97463 

Request Header

Accept: application/json,text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Authorization: Archer session-id="session token ID from login"

Content-Type: application/json

 Advisory Consultant

jsol5
Advocate II

I've seen it a few different ways:

Here's 1 - 

var logoutRequest = client.BuildRequest("core/security/logout")
.WithSession(session)
.WithValue(new StringContainer { Value = session.SessionToken });

var logoutResponse = await client.PostAsync<StringContainer, ArcherResponse<bool>>(logoutRequest);

 

I have not seen the PostAsJsonAsync.

I don't know that you need that.

The response you get is Json and if you need to, you can parse, but if successful, I wouldn't think you'd need any info.

 

But, you said you're doing the same thing to log in... so, not sure why it works for one and not the other.

BodieMinster
Archer Employee
Archer Employee

The StringWrapper is the POCO (Plain Old C# Object) that the API code is using to represent the request body for the logout resource.

public WebApiRequestResult<bool> Logout(StringWrapper sessionToken)

It has a single property called Value which, in this case, is intended to hold the session token. So the JSON should look like this:

 

{"Value":"5D090B29BFA8E5D7E08B334164454C02"}

jsol5
Advocate II

Get it to work?

BradleyHanna
Contributor III

This is my solution:

public async Task<bool> PostLogoutAsync(string sessionToken)
{
    string logoutPath = "platformapi/core/security/logout";
    string logoutBody = @"{'Value':'" + sessionToken + "'}";
    JObject bodyValue = JObject.Parse(logoutBody);

    try
    {
        HttpResponseMessage httpResponseMessage = await httpClient.PostAsJsonAsync<JObject>(logoutPath, bodyValue);

        if (!httpResponseMessage.IsSuccessStatusCode)
        {
            throw new HttpClientRequestFailedException();
        }
        else
        {
            return true;
        }
    }
    catch (Exception exception)
    {
        throw exception;
    }
}

 

I parse the logoutBody string to a JObject and the body of the request is deserialized by the Archer API.  For some reason the formatting done on a plain string by PostAsJsonAsync could not be deserialized by the API.  The more complicated API requests will be easier to build as JObjects anyway, so I am going to use this solution going forward.