How to fetch body data from IHttpActionResult in MVC Controller? - c#

I have ApiController which receives a specific object of a class. That works perfect but what if, HTTP Request which contains a body with JSON is not matching with the object of a class? I will receive a null value of object because there is not a match between JSON and object of a class. My question is, how to get original JSON request when a user sends JSON with an incorrect format?
public class Document{
string name;
int number;
}
JSON REQUEST
{
"name":"Default name",
"number":91526861713"
}
JSON IS INCORRECT BECAUSE DATA TYPE OF number is int, not string "234" !
Automatically documentObject in function is equal to null.
How to get original JSON REQUEST?
[HttpPost]
public IHttpActionResult Receiving([FromBody]Document documentObject)
{
}

you can use Request.Content , But output is raw string.
like this:
[HttpPost]
public async Task<IHttpActionResult> Receiving([FromBody]Document documentObject)
{
var content = await Request.Content.ReadAsStringAsync();
return Json(content); // output => "name=xxx&number=123"
}

Related

How can I bind simple type coming from body of the request in ASP.NET Core 5 Web API

I tried to send a JSON object with the same name that action argument has but It seems not working I don't know what I did wrong.
My question is how to bind simple types like the example shown, without the need to create complex type that wrap my value property?
Action
public IActionResult Test([FromBody] string value)
{
}
PostMan : raw > JSON
{
"value":"testValue"
}
public class MyRequest {
public string Value { get; set; }
}
//controller
IActionResult Test([FromBody] MyRequest request)
This should do the job.
The class/type related to the frombody object should match the whole json object and not only one property of it
This cannot work with GET requests, so try a POST

How to allow an empty request body for a reference type parameter?

I'm Building an .Net Core api controller, I would like to allow users to send GET requests with or without the MyRequest class as a parameter, so the calling the method with Get(null) for example will be Ok.
GET api/myModels requests method:
[HttpGet]
public ActionResult<IEnumerable<MyModel>> Get(MyRequest myRequest)
{
if (myRequest == null)
myRequest = new myRequest();
var result = this._myService.Get(myRequest.Filters, myRequest.IncludeProperties);
return Ok(result);
}
MyRequest class:
public class MyRequest
{
public IEnumerable<string> Filters { get; set; }
public string IncludeProperties { get; set; }
}
When I refer to this Get method using Postman with Body, it works.
The problem is, when I keep the body empty (to call the Get method with a MyRequest null object as a parameter like Get(null)) I'm getting this Postman's massage of:
"A non-empty request body is required."
There is a similar question, but there, the parameters are value type.
Do this:
services.AddControllersWithViews(options =>
{
options.AllowEmptyInputInBodyModelBinding = true;
});
You can make it a optional parameter by assigning a default value null and specifying explicitly that the values will be coming as part of request url
[HttpGet]
public ActionResult<IEnumerable<MyModel>> Get([FromQuery]MyRequest myRequest = null)
{
BTW, a GET operation has no body and thus all the endpoint parameter should be passed through query string (Or) as Route value.
You should specify a routing in your api end point and have the values passed through route and querystring. something like
[HttpGet("{IncludeProperties}")]
//[Route("{IncludeProperties}")]
public ActionResult<IEnumerable<MyModel>> Get(string IncludeProperties = null, IEnumerable<string> Filters = null)
{
With the above in place now you can request your api like
GET api/myModels?Filters=

ASP.Net Core web app POST method always receives NULL as a parameter

In VS2017 I created new ASP.NET Core Web Application
I sample code Get methods works perfectly, but
POST method always receives null as parameter.
This method:
[HttpPost]
public void Post([FromBody]string value)
{
System.Diagnostics.Debug.Print("\n'" + value + "'\n");
}
I tried:
curl -X POST -H "Content-Type: application/json" -d '{"msg": "hello"}' localhost:57084/api/values
In Post value is null.
Tried use POSTMAN: with all possible combinations of content type and message body. NULL as input.
Tried to pass value with '=' as someone suggested. Same, null.
Tried to use dynamics.
public void Post(dynamic value)...
, Value is null.
Tried to use
public void Post([FromBody] HttpRequestMessage request)...
-- same, null.
When I used
[HttpPost]
public void Post(HttpRequestMessage request) // [FromBody]
{
string body = request.Content.ReadAsStringAsync().Result;
var headers = request.Headers;
}
Request had properties: Method: "GET", RequesrURL=null, Headers=null, Content=null
It might be something small and stupid, but I cannot seems to find it yet.
Create a model to hold the data sent to the controller action.
For example, given the following JSON
{"msg": "hello"}
A strongly typed model would look like
public class MyModel {
public string msg { get; set; }
}
Then refactor the controller to expect that model
[HttpPost]
public IActionResult Post([FromBody]MyModel model){
//...access the model
return Ok(model); //echo
}
The request parameter passed through the request is different from the expected one.
If you define your action expecting a string parameter called "value", the expected parameter when you call the request will be:
{ "value" : "something here" }

C# Returning Plain Json from MVC Controller

I'm trying to send data as plain Json, from my controller to the client side of my MVC application. The data is initially collected as a list of objects but I'm having trouble converting it to straight Json. Right now the code in my controller is as follows:
[HttpGet]
public JsonResult SecurityPermissionsTableData()
{
List<SecurityPermissionsGridModel> list = securityPermissionsTable.Get(System.Security.Principal.WindowsIdentity.GetCurrent().Name.Split('\\').Last());
string json = JsonConvert.SerializeObject(new
{
data = list
});
return ResultJson(json);
}
public JsonResult ResultJson(object data)
{
return new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet, Data = data };
}
When I use the JsonConvert.SerializeObject() function, it returns a string:
"{\"data\":[{\"Username\":\"loganfg\",\"readbutton\":null,\"editbutton\":null,\"deletebutton\":null}]}"
However I need to return plain Json in the form of:
{"data":[{"Username":"lgilmore","readbutton":"<a onclick='SP_read(\"7\")' class='SRKbutton tiny SP_rbutton'>Details</a>","editbutton":null,"deletebutton":null}]}
How can I convert the string the serialize function returns to plain Json? Or how do I alter my ResultJson() function to properly handle and convert the string?
JsonResult already serializes the object for you.
Therefore, it's serializing your string to a JSON string literal.
You should get rid of all of your code and just
return Json(list, JsonRequestBehaviour.AllowGet);
You may simply use the Json method.
Pass the object you want to convert to json as the parameter.
public JsonResult SecurityPermissionsTableData()
{
var permissionList = securityPermissionsTable
.Get(System.Security.Principal.WindowsIdentity.GetCurrent()
.Name.Split('\\').Last());
return Json(permissionList , JsonRequestBehaviour.AllowGet);
}

How to serialise Web API 2 HttpRequestMessage into my custom object

I have the following method in my WebAPI 2 project.
public class TestController : ApiController
{
[HttpPost]
public void Test(HttpRequestMessage request)
{
var content = request.Content;
string jsonContent = content.ReadAsStringAsync().Result;
}
}
My custom object looks like this;
public class Test
{
public int Id { get; set; }
public string Name { get; set; }
}
If I post some sample data like
<Test>
<Id>12345</Id>
<Name>My Name</Name>
</Test>
The resulting value in jsonContent is correct. My question is how best should I serialise the HttpRequestMessage (content) into my object Test so that I can perform additional validation / tasks etc.
Should I pass HttpRequestMessage into the method or is it possible to pass something like
public void Test(Test oTest)
It sounds like you're asking how to deserialize jsonContent into a new instance of your Test class, as the first comment mentions above. I would suggest looking into Json.NET. Then you could do something like:
public class TestController : ApiController
{
[HttpPost]
public void Test(HttpRequestMessage request)
{
var content = request.Content;
string jsonContent = content.ReadAsStringAsync().Result;
Test test = new Test();
test = JsonConvert.DeserializeObject<Test>(jsonContent);
//Do validation stuff...
}
}
You can use a parameter in your action method like this.
[HttpPost]
public void Test(Test oTest)
ASP.NET Web API will deserialize the request message body (JSON or XML) into Test. Based on the content type header in the request, web API can handle both JSON and XML content out-of-box. In the case of XML, Web API uses DCS, by default. The XML you have shown in your post will not get deserialized as-is. Try returning a Test object and see how it gets serialized by web API and use the same XML in your POST request for binding to work correctly.
BTW, if you use the Test parameter in your action method, Web API will consume the request body stream. So, you will not be able to read it inside the action method like what you are doing.

Categories