WCF Data Services - Custom POST method - c#

I have created a WCF Data Service and it works fine. My Custom methods that are GET type methods work ok as well. The problem is in POST custom method.
The method looks like that:
[WebInvoke(Method = "POST")]
public string CustomMethod(string myParameter)
{
return "yes" + myParameter;
}
I also invoke:
config.SetServiceOperationAccessRule("CustomMethod", ServiceOperationRights.All);
Then in fiddler my request looks like that:
Method: POST
URL: http://localhost:1219/DataService.svc/CustomMethod
Reguest Headers:
User-Agent: Fiddler
Host: localhost:1219
Content-Length: 27
Content-Type: application/x-www-form-urlencoded
Request Body:
myParameter=parameter1value
The method gets called but the "myParameter" parameter is always null. What am I missing?
Thanks for your time.

Please refer to Section 10.4.1.3. Invoking an Action for OData 3.
Short story: The content type must be JSON.
If the invoke request contains any non-binding parameter values, the
Content-Type of the request MUST be 'application/json', and the
parameter values MUST be encoded in a single JSON object in the
request body.

I believe the way you are passing parameter 'myParameter' may be wrong.
you can try to consume your service using visual studio and then try to pass it.
one more question..
when you call the service as get service, is Content-Type is
Content-Type:application/x-www-form-urlencoded

Related

ASP.NET Web API 2.0 Parameters Null

I know it's been asked a lot of time and I have tried everything but still facing the problem. Here is my code:
// POST api/<controller>
public string Post([FromBody]string value)
{
return value;
}
There is nothing fancy just returning the value.
I am using Chrome's PostMan Plugin
I have tried like 100 times but still getting the same null value as the response. I have tried it with Content-Type application/json and everything mentioned but still getting null.
Not really sure what the question is however what you are looking for is to setup your POST with a single value.
Such as below:
POST /api/values HTTP/1.1
Host: localhost:50121
Content-Type: application/json
Accept: application/json, text/javascript
Cache-Control: no-cache
'abc'
Now this is a JSON post so the body doesn't have a parameter name, this is by design as you are posting a single value.
If you need multiple values or a more complex object you should use a class object instead of a single value.

ServiceStack Client Put request and query parameters

I'm using the latest ServiceStack client lib in a .Net project and I'm having some issue making a PUT request.
Especially it doesn't seem to take into account the type of parameter defined in the RequestDto object and put all params in the body (despite the param being defined as type ="query").
My Request object (auto-generated) looks like this:
[Route("/test/name", "PUT")]
public partial class PutTestName
: IReturn<PutTestNameResponse>
{
///<summary>
///the user id
///</summary>
[ApiMember(Description = "the user id", ParameterType = "query")]
public virtual string UserId { get; set; }
///<summary>
///the name
///</summary>
[ApiMember(Description = "the name", ParameterType = "query")]
public virtual string Name { get; set; }
}
I make the call like this:
_apiClient.Put(new PutTestName(){UserId ="xyz..", Name="Bob"});
and I get "Resource not found" exception in return.
When I run the query manually using Postman (and putting both parameters in the Querystring) it works ok.
When debugging the C# client with fiddler I can see that no parameter is set to the query string and they are both passed in the body.
Edit: This what the Fiddler Request Raw looks like:
PUT https://xxxx/test/name HTTP/1.1
User-Agent: ServiceStack .NET Client 4.56
Accept-Encoding: gzip,deflate
Ocp-Apim-Subscription-Key: 783....
Content-Encoding: gzip
Accept: application/json
Content-Type: application/json
Host: xxx.net
Content-Length: 115
Expect: 100-continue
Connection: Keep-Alive
{"UserId":"xxx","Name":"Bob"}
There is Azure API Management between the ServiceStack API and my call but I don't think this is the issue. The client code is setting the parameters in the body while they're supposed to be in the query.
If the same request works with POST then it's likely that WebDav is enabled and interfering with your PUT Request in which case you should disable WebDav so the request can reach ServiceStack unimpeded.
For debugging HTTP Interoperability issues like this, you should inspect (and provide here) the Raw HTTP Response Headers using a tool like Fiddler, Chrome Web Inspector or WireShark. If the HTTP Response Headers doesn't include an X-Powered-By: ServiceStack.. Header than it's likely the request has been intercepted and blocked before it reaches ServiceStack, e.g. IIS/ASP.NET or a forwarding proxy.
The client code is setting the parameters in the body while they're
supposed to be in the query.
ServiceStack only sends parameters in the body for HTTP Verbs that don't have a request body like GET or DELETE, for Verbs with Request bodies, e.g. POST or PUT ServiceStack's JsonServiceClient will POST JSON as expected.
ServiceStack Services will accept parameters posted in either QueryString, JSON Request Body or x-www-form-urlencoded Content-Type. If you're not calling a ServiceStack Service you should be using a generic HTTP Client like HTTP Utils which will allow you to control exactly how the Request is sent, e.g:
var response = absoluteUrl.ToPutUrl(new PutTestName {...});
Will send the results as x-www-form-urlencoded.
ServiceStack's .NET Service Clients are only for sending requests to ServiceStack Services.

How Do I Pass Json Object From Fiddler To Webapi2

http://localhost:15641/api/Complaints/NewComplaint
User-Agent: Fiddler
Content-Type: application/json
Host: localhost:15641
Content-Length: 63
RequestBody
{
"CostCentre":"test","ComplaintText":"This is test Complaint"
}
WebApi Controller
[Route("api/Complaints/NewComplaint")]
[HttpPost]
public void CreateNewComplaint(BLL.Complaint complaint)
{
//call BLL Create complaint method
}
}
my object is with null values
where am i doing wrong ?
i put breakpoints on controller the complaint object is set with all null values
if i don't pass the values complaint object it self is null
how can i pass the object
Web API expects the data sent to it to be serialized in a fashion like this:
Key1=Value1&Key2=Value2&...
If you are using JavaScript or JQuery, make sure that you're sending an Object(in your case matching Bll.Complaint), not a JSON string. If you give us more details on how you execute the request I will update this answer to have an example of how to do the serialization.

asp.net API post values received are null from postmaster

I'm writing a very basic asp .net api with a simple post method. The post parameters are returning null. I've tried various ways to get the method to return the object I passed in. I created a data transfer object and I've verified that the method is getting called. What else can I check ?
post master settings ----
url: /api/values
params: incidentID 4
params: incidentTitle 'this is some text'
Content-Type: application/json
// POST api/values
[Route("api/values")]
[HttpPost]
public HttpResponseMessage Post([FromBody]incidentDTO incid)
{
return Request.CreateResponse(incid);
}
I assume by postmaster you meant Postman.
If you are using Postman, use the following steps:
Under Header type Content-Type with a value of application/json
Select the raw tab and enter your data as follows:
{
"incidentId":4,
"incidentTitle":"this is some text"
}
Click on Send.
As the post data is being read from the body, there in no need to enter any values in URL params.

Is it possible or necessary to set the content type of a ServiceStack client delete request?

I have the following code.
public T SendUpdateRequest(string url)
{
using (JsonServiceClient client = new JsonServiceClient())
{
T response = client.Put<T>(url);
return response;
}
}
I have similar methods for create and delete requests, calling the JsonServiceClient Post and Delete methods respectively.
When calling my update or create methods, the call to the external API works fine. Delete does not. I can see that the API's delete method does indeed work if I fire a request to it via REST console.
When I compare my non-working delete with the working one's request/response in Fiddler, I can see the main difference is my request is not setting content-type to application/json (all these methods return JSON).
My question is, is it possible (or even necessary) to explicitly set the content-type of my delete request to application/json in order to successfully call my API method?
The ServiceStack clients do not set the content-type header on requests where there is no request body, as the content-type only applies to the body, and is therefore redundant.
This can be seen here in the code that prepares the client request.
if (httpMethod.HasRequestBody())
{
client.ContentType = ContentType;
...
A correctly implemented RESTful service should be happy with a DELETE request without content-type being specified where there is no body.
DELETE /User/123 HTTP/1.1
If the service you are calling is not happy with your request without this type being specified (which is unusual), then you can manually enforce the sending of the type using this filter:
var client = new JsonServiceClient("https://service/");
client.RequestFilter += (httpReq) => {
// Force content type to be sent on all requests
httpReq.ContentType = "application/json";
};
I hope that helps.

Categories