Web API Null Content C# from Postman - c#

Trying this so hard.
Been calling a function API from Postman but when I tried to check the content it is null and the method is GET but I have set to POST.
Here is the receiving code
[System.Web.Http.HttpPost()]
// POST: Stream_Technical
public void Update_Activation(HttpRequestMessage request)
{
string message = request.Content.ReadAsStringAsync().Result;
}

Change your method like this
[HttpPost("collection")]
// POST: Stream_Technical
public void Update_Activation([FromBody]HttpRequestMessage request)
{
string s = JsonConvert.SerializeObject(request);
// string message = request.Content.ReadAsStringAsync().Result;
}
Here I also attached a screen shot
post man request

Related

Unable to get child value on newtonsoft.Json.LinqJvalue when reading coinbase api?

Hello I am trying to get the coinbase API exchange rates from the URL however json.net does not seem to be able to format the JSON file to read the children
this is the method that throws the error
public string CalculateCoinValue(Coinbase connector)
{
//bool valid = connector.rates.isValid;
string cryptoExchangeRate;
if (connector.rates != null)
{
cryptoExchangeRate = (string)connector.rates["data"]["currency"]["rates"][Settings.defualtCrypto.ToUpper()];
}
return "";
}
this is the method im using to get the JSON data which stores it in a JObject whithin the Coinbase class
public async Task<JObject> GetExchangeRatesAsync()
{
HttpClient webClient = new HttpClient();
string url = string.Format("https://api.coinbase.com/v2/exchange-rates?currency=" + Settings.defaultCurrency);
HttpResponseMessage coinbaseJsonRaw = await webClient.GetAsync(url);
return JObject.Parse(await coinbaseJsonRaw.Content.ReadAsStringAsync());
}
what am I doing wrong for this not to work?
The json returned looks different. try the below
cryptoExchangeRate = (string)connector["data"]["rates"][Settings.defualtCrypto.ToUpper()];

Though I send response from HttpHead method , client says "Could not get any response"

I have a HttpGet method in a controller in a windows application project.
I need to return Headers from it, so method's return type is HttpResponsemessage. but not able to get any response from that method.
I have one HttpGet method in a controller in a windows application, it is behaving like a Head method, as I am changing Head request type to HttpGet using Handler (ref).
[HttpGet]
public HttpResponseMessage Get(HttpRequestMessage msg)
{
HttpResponseMessage res = new HttpResponseMessage
{
Content = new StringContent("", Encoding.UTF8, "text/plain")
};
res.Headers.Add("Connection", "Keep-Alive");
res.Headers.Add("Keep-Alive", "timeout = 1000 max = 100");
return res;
//return "Hi";
}
In wireshark when I see request and response,
I don't see any response , also tried by sending request from postman,
I am not able to get any response.
but when I change return type to string in gives status code 200 ok in response.
[HttpGet]
public string Get(HttpRequestMessage msg)
{
return "Hi";
}
But I want to return headers not content.
How can I achieve it?
Can anyone help me on this?

Receiving XML in HttpPost Using C#

I thought this would be pretty easy, but it's just not - at least for me. I am trying to send an XML string to a REST endpoint. At this time, the only thing the endpoint has to do is log the XML to a file or database. The XML itself is unknown, it could be literally any length and have any number of nodes. So it really needs to be treated as a string.
My problem is that I cannot determine how to receive the XML/string in the Post method. I am using the RestSharp library.
Here is the Post method I am using; very simple. I removed logging code and try/catch code to keep it simple.
[HttpPost]
public IHttpActionResult Post([FromBody] string status)
{
// Log the post into the DB
LogPost(status);
}
The code to perform the post:
public void TestPost()
{
IRestResponse response;
try
{
// Get the base url for
var url = #"http://blahblah/status";
// Create the XML content
object xmlContent = "<XML><test><name>Mark</name></test></XML>";
var client = new RestClient(url);
var request = new RestRequest(Method.POST);
// Add required headers
request.AddHeader("Content-Type", "text/plain");
request.AddHeader("cache-control", "no-cache");
request.AddJsonBody(xmlContent);
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
response = client.Execute(request);
}
catch (Exception ex)
{
...
}
}
The problem: the status parameter received by the post is, simply, "Mark". The full XML is missing! I need the entire XML string.
I have tried a few different variations of this. Changing the content-type to "application/xml", "application/json", etc. Nothing is working.
I have tried using request.AddXmlBody(statusObject), and request.AddBody(statusObject). Both were unsuccessful.
I have even tried sending the XML using request.AddHeader() with no luck. What am I missing. There must be something obvious that I'm not getting.
a) you must configure Web API to use XmlSerializer in your WebApiConfig.Register. Otherwise Web API uses the DataContractSerializer by default.
File: App_Start\WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Formatters.XmlFormatter.UseXmlSerializer = true; //HERE!
...
}
b) you need to define a class for your xml
public class test { public string name { get; set; } } //BASED ON YOUR XML NODE
[HttpPost]
public IHttpActionResult Post([FromBody] string status)
{
}
c) if you need to work with a simple string, change POST method
public void Post(HttpRequestMessage request)
{
string body = request.Content.ReadAsStringAsync().Result;
}
d) invoke from restsharp client
string xmlContent = "<test><name>Mark</name></test>";
var client = new RestClient(url);
var request = new RestRequest(Method.POST);
request.AddParameter("application/xml", xmlContent, ParameterType.RequestBody);
var response = client.Execute(request);
For "some" reason request.AddParameter takes the first param as ContentType(not the Name)
https://github.com/restsharp/RestSharp/issues/901
Did you tried to send the request with
Content-Type: application/xml; charset="utf-8"
instead of text\plain?

Get raw post request in an ApiController

I'm trying to implement a Paypal Instant Payment Notification (IPN)
The protocol is
PayPal HTTP POSTs your listener an IPN message that notifies you of an event.
Your listener returns an empty HTTP 200 response to PayPal.
Your listener HTTP POSTs the complete, unaltered message back to
PayPal; the message must contain the same fields (in the same order)
as the original message and be encoded in the same way as the
original message.
PayPal sends a single word back - either VERIFIED (if the message
matches the original) or INVALID (if the message does not match the
original).
So far I have
[Route("IPN")]
[HttpPost]
public void IPN(PaypalIPNBindingModel model)
{
if (!ModelState.IsValid)
{
// if you want to use the PayPal sandbox change this from false to true
string response = GetPayPalResponse(model, true);
if (response == "VERIFIED")
{
}
}
}
string GetPayPalResponse(PaypalIPNBindingModel model, bool useSandbox)
{
string responseState = "INVALID";
// Parse the variables
// Choose whether to use sandbox or live environment
string paypalUrl = useSandbox ? "https://www.sandbox.paypal.com/"
: "https://www.paypal.com/cgi-bin/webscr";
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(paypalUrl);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
//STEP 2 in the paypal protocol
//Send HTTP CODE 200
HttpResponseMessage response = client.PostAsync("cgi-bin/webscr", "").Result;
if (response.IsSuccessStatusCode)
{
//STEP 3
//Send the paypal request back with _notify-validate
model.cmd = "_notify-validate";
response = client.PostAsync("cgi-bin/webscr", THE RAW PAYPAL REQUEST in THE SAME ORDER ).Result;
if(response.IsSuccessStatusCode)
{
responseState = response.Content.ReadAsStringAsync().Result;
}
}
}
return responseState;
}
My problem is I can't figure out how to send the original request to Paypal with the parameters in the same order.
I could build a HttpContent with my PaypalIPNBindingModel but I can't guarantee the order.
Is there any way I could achieve this?
Thank you
I believe you should not use parameter binding and just read the raw request yourself. Subsequently, you can deserialize into the model yourself. Alternatively, if you want to leverage Web API's model binding and at the same time, access the raw request body, here is one way I could think of.
When Web API binds the request body into the parameter, the request body stream is emptied. Subsequently, you cannot read it again.
[HttpPost]
public async Task IPN(PaypalIPNBindingModel model)
{
var body = await Request.Content.ReadAsStringAsync(); // body will be "".
}
So, you have to read the body before model binding runs in Web API pipeline. If you create a message handler, you can ready the body there and store it in the properties dictionary of the request object.
public class MyHandler : DelegatingHandler
{
protected async override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
if (request.Content != null)
{
string body = await request.Content.ReadAsStringAsync();
request.Properties["body"] = body;
}
return await base.SendAsync(request, cancellationToken);
}
}
Then, from controller you can retrieve the body string, like this. At this point, you have the raw request body as well as the parameter-bound model.
[HttpPost]
public void IPN(PaypalIPNBindingModel model)
{
var body = (string)(Request.Properties["body"]);
}

how to return json error msg in asp.net web api?

I would like to return a json errormessage but at the moment in fiddler I cannot see this in the json panel:
string error = "An error just happened";
JsonResult jsonResult = new JsonResult
{
Data = error,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
response = Request.CreateResponse(HttpStatusCode.BadRequest, jsonResult.Data);
how to do this?
A few points:
If all you're looking to do is return an error response containing a simple error message, Web API provides a CreateErrorResponse method for that. So you can simply do:
return Request.CreateErrorResponse(HttpStatusCode.BadRequest,
"An error just happened");
This will result in the following HTTP response (other headers omitted for brevity):
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Content-Length: 36
{"Message":"An error just happened"}
If you want to return a custom object instead, then you use Request.CreateResponse like you were doing, but don't use the MVC JsonResult. Instead, just pass your object directly to CreateResponse:
var myError = new
{
Data = "An error just happened",
OtherDetails = "foo bar baz"
};
return Request.CreateResponse(HttpStatusCode.BadRequest, myError);
Now, say you are doing this but you're not getting JSON back from the server. It is important to realize that Web API normally uses content type negotiation to determine what format to use when sending the response back. That means, it looks at the Accept header that was sent by the client with the request. If the Accept header contains application/xml, for example, then Web API will return XML. If the header contains application/json then it will return JSON. So, you should check that your client is sending the correct Accept header.
That said, there are ways to force Web API to always return data in a specific format if that is what you really want. You can do this at the method level by using a different overload of CreateResponse which also specifies the content type:
return Request.CreateResponse(HttpStatusCode.BadRequest, myError,
new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"));
Alternatively, you can remove the XML formatter from the configuration altogether in your WebApiConfig file:
config.Formatters.Remove(config.Formatters.XmlFormatter);
This will force Web API to always use JSON regardless of what the client asks for.
you can return JSON like below,
return Request.CreateResponse<ResponseApiModel>(HttpStatusCode.BadRequest, response);
I recommend to use IHttpActionResult on your method return type instead HttpResponseMessage, if your api's method return type is IHttpActionResult. you can return like;
return Content(HttpStatusCode.InternalServerError, response);
you can check also that link about best practice of error returning Especially #Daniel Little's answer is really useful.
I know the answer added to late but maybe stand someone in good stead.
JsonResult is a MVC concept. It does not work in Web API. One way to explicitly return json content is to use the class I created in this answer https://stackoverflow.com/a/20504951/6819
Add
config.Formatters.Remove(config.Formatters.XmlFormatter);
line in your WebApiConfig file
I think this will help you or others.
define your custom ApiController
public abstract class ApiController : System.Web.Http.ApiController
{
protected internal virtual BadRequestErrorMessageResult BadRequest(object message)
{
return new BadRequestErrorMessageResult(message);
}
}
define custom message result class
public class BadRequestErrorMessageResult : IHttpActionResult
{
private readonly object _message;
public BadRequestErrorMessageResult(object message)
{
_message = message;
}
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.BadRequest)
{
Content = new ObjectContent<object>(_message, new JsonMediaTypeFormatter(), "application/json")
};
return Task.FromResult(response);
}
}
use your custom response method
// GET api/<controller>
[Authorize]
[HttpGet]
public IHttpActionResult Test()
{
return BadRequest(new
{
Succeeded = false,
Message = "An error occurred during processing, please contact the administrator!"
});
}
response data with custom header error status code
{"Succeeded":false,"Message":"An error occurred during processing, please contact the administrator!"}
You can directly set the status code of the current HTTP response through Response property
Response.StatusCod = (int)HttpStatusCode.BadRequest;
return Json(HttpStatusCode.BadRequest);

Categories