WebAPI HttpResponse Message - asp.net-web-api2

For WebAPI2 Action results, HTTPResponseMessage is used as one of the return type and Request.CreateResponse is used to return the message.
Request.CreateResponse is handy when we want to return single instance of the model but if we want to return multiple rows from the “model”, there is no overload method for Request.CreateResponse or Request.CreateResponse which supports it(as far as I read). If someone could post the sample, it would be great
Also, I have few other queries.
• Why we have to go for HttpResponseMessage rather than IQueryable or Model return type?
• What is the difference between Request.CreateResponse and Request.CreateResponse , as we are able to return a single instance of the model using both methods. How we can choose one among the two?

You can make the return type of your action method be any serializable data. Content negotiation and formatters will turn the returned value into an HTTP response for you.
From Action Results in Web API 2:
Other Return Types
For all other return types, Web API uses a media formatter to serialize the return value. Web API writes the serialized value into the response body. The response status code is 200 (OK).
public class ProductsController : ApiController
{
public IEnumerable<Product> Get()
{
return GetAllProductsFromDB();
}
}
A disadvantage of this approach is that you cannot directly return an error code, such as 404. However, you can throw an HttpResponseException for error codes. For more information, see Exception Handling in ASP.NET Web API.
Web API uses the Accept header in the request to choose the formatter. For more information, see Content Negotiation.
Example request:
GET http://localhost/api/products HTTP/1.1
User-Agent: Fiddler
Host: localhost:24127
Accept: application/json
Example response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/8.0
Date: Mon, 27 Jan 2014 08:53:35 GMT
Content-Length: 56
[{"Id":1,"Name":"Yo-yo","Category":"Toys","Price":6.95}]

Related

RAML, specify API request Content-Length value

I'm trying to set the value of the Content-Length property to 0 in my RAML file.
I first stumbled upon this thread : How to specify API request header value in RAML
When I tried implementing it with this code :
/update:
post:
description: Store updated data in database
headers:
Content-Length:
enum: [0]
body:
...
I got the response 400 Bad Request :
{
"code": "REQUEST_VALIDATION_ERROR",
"message": "Required header Content-Length is missing."
}
My IDE told me a string was expected but feeding with ["0"] didn't solve the problem.
(I'm testing my API specification in Mulesoft Design Center.)
So is there something I did wrong or is there another way to set the Content-Length to 0 in the request's header ?
You should only try to define custom headers in RAML. A required header of the HTTP protocol like Content-Length must not be defined. It should be automatically generated to prevent errors.

Custom error status code with gqlgen + go gin

Recently I have been updating my GO REST APIs into graphQl API's and I came across issue where I am unable to customise my status code with gqlgen.
Response I got
Headers
Status Code: 200 OK
{
data: null,
errors: [
{message: "Unauthorized access", path: ["..."]}
]
}
Expected Header
Status Code: 401 UNAUTHORISED
Any help would be really appreciating!
Assume you have a gqlgen resolver similar to this:
func (r *queryResolver) SecretItems(ctx context.Context, userID string,
password string) ([]SecretItems, error) {
// ...
if !isAuthorized(userID, password) {
return nil, errors.New("Unauthorized access")
}
// ...
}
then the described behavior is expected. Errors should be returned as part of
the response body.
GraphQL is transport agnostic. While it is often served over HTTP, it might be
served over other client-server Protocols as well. Handling errors in the
response body requires no assumptions about the protocol. Hence, you shouldn't
rely on HTTP status codes.
Handling errors in the response body has another advantage: Assume a request
contains multiple queries. Some of them succeed, some of them fail. Then the
response can contain the result of successful queries under data and errors
related to failed queries under errors.
References:
GraphQL website
Specification: Response
Hasura: GraphQL vs REST
Possible reason why you expected a 401 status code
The gqlgen docs on
authentication contain an example
where 401 status code is returned.
Why? This happens in a http handler used as middleware on the chi http server.
The 401 status code is not returned by a GraphQL resolver.

Is it correct to return 200 Ok HTTP status for a POST request?

Usually, we use POST to create a resource on the server-side.
So ideally if everything goes right, the server should respond either with a 201 Created HTTP status or in case of an asynchronous operation with 202 Accepted HTTP status.
Is there any valid scenario where a POST request can be returning a 200 OK HTTP status?
Or should we never use 200 OK HTTP status for a POST request?
I see 200 as a very common response to POST requests on internet. It's fine to use it.
From RFC 7231:
6.3.1. 200 OK
The 200 (OK) status code indicates that the request has succeeded.
The payload sent in a 200 response depends on the request method.
For the methods defined by this specification, the intended meaning
of the payload can be summarized as:
GET a representation of the target resource;
HEAD the same representation as GET, but without the
representation
data;
POST a representation of the status of, or results obtained from,
the action;
PUT, DELETE a representation of the status of the action;
OPTIONS a representation of the communications options;
TRACE a representation of the request message as received by the
end
server.
And section 4.3.3:
Responses to POST requests are only cacheable when they include
explicit freshness information (see Section 4.2.1 of [RFC7234]).
However, POST caching is not widely implemented. For cases where an
origin server wishes the client to be able to cache the result of a
POST in a way that can be reused by a later GET, the origin server MAY
send a 200 (OK) response containing the result and a Content-Location
header field that has the same value as the POST's effective request
URI (Section 3.1.4.2).
Yes, You can return 200 Ok HTTP status, but you SHOULD return a response BODY.
In general, we have 3 options according to your API requirements:
Return 201 Created HTTP status, with EMPTY BODY.
In case you don't need to return a response body.
Return 200 Ok HTTP status, with BODY.
In case you need to return a response body [containg created resource].
Return 202 Accepted HTTP status, with EMPTY BODY.
In case the action will be queued.

File Upload with Additional Parameters as JSON

I am using the below code to upload image with some additional parameters.
[HttpPost]
public HttpResponseMessage Upload(Data data)
{
var count = HttpContext.Current.Request.Files.Count;
return null;
}
I tried checked this method using postman chrome extension. I passed these values
Under Headers
enctype: multipart/form-data
Content-Type: application/json
Under form-data added one image file
Under raw
{
"Id": "1",
"ModifiedBy" : "1"
}
But the problem i am getting 0 for count
The Content-Type should be multipart/form-data not application/json for your code to work. A typical content type looks like this:
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryvmxBBVAoH3KRsa9L
The actual post data then contains blocks of 'data' separated by the boundary. These blocks can contain a content type, but they don't have to. If you're doing file uploads the content type should not matter - the filename is what determines the type.
All that said, with WebAPI you shouldn't be using the ASP.NET HttpContext object, but rather the lower level Web API semantics. While what you're doing works as long as you run inside of the ASP.NET stack, if you self-host or maybe in the future run ontop of a different stack like OWin/Katana this code will no longer work.
To handle file uploads with Web API specific code check out this blog post from Filip W.
http://www.strathweb.com/2012/04/html5-drag-and-drop-asynchronous-multi-file-upload-with-asp-net-webapi/

Relationship between WCF Operation Name and Action

I have a WCF service defined like this:
[ServiceContract(Namespace = "http://AttributeServiceNameSpace", Name = "AttributeServiceName1")]
public interface IHelloIndigoService1
{
[OperationContract(Name="AttributeOperationName11", Action = "aaa2")]
String HelloIndigo11();
[OperationContract(Name = "AttributeOperationName12", Action = "aaa1")]
String HelloIndigo12();
}
And I captured the HTTP message during the service invocation, as below.
POST http://xxx/Service.svc/IHelloIndigoServiceAddress1 HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: "aaa2"
Host: shao-02.fareast.corp.microsoft.com
Content-Length: 162
Expect: 100-continue
Connection: Keep-Alive
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<AttributeOperationName11 xmlns="http://AttributeServiceNameSpace"/>
</s:Body>
</s:Envelope>
So we can see the Action and Operation Name both exist in the SOAP message to invoke the service.
But I just wonder:
Why do we need the Action and the Operation Name to identify a single service method? Only one should be enough.
You don't need Action and OperationName to identify service operation. Operation name defines structure (wrapper element name) of the SOAP message but it is not used for operation identification. The action is used for operation identification.
There are some non standard SOAP parsers using operation name (root body element) for operation identification but those parsers don't use SOAP action.
Edit: I had a discussion with my colleague today and it looks like my previous answer isn't correct. The real unique identification of the message in SOAP protocol is SOAP Action + Root element. So in this case the Action defines SOAP Action and OperationName defines wrapper element's name (used as root message element).