string is null when posting from Angular to Web API? - c#

When I try to post a string to my web api, the value is null. I have tried wrapping it in quotes, but it is still null.
AngularJS code:
return $http.post("http://localhost:59437/api/Recaptcha/Post",
vcRecaptchaService.getResponse());
Web Api code:
[EnableCors("*", "*", "*")]
public class RecaptchaController : ApiController
{
public string Post([FromBody] string response)
{
return response;
}
}
I also am not sure how this even works because, i don't have a response in my form body. vcRecaptchaService.getResponse() just returns a response string and then I am going to send that to google's verify api to verify the recaptcha, so the [FromBody] part doesn't make sense to me if that is not part of the body

Your post call should be sending data in json format like {response: 'something'}
return $http.post("http://localhost:59437/api/Recaptcha/Post",
{ response: vcRecaptchaService.getResponse() } //data
);

Wrapping it in quotes worked, but I had to do it just like this:
return $http.post("http://localhost:59437/api/Recaptcha/Post",
'"' + vcRecaptchaService.getResponse() + '"'
);

Related

Unable to invoke [HttpPost] web api

Below is my post method
[HttpPost]
public string Happay(string fileName)
{
//some code
}
When I try to invoke it from postman using this URL https://localhost:44313/SAPAPI/Happay?fileName=Payload1 it works but when I try to do the same from the browser it give me an exception that says
Resource not found
I removed the [HttpPost] attribute from the top an then I was able to invoke the method from the browser.
The QueryString (in your case ?fileName=Payload1) is only applicable for GET requests.
In case of POST you can provide parameters
as part of the request route, like POST /SAPAPI/Happay/Payload1
as a request body, like filename=Payload1 as raw
as a request header, like "x-file-name": "Payload1"
Depending on the mode you need to specify from where do you expect the parameter
public string Happay([FromRoute]string fileName)
public string Happay([FromBody]string fileName)
public string Happay([FromHeader(Name = "x-file-name")]string fileName)
Parameter as
Sample
Code change
Route
POST /SAPAPI/Happay/Payload1
[FromRoute(Name="fileName")]string fileName
Body
fileName=Payload1
[FromBody(Name="fileName")]string fileName
Header
"x-file-name": "Payload1"
[FromHeader(Name="x-file-name")]string fileName
Add [FromBody] before the parameter.
[HttpPost]
public string Happay([FromBody] string fileName)
{
//some code
}
If you are calling the url from a browser, this is a GET request. Please learn more about REST.

Unescape json response in REST API

I have a REST API written in C #. Method DoQuery send query to the database, and get json as response
public async Task<QueryResponseDto> DoQuery(string request)
{
return await _dbConnection.QuerySingleAsync<QueryResponseDto>("select web.json_request('" + request + "') as response;",commandTimeout:600);
}
...
[HttpPost]
[Route("DoQuery")]
public async Task<string> DoQuery([FromBody] object body)
{
var r = await _dataService.DoQuery(JsonSerializer.Serialize(body));
return r.response;
}
When I run query in database, I get correct json answer like this
[
{
"contractor":{
"ek2id":"91707d21-50f3-4aa4-8209-e80b963da99d",
"externalids":[
{
"externalsource":"SBL",
"externalid":"1-4OB8C75"
}
]
}
}
]
But when I run method DoQuery from PostMan I get escaped response like this
"[{\"contractor\":{\"ek2id\":\"91707d21-50f3-4aa4-8209-e80b963da99d\",\"externalids\":[{\"externalsource\":\"SBL\",\"externalid\":\"1-4OB8C75\"}]}}]"
How can I get normal unescaped response from REST API?
When you query the database it formats the JSON for you when it displays the output. The actual value in the database could be some UTF8, or similar encoding.
If escape is causing issue you could try storing actual UTF8 value for quotes in the string. But in both the cases you need to encode the response.

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?

string parameter in controller is null when using webclient

When I use WebClient to call a function in a controller
using (WebClient client = new WebClient())
{
client.BaseAddress = "http://localhost/";
client.Headers.Add("Content-Type", "application/json");
client.UploadString("api/test", HttpMethod.Put.ToString(), stringParameter);
}
I called the function in controller successfully but the "stringParameter" in controller is empty like the following code:
[Route("api/test")]
[HttpPut]
public async Task<IHttpActionResult> Test([FromBody] string stringParameter)
{
if (!ModelState.IsValid)
{
// the flow goes here
return BadRequest(ModelState);
}
// ...
}
I would like to know where is the mistake(s) I made and how to fix the problem(s). Thank you very much.
Remark: "stringParameter" is fine if it is numeric such as "123" but not work if it is "A123" or "B123".
As you're setting content type to "application/json" you should be sending a valid JSON value rather then raw string. A number is JSON and in plain text is the same, so that's why it works.
Try serializing the text to JSON before sending:
JsonConvert.ToString(stringParameter);
(I'm using Newtonsoft.Json nuget package here)
Alternatively you can try to use content type text/plain, but I'm not sure if your web api is configured to handle that by default.

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