Unable to post serilizable object from $http to web api - c#

web api has [Serilizable] model objects as that needs for serilization intense.
Now, when I post that model object from $.http call using below code then, it post without error but, no data populate and all values are null posted on web api.
If I remove [Serilizable] attribute then works fine and able to get all posted value.
return $http({
method: "POST",
url: config.APIURL + 'Parts',
data: JSON.stringify(part), // Strinify your object
headers: { 'Content-Type': 'application/json' }
});
web api POST method taking parameter as below object:
[Serializable]
public class Part
{
public double? PartLength { get; set; }
}
Please help me here.

Found the solution finally. Need to mark the object with [JsonObject],[JsonProperty] attributes as below.
[Serializable]
[JsonObject]
public class SNPart
{
[JsonProperty]
public double? PartLength { get; set; }
[JsonProperty]
thanks
dhaval

Related

C# MVC AngularJS: Controller Methods invoked, but not receiving values from the $http.post() method

I have an Angular app that invokes a c#mvc method:
AngularJS:
var data = JSON.stringify({ 'panelists': $scope.arr, 'webId': $scope.webinarId });
//Call the services
$http.post('/Home/CreatePanelists', JSON.stringify(data))
.then(function (response) {
if (response.data)
$scope.msg = 'Post Data Submitted Successfully!';
}, function (response) {
$scope.msg = 'Service not Exists';
});
Contents of data:
{"panelists":[{"name":"ali","email":"ali#email.com"},{"name":"tom","email":"tom#email.com"},{"name":"arthur","email":"arthur#email.com"}],"webId":94395753244}
Added the following Files:
/Models/Home/Panelist.cs
public class Panelist
{
public string name { get; set; }
public string email { get; set; }
}
/Models/Home/Parameters.cs
public class Parameters
{
public IList<Panelist> panelists { get; set; }
public string webId { get; set; }
}
Updated the Controller:
/Controllers/HomeController.cs:
public ActionResult CreatePanelists(Parameters data)
{
System.Diagnostics.Debug.WriteLine(data.webId);
System.Diagnostics.Debug.WriteLine(data.panelists);
return new EmptyResult();
}
By the time when the debugger enters the CreatePanelists method, I added a watch on data, and both, panelists, and webId are null.
I don't understand where the problem resides. When I debug the AngularJS code in Chrome, and get to the step in which the post request is made, I see that the variable data, does have the array of objects with values (as shown above).
Why is the MVC Controller method CreatePanelist is not seeing these values?
If somebody have an idea and would not mind offering it, that would be nice.
Thank you in advance for your help.
Your problem comes from calling JSON.stringify twice. You are already stringifying it when setting the variable data, don't do it a second time in your post.

Angular send complex object to C# Controller

I've got a service that I use to send requests to an MVC controller in C#.
This has been working fine until now that I have a complex object I'm trying to send. The param postDto in C# is always null. I've tried a few different solutions but haven't been able to solve this issue. If I remove the list from the object, the object comes across successfully. Any help would be appreciated.
service.ts
...
post$(postDto: MyTSPostDto): Observable<MyTSDto> {
return this.http.post<MyTSDto>(
location.origin + '/api/mycontroller',
postDto,
{ headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }
).pipe(
map((response: MyTSDto) => response)
);
}
myTSPostDto.ts
export class MyTSPostDto {
firstPostDto: FirstPostDto;
secondPostDto: SecondPostDto;
thirdPostDtos: ThirdPostDto[] = [];
}
postDto.cs
public class PostDto
{
public FirstPostDto FirstPostDto { get; set; }
public SecondPostDto SecondPostDto { get; set; }
public List<ThirdPostDto> ThirdPostDtos { get; set; }
}
MyController.cs
...
[HttpPost]
[ProducesResponseType(typeof(MyDto), 200)]
public async Task<IActionResult> Migrate([FromBody] PostDto postDto)
{
...
So it turns out I had some model validation happening in C# that was causing the postDto parameter to come across as null. As soon as I fixed up my model to provide valid inner models, then everything started working.

Post multiple objects to web API [duplicate]

This question already has an answer here:
Simple post to Web Api
(1 answer)
Closed 7 years ago.
I am trying to pass data to my web API using JSON objects. Sending a single object does seems to work fine but as soon as I put a second parameter, the second object does not even seems to initialize on the server side?
Please view the code below to see how I am handling the data parameter
[HttpPost("")]
public JsonResult Post([FromBody]Log_Header headerData,
[FromBody]Log_Detail detailData)
{
return Json("Test");
}
Each of the classes above have simple string data, eg of class below:
public class Log_Header
{
public int Id { get; set; }
public string Name{ get; set; }
}
Example of data being sent:
var header = {
Id: 0,
Name: "Test 3",
}
var detail = {
Id: 0,
Desc: "Test 1",
}
$http({
method: 'POST',
url: "api/addLog",
data : {
header: header,
detail: detail
}
})
This is all just demo data.
I have tried sending the data up in few different ways e.g below:
var data = {
Id: 0,
Name: "Test 3",
LogID: 0,
Desc: "Test",
}
But nothing seems to get this working, I'm guessing I am setting up the web API incorrectly?
Overall, the problem is [FromBody]Release_Log_Detail detailData does not receive any data at all and when viewing the object from a breakpoint it appears as null.
if anyone has any ideas please leave a comment or answer below. If you need anymore information from me please ask.
Whatever we post from angular $http, it consider a single object, so we need to read it in a single object on server
we can do like this
[HttpPost("")]
public JsonResult Post([FromBody]PostData data)
{
return Json("Test");
}
class PostData
{
public Log_Header LogHeader { get; set; }
public Log_Detail LogDetail { get; set; }
}
angular post
$http({
method: 'POST',
url: "api/addLog",
data : {
LogHeader : header,
LogDetail : detail
}
})
In the javascript
$http({
method: 'POST',
url: "api/addLog",
data : JSON.stringify({
header: header,
detail: detail
})
})
create a model
public class dataViewModel
{
public string[] header{ get; set; }
public string[] detail{ get; set; }
}
You have create a controller of name api and action name addLog
[HttpPost]
public JsonResult addLog(dataViewModel data)
{
return Json("Test");
}
hope this helps

ASP .NET MVC 4 binding json sent through ajax to custom class in controller not working correctly

I have following controller:
[HttpPost]
public JsonResult SaveCompensationComponent(int agencyId, CompensationComponentAllData compensationComponent)
{
int? id = _dmsCompensation.SaveCompensationComponent(agencyId, compensationComponent);
return Json(id, JsonRequestBehavior.AllowGet);
}
Definition of the CompensationComponentAllData class:
public class CompensationComponentAllData
{
some properties
...
public CompensationObject CompensationElement { get; set; }
public CompensationObject CompensationBasis { get; set; }
...
some properties
...
}
CompensationObject class:
public class CompensationObject
{
some properties
...
public ActivityData ByActivity { get; set; }
...
some properties
...
}
ActivityData class:
public class ActivityData
{
some properties
...
public List<int> GoalCategories { get; set; }
public List<int> Policies { get; set; }
...
some properties
...
public ActivityData() { }
public ActivityData(CompensationObjectByActivity record) {
...
}
}
In javascript I create appropriate objects and send that through ajax (contentType: 'application/json' and JSON.stringify used before sending data). Everything is correctly sent to server because I executed following code in the controller:
HttpContext.Request.InputStream.Seek(0, SeekOrigin.Begin);
var jsonStringData = new StreamReader(HttpContext.Request.InputStream).ReadToEnd();
And jsonStringData had correct value:
"{\"agencyId\":\"332\",\"compensationComponent\":{\"Id\":431,\"CompensationComponentInfoId\":509,\"AgencyJobPositionId\":\"306\",\"Name\":\"ggggggg44\",\"Description\":\"fdssssssss\",\"CompensationComponentImpactLevelId\":\"1\",\"CompensationProductionTypeId\":\"1\",\"CompensationFrequency\":{\"Id\":\"1\"},\"CompensationDateTypeId\":\"3\",\"EffectiveDate\":\"06/10/2015\",\"BasisDifferentThanElement\":false,\"CompensationElement\":{\"ObjectTypeId\":\"3\",\"ByActivity\":{\"CompensationAttributeId\":\"21\",\"UnitsId\":\"3\",\"PoliciesLevel\":\"Individual Company/Policy\",\"Policies\":[\"572\",\"139\",\"138\"],\"VerificationLevelId\":\"1\"}},\"CompensationBasis\":{\"ObjectTypeId\":\"3\",\"ByActivity\":{\"CompensationAttributeId\":\"21\",\"UnitsId\":\"3\",\"PoliciesLevel\":\"Individual Company/Policy\",\"Policies\":[\"572\",\"139\",\"138\"],\"VerificationLevelId\":\"1\"}},\"CompensationStructureId\":\"2\",\"CompensationRateId\":\"1\",\"FixedValue\":\"10.00\",\"UseChargeback\":false}}"
Now problem is that after binding compensationComponent.CompensationElement.ByActivity.Policies has a null value even though it should be a list with 3 elements.
What makes me even more confused is that in the same time compensationComponent.CompensationBasis.ByActivity.Policies is bound correctly. Also compensationComponent.CompensationElement.ByActivity.GoalCategories is bound correctly too.
EDIT:
This is my ajax call:
$.ajax({
type: type,
url: url,
data: JSON.stringify(data),
success: callback,
error: function (xhr, ajaxOptions, thrownError) {
...
},
contentType: 'application/json',
cache: cache
});
If I remove JSON.stringify and try something as suggested in this post I get error in binding so 500 is just returned.
Please help.
I think that's a little bit strange that you want to receive part of the JSON as method parameters. I think you need to introduce a class for root object:
public class CompensationModel
{
public int AgencyId { get; set; }
public CompensationComponentAllData CompensationComponent { get; set; }
}
And your controller method will take this class as a parameter:
[HttpPost]
public JsonResult SaveCompensationComponent(CompensationModel model)
I suggest you to use services like json2csharp, let's computer does the boring work.
And few comments about JSON that you send. JSON.stringify doesn't change types:
JSON.stringify({a: [1, 2, 3]}) // -> "{"a":[1,2,3]}"
JSON.stringify({a: ["1", "2", "3"]}) // -> "{"a":["1","2","3"]}"
So if you get strings in your JSON that menas that javascript values are of type string. In C# models you expect to have int, so you might consider to convert data in javascript, though MVC is smart enough to convert these values.

Get data from HttpContext Angular and Web API

In the angular controller I have this code to transfer $scope.myModel to a Web API controller:
$scope.upload[index] = $upload.upload({
url: settings.constants.uploadURL,
headers: { 'myHeaderKey': 'myHeaderVal' },
data: { model: $scope.myModel },
file: $file,
fileFormDataName: 'myFile'
}).then(function (response) { ...
The Web API controller post method looks like this
public HttpResponseMessage Post()
{
return UploadFile(HttpContext.Current);
}
How do I get the data: model from out from the HttpContext??
WebAPI is not designed to be used in that fashion. Specifically, it is usually bad practice to refer to HttpContext.Current from within a WebAPI controller method. If you did want to check the request or response, you should refer to them by the properties of the ApiController base class, see the msdn docs.
Usually, people prefer model binding for situations like this. Suppose you had in js:
{
foo: "bar"
}
You should declare a class in C# that maps to it:
public class MyRequestModel
{
public string Foo { get; set; }
}
And by declaring your API method:
public HttpResponseMessage Post(MyRequestModel mdl)
{
// do stuff, mdl.Foo will have "bar" in it magically
}
This results in more object-oriented ways of transferring data from javascript to C#. It's more typesafe because you can be guaranteed that the Foo property in C# will have a string, or an int, or whatever you declare it to be as opposed to parsing the request yourself.

Categories