This question already has answers here:
ASP.NET Core v2 (2015) MVC : How to get raw JSON bound to a string without a type?
(10 answers)
Closed 1 year ago.
I have API, that recieve JSON from body, which is send from some WebUI.
[Route("api/[controller]")]
[ApiController]
public class MyController : ControllerBase
{
public IActionResult Create([FromBody] MyModel request)
{
MyModel newRecord = new();
try
{
newRecord.Id = null;
newRecord.Date = request.Date;
newRecord.Name = request.Name;
}
catch (Exception e)
{
return StatusCode(400, $"Error: {e.Message}");
}
return Ok(newRecord);
}
}
But request is not constant. It changes with develepment.
Right know i have to match MyModel with request to work on JSON in Body. But it generates too much work, because of many changes.
Is there a solution, so I can recieve uknown JSON object and parse it inside of controler?
For example, is there a trick, so I can write
public IActionResult Create([FromBody] var request)
or something similiar?
System.Text.Json has an class called JsonElement which can be used to bind any JSON to it.
[HttpPost]
public IActionResult Create([FromBody] JsonElement jsonElement)
{
// Get a property
var aJsonProperty = jsonElement.GetProperty("aJsonPropertyName").GetString();
// Deserialize it to a specific type
var specificType = jsonElement.Deserialize<SpecificType>();
return NoContent();
}
Related
Detail: I am trying to set up a simple get/post method inside asp.net controller and using postman to set if its set up correctly. I have looked for similar question on stackoverflow and they did not fixed my issue
Error: My Get method works fine but my post method giving an following error. Please see below postman:
debug: if I add a break line inside post method. it is never reaching to that break line
Code in asp.net
[ApiController]
[Route("[controller]")]
public class CoursesTakenController : Controller
{
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] {"value", "value" }
}
[HttpPost]
public Task<ActionResult<string>> Post([FromBody] string values)
{
return Ok(values);
}
}
I also tried this: but doesnt work
[HttpPost]
public async Task<IActionResult> Post([FromBody] string values)
{
return Ok();
}
You are posting a json object while the method expects a string. System.Text.Json (default json serializer used by ASP.NET Core) is pretty restrictive in JsonTokenType handling, so either post a string i.e. just "RandomText" (or encoded into string json object - {\"values\":\"asdasdasd\"}) or change action to accept an object:
public class Tmp
{
public required string Values { get; set; }
}
[HttpPost]
public async Task<ActionResult<string>> Post([FromBody] Tmp values)
{
...
}
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
I try to have more than one parameter in a POST from angular 9 to a .NET API controller
I get the error The JSON value could not be converted to Newtonsoft.Json.Linq.JToken
when sending my request, passing these arguments to my http post from angular 9
from:
return this.http.post<any>(environment.apiUrl + 'api/Partners/',partner : partner);
to
return this.http.post<any>(environment.apiUrl + 'api/Partners/',{partner : partner,manager : manager});
using the following code for the .NET controller
[HttpPost]
public async Task<ActionResult<int>> PostPartner([FromBody] JObject body)
{
Partner partner = body["partner"].ToObject<Partner>();
User manager = body["manager"].ToObject<User>();
...
JObject beeing from using Newtonsoft.Json.Linq
I know I can use System.text.json but I just don't find any example that fits my post function signature
any help appreciated
thanks
Instead of using Newtonsoft.Json.Linq.JObject, you should be able to use a model class which should contain both the Partner and the User properties like:
public class PostPartnerModel
{
public Partner Partner { get; set; }
public User Manager { get; set; }
}
and have your action like:
[HttpPost]
public async Task<ActionResult<int>> PostPartner([FromBody] PostPartnerModel model)
{
Partner partner = model.Partner;
User manager = model.Manager;
...
Here is my code:
[HttpGet]
[Produces("application/json")]
[Route("whatever")]
public ActionResult<JsonResult> Get()
{
string jsonText = "{\"city\":\"paris\"}";
return new JsonResult(JObject.Parse(jsonText));
}
This is the output I want:
{"city":"paris"}
This is the output I get:
{"contentType":null,"serializerSettings":null,"statusCode":null,"value":{"city":"paris"}}
How can I change my code to prevent .NET framework from wrapping my original JSON?
Then use a simpler and strongly typed result object instead of trying to manually create the JSON string.
[HttpGet]
[Produces("application/json")]
[Route("whatever")]
public IActionResult Get() {
var model = new { city = "paris" };
return Ok(model);
}
the framework will serialize the model to the desired output
There is no problem with ASP.NET MVC's JsonResult, but you're using JSON.NET. In JSON.NET, when you convert an json string vi JObject.Parse(), it returns a JObject object that contains some members. If you want to get the converted json, you should use ToString(), as the following:
[HttpGet]
[Produces("application/json")]
[Route("whatever")]
public ActionResult<JsonResult> Get()
{
string jsonText = "{\"city\":\"paris\"}";
return new JsonResult(JObject.Parse(jsonText).ToString());
}
I am trying to receive a HTTP POST from Mirth Connect in my ASP.NET MVC solution but I donĀ“t know how this data comes to my web application. I create a controller to receive it:
public class IntegrationController : Controller
{
public ActionResult Index()
{
var c = HttpContext.CurrentHandler;
var v = c.ToString();
Console.Write("The value is" + v);
return View();
}
}
What should I receive in Index()? A dictionary? And once I receive it, how to how it in the viewer?
Thank you.
I use the [FromBody] Annotation, then I can treat the incoming like any other parameter.
[Route("api/gateways")]
[Route("api/connectedDevices")]
[Route("api/v0/gateways")]
[Route("api/v0/connectedDevices")]
[HttpPost]
public HttpResponseMessage Create([FromBody] IGatewayNewOrUpdate device,
I do have a case when I read the content directly from the Request;
[HttpPost]
public HttpResponseMessage AddImageToScene(long id, string type)
{
SceneHandler handler = null;
try
{
var content = Request.Content;
I think it may be a little different for different versions, but I hope that will give you a starting point.
Try something like this. This will work, if v is the name of a field that will be posted from a form.
public class DataModel
{
public string v {get; set;}
}
public class IntegrationController : Controller
{
[HttpPost]
public ActionResult Index(DataModel model)
{
Console.Write("The value is" + model.v);
return View();
}
}
If you receive Json then a can add [FromBody]
public class IntegrationController : Controller
{
[HttpPost]
public ActionResult Index([FromBody] DataModel model)
{
Console.Write("The value is" + model.v);
return View();
}
}