JsonIgnore attribute not working on API Model web api - c#

In my .net 6.0 web api (c#) i am using JsonIgnore attribute to hide a property from resulted json outpul but it seems to take no effect,
Model
public class xyz
{
//[IgnoreDataMember]
[JsonIgnore]
public string AppNo { get; set; }
public int dpd { get; set; }
public string email { get; set; }
public string address { get; set; }
public int currency { get; set; }
}
Controller Action Method
public async Task<IActionResult> GetInfoAsync([FromQuery] string identifier)
{
var info= await GetInfo(identifier);
return Ok(info);
}
In resulted output , I still see AppNo
{
"appNo": "12xcv56",
"dpd": 0,
"email": test#xt.com,
"address": "b 101 j CHSL,thane",
"currency": 1
}
I have also tried [IgnoreDataMember] but it does not take any effect. Is there any other setting which i need to take for this ?
I am using newtonsoft.json for [JsonIgnore] attribute.
Any help is appreciated.

Related

HttpClient not returning API data that matches my model

Hi wrote a little web app that connects to an API.
It is connecting to the API and returning data as you can see here:
astroTechItem= await Http.GetFromJsonAsync<AstroTechItem[]>("api/AstroTechItem/34");
And it's returning the following JSON:
{
"objectId": 34,
"scopeId": 3,
"title": "solar telescope",
"completed": false
}
In my app, I have this model:
private class AstroTechItem
{
public long Id { get; set; }
public string Name { get; set; }
public bool IsComplete { get; set; }
}
And I am deserializing like this:
JsonSerializer serializer = new JsonSerializer();
try
{
return serializer.Deserialize<AstroTechItem>(jsonReader);
}
catch(JsonReaderException)
{
Console.WriteLine("Invalid JSON.");
}
}
else
{
Console.WriteLine("HTTP Response was invalid and cannot be deserialised.");
}
But my model does not match what the API is returning.
My console keeps showing: Invalid JSON.
Do I need to contact the maker of the API and have them change it?
Or is there a way to fit that JSON into my model?
I can't figure it out.
thanks!
To deserialize json to a model, the model's properties must match the properties of the json. Or you can annotate the model with the json property names. In your case none of the properties match.
Easiest is to update the model to align it with the external API like so:
private class AstroTechItem
{
public long ObjectId { get; set; }
public long ScopeId { get; set; }
public string Title { get; set; }
public bool Completed { get; set; }
}
Otherwise you can annotate the model:
private class AstroTechItem
{
[JsonProperty("objectId")]
public long Id { get; set; }
[JsonProperty("title")]
public string Name { get; set; }
[JsonProperty("isComplete")]
public bool Completed { get; set; }
}

How to post multiple object data json in web api in one controller

i have json data example this :
{
"datetime": "2019-07-31 15:40:01",
"Kursi": [
{
"kursi_id": 23,
"kursi_value": 100
}
],
"Bunga": [
{
"bunga_id": 3,
"bunga_value": "894,9"
}
]
}
how im supposed to do. i want to post this json into my db sql server in one controller. but i have no idea if the data have two object "Kursi" and "Bunga" ?
If you want to post data to the controller, create a model that represents you json.
public class MyModel
{
public DateTime datetime { get; set; }
public List<Kursi> Kursi { get; set; }
public List<Bunga> Bunga { get; set; }
}
public class Kurski
{
public int kursi_id { get; set; }
public int kursi_value { get; set; }
}
public class Bunga
{
public int bunga_id { get; set; }
public string bunga_value { get; set; }
}
Please, do read the documentation. It is not as hard as it looks, and it pays off the hard work.
By the way, ASP.NET Core is an alternative to Web API.

Returning custom status code is not working in ASP.Net Web API

I am a newcomer in ASP.Net Web API world. Sorry if this is a foolish question.
I have the following api method -
[Route("api/v1/Location/Create")]
[HttpPost]
public IHttpActionResult Create(Location location)
{
if (!ModelState.IsValid)
{
return StatusCode(HttpStatusCode.BadRequest);
}
return Ok();
}
public class Location
{
public int MCC { get; set; }
public int MNC { get; set; }
public int LAC{ get; set; }
public int CellId { get; set; }
}
If I send a string value from client, it still returns StatusCode 200.
What I am missing here?
You haven't put any data annotations on your location class.
Try it adding [Required] data annotation one of property.
Modify your class as follows-
using System.ComponentModel.DataAnnotations;
public class Location
{
[Required()]
public int MCC { get; set; }
[Required()]
public int MNC { get; set; }
[Required()]
public int LAC{ get; set; }
[Required()]
public int CellId { get; set; }
}
ModelState.IsValid is checking the data model validation when each filed is annotated by [Required].

How can we hide a property in WebAPI?

I have a model say under
public class Device
{
public int DeviceId { get; set; }
public string DeviceTokenIds { get; set; }
public byte[] Data { get; set; }
public string FilePwd { get; set; }
}
Now I have a ASP.net Web API where there is a POST method as under
[HttpPost]
[Route("AddDeviceRegistrations")]
public void InsertDeviceRegistrations(Device device)
If I expose the WebAPI, obviously all the fields will be available e.g.
{
"DeviceId": 1,
"DeviceTokenIds": "sample string 2",
"Data": "QEBA",
"FilePwd": "sample string 3"
}
What I want is that, whenever I expose my WebAPI, the DeviceID should not get expose. I mean I am looking for
{
"DeviceTokenIds": "sample string 2",
"Data": "QEBA",
"FilePwd": "sample string 3"
}
Is it possible? If so how?
I can solve the problem by changing the function signature as
public void InsertDeviceRegistrations(string deviceTokenIds, byte[] data, string FilePwd).
But I wanted to know if it can be possible or not ?
If so , how?
Thanks in advance.
I just figured out
[IgnoreDataMember]
public int DeviceId { get; set; }
The namespace is System.Runtime.Serialization
More information IgnoreDataMemberAttribute Class
Learnt something new today.
Thanks All.
There's good practice to use View Models for all GET/POST requests.
In you case you should create class for receiving data in POST:
public class InsertDeviceViewModel
{
public string DeviceTokenIds { get; set; }
public byte[] Data { get; set; }
public string FilePwd { get; set; }
}
and then map data from view model to you business model Device.
If you are using Newtonsoft.Json
you can hide the properties like this:
public class Product
{
[JsonIgnore]
public string internalID { get; set; };
public string sku { get; set; };
public string productName { get; set; };
}
and your serialized response will not include the internalID property.
The use of the Attribute [NonSerialized] on top of the Property stops its from being Serialized in the outputting JSON/XML .
public class Device
{
[NonSerialized]
public int DeviceId { get; set; }
public string DeviceTokenIds { get; set; }
public byte[] Data { get; set; }
public string FilePwd { get; set; }
}
If you want to hide the data member of Resonse class with null parameter. Go to your project WebApiConfig file residing in App_start folder, add the following code:
var jsonConfig = config.Formatters.JsonFormatter;
jsonConfig.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;

MVC 4 Post on Nested JSON is null

I'm currently working on a mobile app that communicates with an MVC4 API.
The problem I just noticed is that it seems to be unable to parse nested objects for some reason.
Example:
I'm POSTing the following data towards the url (http://localhost/DoSomething):
{
"id":610,
"dynamic":[
{
"fieldId":2756,
"fieldValue":""
},
{
"fieldId":2757,
"fieldValue":""
}
],
"person":{
"name":"test",
"age":"123",
"dateOfBirth":"test",
"groups":[
{
"groupId":1182
},
{
"groupId":1311
},
{
"groupId":673
}
]
}
}
Knowing that MVC will try to serialize it against the provided models, I have created the following model for the request:
public class PersonRequest : RequestBase
{
public class Field
{
public int fieldId { get; set; }
public string fieldValue { get; set; }
}
public class Group
{
public int groupId { get; set; }
}
public class Person
{
public string name { get; set; }
public string age { get; set; }
public string dateOfBirth { get; set; }
public IEnumerable<Group> groups { get; set; }
}
public int id { get; set; }
public IEnumerable<Field> dynamic { get; set; }
public Person person { get; set; }
}
In order to handle the input I have created the following route (which works):
routes.MapRoute(
name: "PersonRequest",
url: "DoSomething",
defaults: new { controller = "Person", action = "Generate" }
);
And my actual routing method:
[HttpPost]
public ActionResult Generate(PersonRequest request)
{
return Json(request, JsonRequestBehavior.AllowGet);
}
The response is however:
{"id":610,"person":null,"dynamic":null}
After searching for a possible solution, people said you would have to use IEnumerable for such situations instead of a List. Sadly, this didn't seem to be working for me.
Just some extra info:
I could always use JSON.stringify on the clientside on the dataobject person and dynamic, and eventually deserialize it myself on the backend (as shown in this topic: parse Json text to C# object in asp mvc 4), but there has to be a better workaround for this problem.
Change: Changed groups to dynamic in the resulting json.
Solved: https://stackoverflow.com/a/29349804/2076351
Why are you using IEnumerable<>, the query is fired at the end,
use List<> and check.
public class PersonRequest : RequestBase
{
public class Field
{
public int fieldId { get; set; }
public string fieldValue { get; set; }
}
public class Group
{
public int groupId { get; set; }
}
public class Person
{
public string name { get; set; }
public string age { get; set; }
public string dateOfBirth { get; set; }
public List<Group> groups { get; set; }
}
public int id { get; set; }
public List<Field> dynamic { get; set; }
public Person person { get; set; }
}
Solved.
Seems that my backend was properly setup. The fix was the way the data was sent towards the backend.
If you are sending a nested object towards the backend, to be parsed. You'll have to do two things:
Use JSON.stringify on the entire data send to the data
Use a proper content-type, e.g.:
xhr.open("POST", url);
xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
xhr.setRequestHeader("hash", params.hash);
xhr.send(JSON.stringify(params.data));

Categories

Resources