Web API: FromBody always null - c#

I'm trying to develop a web API, and when I test the POST method, the body is always null. I have tried everything when sending the request:
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://localhost:1748/api/SomeAPI");
req.Method = "post";;
var aaa = Encoding.Default.GetBytes("Test");
req.ContentType = "application/xml";
req.ContentLength = aaa.Length;
req.GetRequestStream().Write(aaa, 0, aaa.Length);
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
using (System.IO.StreamReader sr = new System.IO.StreamReader(res.GetResponseStream())) {
Console.WriteLine(sr.ReadToEnd());
}
I use a breakpoint, and the API is called properly, but the body member is always null:
[HttpPost]
public void Post([FromBody]String test) {
}

try
[HttpPost]
public void SomeApi()
{
var test = HttpContext.Current.Request.Form["Test"];
}
If u send correctly the value,this will work 100%

Your Content Type is set to XML so you must pass the data as XML. This means wrapping your data in <string> element.
I would recommend using RestSharp (http://restsharp.org/) for making WebAPI calls from .Net.
var client = new RestClient("http://localhost:1748/");
var request = new RestRequest("api/SomeAPI", Method.POST);
request.AddBody("Test");
var response = client.Execute(request);
Update
I have created a sample project and it works absolutely fine:
Server side:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
namespace WebApplication1.Controllers
{
public class HomeController : ApiController
{
[Route("api/TestAPI")]
[HttpPost]
public IHttpActionResult Post([FromBody]String test)
{
return Ok(string.Format("You passed {0}.", test));
}
}
}
Client side:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://localhost:1748/api/TestAPI");
req.Method = "post"; ;
var aaa = Encoding.Default.GetBytes("\"Test\"");
req.ContentType = "application/json";
req.ContentLength = aaa.Length;
req.GetRequestStream().Write(aaa, 0, aaa.Length);
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
using (System.IO.StreamReader sr = new System.IO.StreamReader(res.GetResponseStream()))
{
Console.WriteLine(sr.ReadToEnd());
}
}
}
}
After installing the WEB API service in IIS and running the console app it prints:
"You passed Test."
Please note the quotes around the response.
If you want to use XML then you need to modify the content type and data you are sending:
var aaa = Encoding.Default.GetBytes("<string xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/\">Test</string>");
The response you will get is
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">You passed Test.</string>
Both samples in the debugger will have correct value passed in the test parameter.

Two things to try, 1st, try your request using a tried and tested tool like Postman. This will eliminate any chance your request is malformed in any way. 2nd, try changing your ContentType to text/plain. It's possible the request pipeline is seeing application/xml but your request body is invalid xml which really should be a bad request but is just being serialized as null.

Related

POST function in RestSharp

I want to POST a file to an API by RestSharp, but the Method.Post encounter error as cannot convert from 'RestSharp.Method' to 'string?', and the error for the Method.POST is 'Method' does not contain a definition for 'POST'?
using RestSharp;
using System;
using System.Net;
using System.Net.Http;
namespace UploadToAzure
{
class Program
{
static void Main()
{
var client = new RestClient("http://localhost:7071/api/Function1");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddFile("File", "/D:/sample Files/audio0001.mp3");
IRestResponse response = (IRestResponse)client.Execute(request);
Console.WriteLine(response.Content);
}
}
}
Thanks for your answers!
It solved when I add string of destination to RestRequest and change IRestResponse to RestResponse. In addition correct the path of file.
using RestSharp;
using System;
using System.Net;
using System.Net.Http;
namespace UploadToAzure
{
class Program
{
static void Main()
{
var client = new RestClient("http://localhost:7071/api/Function1");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddFile("File", #"D:/sample Files/audio0001.mp3");
RestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
}
}
}
I had similar issue, but solved it by doing the following two things
Changed POST to Post.
Putting Method.Post in double quotes "", i.e treating it as a string.

HttpClient and HttpWebRequest cannot make empty Post request

Seems HttpClient is not able to perform the following post request (it throws validation errors)
POST with URI encoded parameters
no Body but Content-Type header setted.
I'm sure this is a problem of usage of C# since I was able to perform the correct request with Postman (see the image)
The service I'm trying to authenticate against is this one Fitbit OAUTH2
I tried also HttpWebRequest, but I failed to do that even with that class, however here's also the second attemp. Seems C# is performing some action different from Postman but I have to figure out which action. Does anyone ever had a similiar issue?
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
public static class MyRequest
{
public static string Call( string uri, string headerName, string header)
{
HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create( uri);
webRequest.Method = "POST";
webRequest.Headers.Add( "Authorization", $"{headerName} {header}");
webRequest.ContentType = "application/x-www-form-urlencoded";
var response = (HttpWebResponse) webRequest.GetResponse();
if(response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.Created)
{
}
else
{
return null;
}
using ( var stream = response.GetResponseStream())
{
return stream.ToString();
}
}
}
If I use the HttpClient with the following content
content = FormUrlEncodedContet( keyValues)
the final URL do not have the #_=_ appended, and that is requested by that service otherwise it returns 401

How do I properly post to a php web service using JSON and C#

I'm trying to contact a simple login web service that will determine whether the JSON request was successful or not. Currently, in the C# program I am geting an error saying a JSON argument is missing. The proper URL to request in the web browser is:
https://devcloud.fulgentcorp.com/bifrost/ws.php?json=[{"action":"login"},{"login":"demouser"},{"password":"xxxx"},{"checksum":"xxxx"}]
The code that I have implemented right now in C# is:
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Web.Script.Serialization;
namespace request
{
class MainClass
{
public static void Main (string[] args)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://devcloud.fulgentcorp.com/bifrost/ws.php?");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = new JavaScriptSerializer().Serialize(new
{
action = "login",
login = "demouser",
password = "xxxx",
checksum = "xxxx"
});
Console.WriteLine ("\n\n"+json+"\n\n");
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
Console.WriteLine (result);
}
}
}
}
It looks like the sample URL is passing the JSON as a query string - it is a simple GET request.
You are trying to POST the JSON - which is a much better approach that passing JSON in the query string - i.e because of length limitations, and the need to escape simple characters such as space. But it will not work as does your sample URL.
If you are able to modify the server I would suggest modifying the PHP to use $_REQUEST['action'] to consume the data, and the following C# code:
Public static void Main (string[] args)
{
using (var client = new WebClient())
{
var Parameters = new NameValueCollection {
{action = "login"},
{login = "demouser"},
{password = "xxxx"},
{checksum = "xxxx"}
httpResponse = client.UploadValues( "https://devcloud.fulgentcorp.com/bifrost/ws.php", Parameters);
Console.WriteLine (httpResponse);
}
}
If you must pass JSON as a query string, you can use UriBuilder to safely create the full URL + Query String and then make the GET request - no need to POST.

Sending HTTP request from Netduino

I have Netduino Plus and I need it to send Http requests to my server. I'm not a guru in C#, I've never tried it before, so I copy/paste code from internet and try to make it works. But even after several hours I can't get it work.
using System;
using System.IO;
using System.Net;
using System.Text;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;
namespace NetduinoPlusApplication5
{
public class Program
{
static void Main()
{
var request = WebRequest.Create("http://example.com?variable=1");
request.Method = "GET";
var result = request.GetResponse();
}
}
}
What am I doing wrong?
You are executing a GET request so I think you want to get the response body from the server. In this case you have to use :
Stream respStream = resp.GetResponseStream();
instead of simple GetResponse(). In this way, you can read on the stream the response body.
Paolo.

Login to MineCraft using C#

I'm trying to create a simple custom minecraft launcher for myself and some friends. I don't need the code to start minecraft, just the actual line of code to login. For example, to my knowledge, you used to be able to use:
string netResponse = httpGET("https://login.minecraft.net/session?name=<USERNAME>&session=<SESSION ID>" + username + "&password=" + password + "&version=" + clientVer);
I'm aware there is no longer a https://login.minecraft.net, meaning this code won't work. This is about all I need to continue, only the place to connect to login, and the variables to include. Thanks, if any additional info is needed, give a comment.
You need to make a JSON POST request to https://authserver.mojang.com/authenticate and heres my method of getting an access token (which you can use to play the game)
Code:
string ACCESS_TOKEN;
public string GetAccessToken()
{
return ACCESS_TOKEN;
}
public void ObtainAccessToken(string username, string password)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://authserver.mojang.com/authenticate");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{\"agent\":{\"name\":\"Minecraft\",\"version\":1},\"username\":\""+username+"\",\"password\":\""+password+"\",\"clientToken\":\"6c9d237d-8fbf-44ef-b46b-0b8a854bf391\"}";
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
ACCESS_TOKEN = result;
}
}
}
Declare these aswell:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.IO;
using System.Web.Script.Serialization;
And if you haven't already, refrence System.Web.Extentions
I tested this with C# winforms and it works :)
Thanks,
DMP9
The login server is now https://authserver.mojang.com/authenticate, and it uses JSON-formatted info.
Use this format for the JSON request:
{"agent": { "name": "Minecraft", "version": 1 }, "username": "example", "password": "hunter2"}
Here is a full implementation for logging in.

Categories