Angular4 http.post .NET Core MVC bind failure - c#

Tried a lot of solutions to pass an object from Angular4 service to c# controller. Although I do have the object received in service, does not bind to c# controller and so, I receive null.
Angular service:
getShedule(payload: any) {
this._http.post("Shedule/GetSchedule", payload)
.map(res => res.json()).subscribe((x) => {
console.log("callback succes");
});
}
C# controller:
[HttpPost]
public void GetSchedule(object priceScheduleObject)
{
//logic here
}
Any help is welcome.

Try to change your C# controller to
[HttpPost]
public void GetSchedule([FromBody] JObject priceScheduleObject)
{ /
The [FromBody] annotations let the ASP.NET Core Binding logic look into the body of the message (and not posted form fields).
If your do not want to interact with the JObject representing the JSON data you can bind the data to a model like
public class PriceSchedule {
public string Name {get; set;} // just an example, propert names depend on your json
...
}
[HttpPost]
public void GetSchedule([FromBody] PriceSchedule priceScheduleObject)
{ /

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 pass Byte Array as a class property to OData function in ASP.NET Web API?

I am using OData V4 with ASP.NET Web API. After doing a lot of research and experiments I am still not able to pass the Byte array (byte[]) as a class model property. I am not sure that how the .Net Framework is receiving it as a string. But when I configure the controller action to receive only the Byte array (byte[]) parameter then it receives the correct data. It does not receive it as a class property.
Here is my class model.
public class TempFileModel
{
public string Name { get; set; }
public byte[] Content { get; set; }
}
Here is the OData model configuration:
public class TransientFileConfiguration : IModelConfiguration
{
public void Apply(ODataModelBuilder builder, ApiVersion apiVersion, string routePrefix)
{
builder.EntitySet<TransientFileModel>("TransientFiles");
builder.EntityType<TransientFileModel>().HasKey(e => e.Key);
builder.Action("UploadFile")
.Returns<List<string>>()
.CollectionParameter<TempFileModel>("file");
}
}
My Controller action for this:
[HttpPost]
[ODataRoute("UploadFile")]
public async Task<IHttpActionResult> UploadFile(ODataActionParameters parameters)
{
var paramValue = parameters["file"];
return Ok(new List<string>());
}
The error I get every time:
Error Message: "Invalid cast from 'System.String' to 'System.Byte[]'."
Here are few links that I have searched for unbound action using OData API and working with this issue:
https://learn.microsoft.com/en-us/aspnet/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/odata-actions-and-functions
https://learn.microsoft.com/en-us/odata/webapi/action-parameter-support
How to pass Array to OData function in ASP.NET Web API implementation?
How to make an unbound POST action in webapi 2.2 odata
A question on StackOverflow with similar context maybe (just to understand the issue):
Pass two byte array to asp.net web api post method

asp.net - how to get value from post method

In asp.net app i receive a form values from angular app.
[HttpPost]
public IActionResult addChange([FromBody] Change change)
{
return Json(change.Status);
}
How to get object or some value of object to use it in another class?
You should be able to access property like that: change.PropertyName.
But you might send data from angular as FormData, then you should change [FromBody] to [FromForm].
It's most likely that you are doing something wrong at angular site. You should check this endpoint via postman.
Edit:
To use this object in another method you should pass it through.
[HttpPost]
public IActionResult addChange([FromBody] Change change)
{
AnotherMethod(change);
return Json(change.Status);
}
public void AnotherMethod(Change change)
{
var foo = change.Status;
}

Migration from ASP.NET MVC to ASP.NET Core MVC - action model binding resulting null

While migrating from ASP.NET MVC to ASP.NET Core MVC, I faced binding behavior troubles which I couldn't overcome.
I have this controller (for Razor, not API):
public class SomeController : Controller
{
[HttpPost]
public IActionResult SomeAction([FromBody] SomeModel model)
{
return Ok(model?.SomeValue);
}
}
public class SomeModel
{
public int SomeValue { get; set; }
}
If I make a request to /some/someAction with a body of { "SomeValue": "6970" }, I get a model equals null.
If I remove quotes { "SomeValue": 6970 } I receive what I need, the model isn't null.
The project is big and I cant change all the js code to ints, also it could be a problem to change all models which expect int.
How I can let it work easily?
Try to change your model from int to string and check if it works

How to catch and save json data posted to restful asp.net web api

I have this code:
[Route]
public HttpResponseMessage PostData[FromBody] DataModel data)
{
... implementation...
}
This automatically binds / converts the json data to my data model. However, I would like to save / catch the raw json file that was posted and save it for logging purposes.
Any suggestions on how I can achieve this?
You can just do the below and then use JSON converter to convert the string to JSON later.
[HttpPost]
public HttpResponseMessage PostData([FromBody] string text)
{
// log text.
DataModel data = JsonConvert.DeSerialize<DataModel>(text);
}
Or you can also do,
[HttpPost]
public HttpResponseMessage PostData()
{
string text = Request.Content.ReadAsStringAsync().Result;
//log text
DataModel data = JsonConvert.DeSerialize<DataModel>(text);
}
Since you mention it is for logging, you might want to consider doing this in a Web API filter or a delegating handler - to make the logic more centralized instead of having the logic in each action method.
public class LogApiRequest : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
var text = actionContext.Request.Content.ReadAsStringAsync().Result;
MyLogger.Log(LogLevel.INFO, text);
base.OnActionExecuting(actionContext);
}
}
and then register your filter - typically in WebApiConfig.cs or decorate your action method or controller class with the filter.
config.Filters.Add(new LogApiRequest());

Categories