OData $batch from Postman - asp.net-web-api

I am trying to post OData batch request in postman.
The url:
http://localhost:52484/$batch
Header:
Content-Type : multipart/mixed; boundary=batch_36522ad7-fc75-4b56-8c71-56071383e77b
Body (raw) :
--batch_36522ad7-fc75-4b56-8c71-56071383e77b
Content-Type: application/http
Content-Transfer-Encoding:binary
GET /Schools?$top=1
Host: host
--batch_36522ad7-fc75-4b56-8c71-56071383e77b
But am getting the below error:
{
"Message": "No HTTP resource was found that matches the request URI 'http://localhost:52484/%24batch'.",
"MessageDetail": "No route providing a controller name was found to match request URI 'http://localhost:52484/%24batch'"
}
Any idea about what is missing in the request?

Please check if you configure OData route and batchHandler correctly, something like the below:
ODataBatchHandler odataBatchHandler = new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer);
odataBatchHandler.MessageQuotas.MaxOperationsPerChangeset = 10;
odataBatchHandler.MessageQuotas.MaxPartsPerBatch = 10;
config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: null,
model: builder.GetEdmModel(),
batchHandler: odataBatchHandler
);

Related

Postgraphile StatusCode: 405, ReasonPhrase: 'Method Not Allowed

I use Postgraphile locally and it work very well.
I want to send a HttpClient post requset in my Application, but it does not work and I get this error:
StatusCode: 405, ReasonPhrase: 'Method Not Allowed
hier is my code:
using (HttpClient httpClient = new HttpClient())
{
string content = "query {accounts {nodes {id,name,street,postalcode,city}}}";
var httpConent = new StringContent(content, Encoding.UTF8, "application/json");
var responseMessage = await httpClient.PostAsync("http://localhost:5000/graphiql", httpConent);
var result = responseMessage.Content.ReadAsStringAsync();
}
In line 5 of your code snippet, you're submitting to the /graphiql URL (which is for the GraphiQL GUI), you should be submitting to /graphql.
In line 4 of your snippet, you are claiming the content variable is application/json, but it is in fact a GraphQL string. You should be submitting something like {"query":"{__typename}"} as application/json.
You do not appear to be issuing an Accept: application/json header.
I suggest you use the network debugging tools of your web browser to inspect exactly what the browser is doing when it runs the GraphQL query, and compare that with what you are attempting to do with your code. You might also refer to the GraphQL-over-HTTP specification: https://graphql.github.io/graphql-over-http/draft/

AWS API Gateway adding Content-Type Header to OPTIONS Reques

I am trying to write an OPTIONS request using a Lambda and AWS Gateway to respond to post requests - this code comes from AWS documentation:
exports.handler = function(event, context) {
var responseCode = 200;
var response = {
statusCode: responseCode,
headers: {
"Access-Control-Allow-Origin": "*"
}
};
context.succeed(response);
};
When I test it in AWS Lambda, it provides the correct response
Response:
{
"statusCode": 200,
"headers": {
"Access-Control-Allow-Origin": "*"
}
}
However, when I try to run it using AWS API Gateway,
it adds on a Content-Type header that was not part of the response. As a result, when I tried to make a post requests, I get the error that 'Content Type in not allowed in preflight response'. Any idea what the issue could be?
if you run the below command,
curl -H "origin: example.com" -v "https://h64hstwg05.execute-api.us-east-1.amazonaws.com/default/optionsrequest"
it returns content-type: application/json. it is because application/json is the default value when it is not specified.
here is this from aws docs.
When the Content-Type header is absent in the request, API Gateway assumes that its default value is application/json
Reference:
https://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/request-response-data-mappings.html
You could always override and return a different content-type header from the lambda.
Hope this helps.

Content type 'text/plain;charset=UTF-8' not supported error in spring boot inside RestController class

I got the following #RestController inside a spring boot application :
#Data
#RestController
public class Hello {
#Autowired
private ResturantExpensesRepo repo;
#RequestMapping(value = "/expenses/restaurants",method = RequestMethod.POST,consumes =MediaType.APPLICATION_JSON_VALUE ,
headers = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public void hello(#RequestBody ResturantExpenseDto dto)
{
Logger logger = LoggerFactory.getLogger("a");
logger.info("got a request");
ResturantExpenseEntity resturantExpenseEntity = new ResturantExpenseEntity();
resturantExpenseEntity.setDate(new Date(System.currentTimeMillis()));
resturantExpenseEntity.setName(dto.getName());
resturantExpenseEntity.setExpense(dto.getExpense());
repo.save(resturantExpenseEntity);
}
}
When I try to send request from restClient/RestedClient (both addons of mozila) I get the following error :
{
"timestamp": 1512129442019,
"status": 415,
"error": "Unsupported Media Type",
"message": "Content type 'text/plain;charset=UTF-8' not supported",
"path": "/expenses/restaurants"
}
This eror states that the end point doesnt support Json content,But I did
put
consumes =MediaType.APPLICATION_JSON_VALUE
inside #RequestMapping annotation
What am I missing?
Late response but I had the same problem posting the answer it might be useful to someone so I installed Postman and then just change your Content-Type to application/json
If the request is made like this: then it will resolve the issue.
curl -X PUT -H 'Content-Type: application/json' -i http://localhost:8080/spring-rest/api/employees/500 --data '{
"name": "abc",
"email": "abc.a#gmail.com",
"salary": 10000
}'
I see the headers are proper: headers = MediaType.APPLICATION_JSON_VALUE
but when the request is made, at that time we need to inform the handler that its a application/json mime type.
This is late too, but in RESTClient(Mozilla addon), you can add Content-Type: application/JSON from the Headers dropdown menu and even at the response side change it to JSON format
if you are using html with ajax.Check the request header and the payload. Make sure the ajax has the following fields
url : your url
type : 'post',
dataType: "json",
contentType: "application/json; charset=utf-8",
data : JSON.stringify( your payload )
if the ajax call has the following fields remove them and try again
processData : false,
contentType : false,

WebAPI OData v4 custom action without parameters can't be routed with error "No routing convention was found..."

I have very simple OData controller that successfully process standard actions (at least GET, POST, PUT and DELETE methods are working). I have followed this tutorial and added simple bound action. The method has parameters argument, but actually it does not required the parameters:
[HttpPost]
public IHttpActionResult Close([FromODataUri] int key, ODataActionParameters parameters) {
return Ok();
}
I have defined this action in OData EDM configuration as following:
builder.EntitySet<Ticket>("tickets");
builder.EntityType<Ticket>().Action("Close");
I am trying to call action from Postman:
POST /odata/tickets(2)/Default.Close HTTP/1.1
Host: localhost:50477
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: eef4c1f6-8c7f-f5eb-c22d-4397f3bda170
But receives the error message:
{
"error": {
"code": "",
"message": "No HTTP resource was found that matches the request URI 'http://localhost:50477/odata/tickets(2)/default.close'.",
"innererror": {
"message": "No routing convention was found to select an action for the OData path with template '~/entityset/key/unresolved'.",
"type": "",
"stacktrace": ""
}
}
}
I have read the whole internet and all related articles on SO but can't fix this issue. Please help me because I have no any fresh idea how to fight this.
My controller:
public class TicketsController : ODataController
{
[HttpPost]
public IHttpActionResult Close([FromODataUri] int key, ODataActionParameters parameters)
{
return Ok();
}
}
My request:
string requestUri = "http://localhost/odata/tickets(2)/Default.Close";
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUri);
request.Content = new StringContent("",
Encoding.UTF8,
"application/json");
HttpResponseMessage response = _client.SendAsync(request).Result;
Or remove the ODataActionParameters parameters in the close method and call with:
string requestUri = "http://localhost/odata/tickets(2)/Default.Close";
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUri);
HttpResponseMessage response = _client.SendAsync(request).Result;
My EdmModel is use your model.

Http multipart request using Google Drive API

I am trying to send HTTP multipart request using Google Drive API to insert file in Google Drive.
I am following the link below : Multipart upload
However, I am getting a Bad request error.
Below is the request string which I have created using the documentation link above:
String content = '\r\n--' + boundary + '\r\n';
content +='Content-Type: '+'application/json; charset=UTF-8'+'\r\n\r\n';
content +='{' + '\r\n';
content +='"title": "My File"'+'\r\n';
content +='}'+'\r\n\r\n';
content += '--'+boundary + '\r\n';
content +='Content-Type: '+'text/plain'+'\r\n';
content += EncodingUtil.base64Encode(b)+'\r\n';
content += '-'+boundary+'-\r\n';
Please can someone tell me what I am missing here ??
I was having trouble with this as well,
but if you look at the code for the google drive API on github:
Github Drive API
The request parameters accept a media object, which can have a body and mimeType.
I was working with a service account, and this lets you upload files directly to drive.
auth.getApplicationDefault(function(err, authClient) {
if (err) {
console.log('Authentication failed because of ', err);
return;
}
if (authClient.createScopedRequired && authClient.createScopedRequired()) {
var scopes = ['https://www.googleapis.com/auth/drive'];
authClient = authClient.createScoped(scopes);
}
var request = {
project: "YOUR_PROJECT",
auth: authClient,
resource: {
parents: ['blah']
},
media: {
body: 'hi',
mimeType: 'text/plain'
}
};
drive.files.create(request, function(err, result) {
if (err) {
console.log(err);
} else {
console.log(result);
}
});
});
I had this problem too and after trying some changes I finally reached a working example:
Header :
POST /upload/drive/v2/files?uploadType=multipart&access_token=ya29.CjAmA2j6eonCiROaNum-V1cWdFVH2vXpNiXAsXK6iLPu7K54tD4uNsmH-eEycMcnaBE HTTP/1.1
Host: www.googleapis.com
Accept: */*
Content-Type: multipart/related; boundary="foo_bar_baz"
Content-Length: 150
remember to add boundary="foo_bar_baz" in Content-Type field
Body :
--foo_bar_baz
Content-Type: application/json; charset=UTF-8
{
"title": "My File"
}
--foo_bar_baz
Content-Type: text/txt
JPEG data
--foo_bar_baz--

Resources