How to I get the detail (custom error message) returned with a bad request status code? So that I can do an ASSERT on it - testing

Hi so I am setting up some Integration tests (using Xunit) and I would like to run an Assert to check whether the correct custom error message is returned.
This is the data I need to get is in the following response see image...
detail: "Username must be unique" Don't worry this message will be modified to be more useful later on I am just wanting to get it working first
Required Info
This is the current code...
//Act
response = await _httpClient.PostAsync("CompleteUserSetup", formContent);
//Assert
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode) ; //Bad request should be returned
//TODO: check custom error message is correct
So hoping for...
ASSERT.Equal("Username must be unique", some code to get detail from response)

Okay so I figured out how to get the data I needed. I just needed to convert the result into an object and then I was able to pull the detail data that I needed.
var resultModel = await System.Text.Json.JsonSerializer.DeserializeAsync<Result>(response.Content.ReadAsStream(), JsonSerializerHelper.DefaultDeserialisationOptions);
var errorMessage = resultModel.detail;

Related

Getting data from AlamofireNetworkClient request

From the documentation
let client = AlamofireNetworkClient()
let request = client.request(method: .get, endpoint: "http://my-amazing-api.com/endpoint")
let data = request.asData // parse `Data`
First line fails to compile: Missing argument for parameter 'eventMonitors' in call
Second line fails to compile: Cannot infer contextual base in reference to member 'get'
If I change the client to
let client: AlamofireNetworkClient = .default
I can at least compile, but how do I get actual data back from the call?
'data' is PovioKitPromise.Promise<Foundation.Data>
How to I get the result of the call as actual data/ascii/whatever?
There is not a single functioning example in the documentation of extracting a response from a request.

How do I get the message from an API using Flurl?

I've created an API in .NET Core 2 using C#. It returns an ActionResult with a status code and string message. In another application, I call the API using Flurl. I can get the status code number, but I can't find a way to get the message. How do I get the message or what do I need to change in the API to put the message someway Flurl can get it?
Here's the code for the API. The "message" in this example is "Sorry!".
[HttpPost("{orderID}/SendEmail")]
[Produces("application/json", Type = typeof(string))]
public ActionResult Post(int orderID)
{
return StatusCode(500, "Sorry!");
}
Here's the code in another app calling the API. I can get the status code number (500) using (int)getRespParams.StatusCode and the status code text (InternalError) using getRespParams.StatusCode, but how do I get the "Sorry!" message?
var getRespParams = await $"http://localhost:1234/api/Orders/{orderID}/SendEmail".PostUrlEncodedAsync();
int statusCodeNumber = (int)getRespParams.StatusCode;
PostUrlEncodedAsync returns an HttpResponseMessage object. To get the body as a string, just do this:
var message = await getRespParams.Content.ReadAsStringAsync();
One thing to note is that Flurl throws an exception on non-2XX responses by default. (This is configurable). Often you only care about the status code if the call is unsuccessful, so a typical pattern is to use a try/catch block:
try {
var obj = await url
.PostAsync(...)
.ReceiveJson<MyResponseType>();
}
catch (FlurlHttpException ex) {
var status = ex.Call.HttpStatus;
var message = await ex.GetResponseStringAsync();
}
One advantage here is you can use Flurl's ReceiveJson to get the response body directly in successful cases, and get the error body (which is a different shape) separately in the catch block. That way you're not dealing with deserializing a "raw" HttpResponseMessage at all.

Set response headers

I need to set some response headers within server.onPreHandler ext method.
There are 2 scenarios, where I need this happen when user sends an API request to my route end point.
1) In success scenario, I need to set headers and let process continue further down life cycle
2) In error scenario (where user has not provided a required field), I need to set headers and return immediately to user with appropriate error info.
In both of these scenarios, I would like to set response headers.
In the 2nd scenario above, I am able to invoke reply.response('error') and then set response header to it using response.header('x', 'value'). However, in the 1st scenario, where before calling reply.continue() I am trying to set header using request.response.header('x', 'value), I get response null error.
Please help
Thanks
Ramesh
I'm able to change response headers like this. Have you tried this way?
// at your onPreResponse ext body
const response = request.response;
if (request.response.isBoom) {
response.output.headers['x'] = 'value';
} else {
response.header('x', 'value');
}

How to get error or success result from Acumatica Web service api?

//LoginResult loginResult = context.Login("user","pass");
//if (loginResult.Code != ErrorCode.OK)
//Get Schema
//Insert
//Add fields values
//....
O301000.Actions.CopyOrder,
O301000.Actions.Save,
O301000.OrderSummary.OrderNbr
Submitresult = O301000.context.Submit(cmds);
How do I know if there was an error when inserting/saving the Order (or any other file)?
I just can find a value 'Submitresult.ErrorCode' like in the Login Result.
Mean while a have solve the issue, when inserting, by looking for the 'O301000.OrderSummary.OrderNbr' not null value.
But that does not works when updating a record.
You should always use a
try{Submitresult = O301000.context.Submit(cmds);}
catch(Exception ex){Console.WriteLine(ex.Message);}
when making these calls. If the SOAP calls returns an error, than the message is passed to the Exception object.

Adding events to Davical server using Http request and DDay.iCal

I am trying to add an event from my local database to the Davical server (in fact, this should apply to any CalDav server, as long as it is compliant with the CalDav protocol)...
From what I could read here, I can send a PUT request to add events contained in a VCALENDAR collection... So here is what I try to do:
try {
// Create the HttpWebRequest object
HttpWebRequest Request = (HttpWebRequest)HttpWebRequest.Create("http://my_caldav_srv/davical.php/user/mycalendar");
// Add the network credentials to the request
Request.Credentials = new NetworkCredential(usr, pwd);
// Specify the method
Request.Method = "PUT";
// some headers - I MAY BE MISSING THINGS HERE???
Request.Headers.Add("Overwrite", "T");
// set the body of the request...
Request.ContentLength = bodyStr.Length;
Stream reqStream = Request.GetRequestStream();
// Write the string to the destination as a text file.
reqStream.Write( Encoding.UTF8.GetBytes(body), 0, body.Length);
// Set the content type header.
Request.ContentType = contentType.Trim();
// Send the method request and get the response from the server.
Response = (HttpWebResponse)Request.GetResponse();
}
catch (Exception e) {
throw new Exception("Caught error: " + e.Message, e);
}
The body I send is actually an emtpy calendar:
BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
PRODID:-//davical.org//NONSGML AWL Calendar//EN
X-WR-CALNAME:My Calendar
END:VCALENDAR
For a reason I cannot understand, the call with "PUT" returns an error (405) Method Not Allowed. The PUSH returns (500) Internal Server Error, but looking at the debug details, the reason is the same as for the PUT case...
In debugging on the server side, I found out that the reason is that in caldav-PUT-vcalendar.php, the following clause is violated:
$c->readonly_webdav_collections
Well, first, let me mention that with the SAME credentials entered in Lightning, I am able to add/remove events and, on the admin interface, I actually made sure to grant ALL rights to the user. So I'd be surprised it is due to that...
Any help would be most appreciated !
Kind regards,
Nik
OK, I got it....
The reason is that one must put the event to some EVENT adress....
I.e. the "url" is not the collection's address, but the EVENT's address...
So the same code using the following address works:
string url="http://my_server/caldav.php/username/calendarpath/_my_event_id.ics";
Does anybody know if it is possible to insert / delete multiple events at once ???