Implicit cast operator in ActionResult<bool> not working - asp.net-core

I am following this guide to build my controllers. I do the following.
This is my controller:
// GET api/sth/{sthId}/isValid
[HttpGet("{sthId: int}/isValid")]
[ProducesResponseType(StatusCodes.Status200OK)]
[MyAuthorizeFilter]
public ActionResult<bool> Whatever(int sthId)
{
return this.myService.Whatever(sthId);
}
Theoretically, this should be converted to an Ok() ActionResult. However, If I write the following unit test:
[Fact]
public void Whatever()
{
this.myServiceMock.Setup(x => x.Whatever(It.IsAny<int>())).Returns(true);
-> I DEBUG HERE -> var result = this.myController.Whatever(1);
Assert.IsType<OkObjectResult>(result);
Assert.True((bool)result.Value);
}
I see that my result is an ActionResult<bool> indeed, whose Value is true as expected, but result.Result is null. So: no Ok action result whatsoever.
What am I missing? Do I have to write explicitly the return Ok() to get it? With the sentence
Implicit cast operators support the conversion of both T and ActionResult to ActionResult<T>. T converts to ObjectResult, which means return new ObjectResult(T); is simplified to return T;.
in the documentation I thought it was not necessary...?

The ActionResult<TValue> class:
wraps either an[sic] TValue instance or an ActionResult.
See also the source, its constructors assign either Value or Result, never both.
The MVC pipeline will assign a success status code to the response if no status code was explicitly set. But I can't find documentation for that claim.
This means the response as obtained in this test won't have a status code or OkActionResult anywhere. You can convert it to an ObjectResult, but that won't have a status code.

If you use something like swagger you will indeed get an OK from the server.
This happens to you because you dont perform an http request you simple call a method(your controller method) and you get a return type. You dont create a web server or something so no http status code is generated by .net core.
If you want to get status codes you should write test using http requests. Generally you could look up something like postman to perform your testing.

Related

How to send custom http response code back from spring cloud functions in gcp?

We are using the new gcp cloud functions using Java / Kotlin.
As in the current reference implementations, we are returning org.springframework.messaging.support.GenericMessage objects.
So our code looks like this (Kotlin):
fun generatePdfInBase64(message: Message<Map<String, Any>>): Message<*> {
val document = process(message)
val encoded = Base64.getEncoder().encodeToString(document.document)
return GenericMessage(encoded)
}
We were not able to find any way to include a custom http response code to our message, e.g. 201 or something. The function only responds 200 in case of no exception or 500.
Does someone know of a way to do this?
Best wishes
Andy
As it is mentioned at the official documentation, the HttpResponse class has a method called setStatusCode where you are able to set the number of the status as your convenience
For example:
switch (request.getMethod()) {
case "GET":
response.setStatusCode(HttpURLConnection.HTTP_OK);
writer.write("Hello world!");
break;
On the other hand the constructor of the GenericMessage receives as parameter a payload, therefore I think you can create a string with a json format and use the constructor for create your GenericMessage instance with the status response you need.
If you want to know more about the statuds codes take a look at this document.

Difference between EnsureSuccessStatusCode and Assert.Equal(HttpStatusCode.OK, response.StatusCode) in XUnit ASP.Net Core WebAPI Tests

I read in a Book (ISBN 1838550313, 9781838550318 S.315) that they check a WEB-API Request with both EnsureSuccessStatusCode() and Assert.Equal(HttpStatusCode.OK, ..) in one validation Method. But is the second Assert call not unnecessary to check if the HTTP-Status is 200 or not? What is the difference and what is the best practice?
HttpResponseMessage.EnsureSuccessStatusCode is implemented like this:
public HttpResponseMessage EnsureSuccessStatusCode()
{
if (!IsSuccessStatusCode)
{
throw new HttpRequestException(…, inner: null, _statusCode);
}
return this;
}
So it just checks the value of IsSuccessStatusCode which is implemented like this:
public bool IsSuccessStatusCode
{
get { return ((int)_statusCode >= 200) && ((int)_statusCode <= 299); }
}
So a status code is considered to be successful, if it is in the range [200, 299]. This matches the definition of the HTTP status codes.
If the status code value is not a successful code, then the EnsureSuccessStatusCode method will throw an exception. So it is a quick way to stop the execution in cases where the request failed.
Asserting for equality with HttpStatusCode.OK checks if the status code is exactly 200. This also means that other successful codes would be rejected. Whether that is an appropriate thing to do depends on the API you are testing. Many RESTful APIs will often return different successful status codes depending on what happened. For example, an API might return “201 Created” to express that a resource has been created.
If the test wants to explicitly ensure that the response has a status code “200 OK”, then calling EnsureSuccessStatusCode is not needed. Otherwise, if you want to accept any successful status code, just calling EnsureSuccessStatusCode will be enough for the test since a thrown exception will usually fail the test.

Liferay custom single-sign-on with redirect and parameters

this is my first question here and it's quite tricky as i didn't find enough relevant resources on the web. So I really hope, to get some help with this:
I am doing a custom single-sign-on with Liferay 6.2 GA4. Therefore I have developed a custom login-hook, that can handle my URL that looks like:
http://localhost:8080/c/portal/login?q=10C7vCMqv%2BlYThuxjdOmbUIXj1LKz9W3s5IUg%2F8H%2FvqRPUGOuzoC7pRT4hwVp2TpLf%2FnDRaGfpvoubhvSxlhidyX1SAowlvhdeWb95xRyxyCGZmKxE%2FZejk%2BIS5PvVHYIprBmM5Ec1cM%2Fq5dd5OGpEJJislrctRP
From this i decode the q-parameter to get the login parameters and other parameters, that i need to decide on which page I get redirected and i pass the attribute to the request
request.setAttribute("myParam", recordId);
and
return credentials;
I have also a LoginPostAction, that gets called afterwards and here it is, where it gets tricky:
public final void run(final HttpServletRequest request, final HttpServletResponse response)
throws ActionException {
...
final PortletURL redirectURL = PortletURLFactoryUtil.create(
request, "portlet_WAR_myportlet",
>>>> PortalUtil.getPlidFromPortletId(???, "portlet_WAR_myportlet"),
PortletRequest.RENDER_PHASE);
redirectURL.setParameter("myParam", String.valueOf(request.getAttribute("myParam")));
response.sendRedirect(redirectURL.toString());
}
So, I have the portlet name (PortletId) but I cannot get the Plid from this, as i don't have the ThemeDisplay at this time.
First question: How can i create a PortletURL at this time, which i can use in sendRedirect()?
Second: I have also tried to setAttribute and hardcode the sendRedirect("/urlToMyPortlet"), but I cannot use this at this time anymore as it gets lost afterwards (and is null) when i try to get it on the next page.
Any suggestions?
Thanks a lot in advance,
rom12three

MobileFirst - Answering a call to a WS (JAX-RS)

I have a java adapter (JAX-RS) that returns a POJO, one of the attributes is called validateUser and is a boolean value. I want to get the value of this boolean when called from main.js
It should work like this (main.js):
onGetLoginSuccess function (response)
busy.hide ();
alert ("validate:" + response ["validateUser"]);
As I can get the value in the variable response, the validateUser attribute my POJO.
Thank you for your attention
You can use alert(response.responseJSON.validateUser);
In general to examine the structure of "response" you could do something like: alert(JSON.stringify(response)); It could help you to understand which fields are available and how can you find this validateUser.
It is also important to make sure that your JAX-RS adapter returns JSON content type. Make sure that you have the annotation: #Produces("applicaion/json") in your JAX-RS method that returns this POJO

wcf message response parameter

I've read this example http://msdn.microsoft.com/en-us/library/ee476510.aspx about dynamic responses in wcf.
The sample on the bottom fit my goal pretty well. This is what i did:
[OperationContract]
[WebGet(UriTemplate = "/salaries({queryString})")]
Message GetSalaryByQuery(string queryString);
and my GetSalaryByQuery-Method:
public Message GetSalaryByQuery(string querystring)
{
if (WebOperationContext.Current.IncomingRequest.Accept == "application/json")
return WebOperationContext.Current.CreateJsonResponse<Result>(Salary.GetSalaryByQueryJson(querystring));
else
return WebOperationContext.Current.CreateAtom10Response(Salary.GetSalaryByQuery(querystring));
}
It is pretty similiar to the example i found.
But its not working however. It says that there is another parameter besides the message. I googled the message-class and it seems to me that its not possible to add an parameter to a message-response.
Is there a way to pass a parameter with the request and get a response with a message object?
Is there another way to get the dynamic response?
Thanks in advance.
I got it to work. I just deleted the Metadata-Enpoint and the behavior. My Webservice provides metadata on its own and therefore doesnt need to have the mex-Metadata defined.