Access Query params value if passing like [] - c#

The Request URL is like below
?Page=1&Count=10&q[]=Name:[Abc, Xyz]&q[]=City:[XXX, YYY]&q[]=ID:[1,2]
I am using Asp.Net Core API and C#.
Controller code:
public async Task<ActionResult> GetUserListAsync([FromQuery]Data data)
{
----
----
}
Data Object class
public class Filters
{
public List<string> Name { get; set; }
public List<string> City { get; set; }
public List<int> ID { get; set; }
}
public class Data
{
public List<Filters> q { get; set; }
public int Page { get; set; }
public int Count { get; set; }
}
When I tried like this, I get the value for the fields Page and Count. But I not able to get the values for the field q.
How can I take the values for the field q from the request?
Otherwise, If I give like this as mentioned below means, how to take the values?
&query_hash[0][field]=Id&query_hash[0][Values][]=1&query_hash[1][field]=Date&query_hash[1][Values][from]=2020-03-11T18.30.00.000Z&query_hash[1][Values][from]=2020-03-12T18.30.00.000Z

Pass the array in Request url like below
?Page=1&Count=10&q[0].Name=Abc&q[0].Name=xyz&q[0].City=AAA&q[0].ID=1&q[0].ID=2&q[1].Name=rrr
Result:

Related

List of objects and image is not being passed (Registered) with FromForm POST Call

i have a model class of the following..
public class RegisterDTO
{
public string Name{ get; set; }
public string Location { get; set; }
public string PhoneNumber { get; set; }
public IFormFile Image { get; set; }
public List<string> Days { get; set; }
//here is the list of costs
public List<CostDTO> Costs { get; set; }
public IFormFile Image1 { get; set; }
public IFormFile Image2 { get; set; }
}
and here is the CostDTO class
public class CostDTO
{
public string itemName { get; set; }
public bool isPercent { get; set; }
public float value { get; set; }
}
and here is the service for registering the values stated above..
public async Task <string> Register(RegisterDTO model)
{
var entity = await _context.Tablename.FirstOrDefaultAsync();
List<Cost> costs = new();
//here is the loop that maps the DTO to an entity and stores it into the list
foreach (var item in model.costs)
{
var cost = _mapper.Map<Cost>(item);
costs.Add(cost);
}
//then save to the database
}
And here is the controller that calls the service.
[HttpPost("info")]
public async Task<ActionResult> Register([FromForm] RegisterDTO model)
{
var result = await _serviceName.Register(model);
return Ok(result);
}
My question is, at the beginning of the for loop, model.costs is empty and its not allowing me to pass a list of objects onto the service call. how do i go about fixing this.
you can fix it like this costs[0].itemName="item1",costs[1].itemName="item 2",
but it's not good solution, it's better to separate your dto ,get images in a model use [fromform] and another model [frombody]
As Hossein said, you should firstly make sure the request has sent the Costs list to the web api controller method.
The asp.net core model binding will auto map the formdata array with the list. So you should use it like below:
Then the result:

ASP.NET nested list of models is not binding

I'm trying to post a list of models to the server, using ASP.NET's model binding and manipulating a bunch of values with JavaScript. When I send the values to the server, this is what I get:
model.inventory.processed_items[0].id: GA-6570
model.inventory.processed_items[0].event:
model.inventory.processed_items[0].subevent:
model.inventory.processed_items[0].restrict_marking:
model.inventory.processed_items[0].cecp_string:
model.inventory.processed_items[0].discrepancies:
model.inventory.processed_items.Index: 0
model.inventory.processed_items[1].id: GD-1000
model.inventory.processed_items[1].event:
model.inventory.processed_items[1].subevent:
model.inventory.processed_items[1].restrict_marking:
model.inventory.processed_items[1].cecp_string:
model.inventory.processed_items[1].discrepancies:
model.inventory.processed_items.Index: 1
These are my model classes that I'm binding to (I've omitted any fields that don't really matter to the question):
public class PackageViewModel
{
public InventoryViewModel inventory { get; set; }
}
public class InventoryViewModel
{
public List<ProcessedItemViewModel> processed_items { get; set; }
}
public class ProcessedItemViewModel
{
public string id { get; set; }
public int #event { get; set; }
public string subevent { get; set; }
public string cecp_string { get; set; }
public string restrict_marking { get; set; }
public string discrepancies { get; set; }
public string highest_classification { get; set; }
public int occurences_count { get; set; }
public IEnumerable<ProcessedOccurenceViewModel> occurences { get; set; }
}
public class ProcessedOccurenceViewModel
{
public string text { get; set; }
public string security_num { get; set; }
public Nullable<int> media_count { get; set; }
public string classification { get; set; }
}
This is my controller:
[HttpGet]
public ActionResult Create()
{
var inventoryVM = new InventoryViewModel
{
processed_items = new List<ProcessedItemViewModel>()
};
var packageVM = new PackageViewModel {
inventory = inventoryVM
};
return View(packageVM);
}
[HttpPost]
public ActionResult Create(PackageViewModel packageVM)
{
if (ModelState.IsValid)
{
...
}
}
When I check packageVM in debugger, the values are not bound to the view model. However, other values excluding this nested list of models are included in the packageVM model during the POST request. I don't understand why this portion is not binding because I have supplied indices and also passed in an empty list to the view.
The property names for the values you are sending do not match the model you are binding to. PackageViewModel does not contain a property named model (it contains one named inventory), so instead of
model.inventory.processed_items[0].id: GA-6570
it needs to be
inventory.processed_items[0].id: GA-6570
An easy way to think about this is to consider how you would access the value of a property of the model in the POST method
public ActionResult Create(PackageViewModel packageVM)
{
// get the id of the first item in processed_items
string id = packageVM.inventory.processed_items[0].id
Because the parameter in the method is named packageVM, just drop that prefix, (i.e. becomes inventory.processed_items[0].id), and that is what the name of the data needs to be in order to bind.
As a side note, it you are using the strong typed ***For() methods inside a for loop to generate your form controls based on your model, they will generate the correct name attributes, and you can just use $('form').serialize() to correctly generate the data to be sent via your ajax call.

Web api skips all objects but first in List<T> when returning to client

I have a web api that returns a complex object that looks like this:
public class CanDeleteRumsaAttributeResponse
{
public CanDeleteRumsaAttributeResponse()
{
}
public CanDeleteRumsaAttributeResponse(int attributeId)
{
RumsaAttributeId = attributeId;
}
public int RumsaAttributeId { get; set; }
public bool AttributeFound { get; set; }
public List<RumsaRoom> AffectedRumsaRooms { get; set; } = new List<RumsaRoom>();
public List<RumsaAttribute> AffectedLinkedRumsaAttributes { get; set; } = new List<RumsaAttribute>();
[JsonIgnore]
public bool CanDelete
{
get
{
return AffectedRumsaRooms.Count == 0&&AttributeFound&&AffectedLinkedRumsaAttributes.Count==0;
}
}
}
When I debug it I can see that the controller return that object and that the list AffectedLinkedRumsaAttributes has several objects in the list
When the client receives the list all but the first object are null.
I've tried returning the object as Ok(CanDeleteRumsaAttributeResponse) and I've tried serializing it like this:
RoomAttributesUtils utils = new RoomAttributesUtils(db);
string json = JsonConvert.SerializeObject(utils.GetCanDeleteColor(id));
var response = this.Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(json, Encoding.UTF8, "application/json");
return response;
In the second case I can search the json string and find the missing data.
So its being serialized in the second case.
I've checked fiddler to see what is being sent and I can see that something is not right in the json-data.
The missing objects gets values like $ref: "4" and so on, but nothing else.
Here is the json-string I'm afraid I dont know how to format it properly for Stackoverflow, but I think that the information is there as well, but when I look at it using a viewer, its not and it sure doesnt deserialize to the correct objects.
The other list in the object can have any number of objects and they all return fine. Also, other endpoints are returning lists of the same type perfectly fine.
The three objects have unique values on the Code property and they are V30, V31 and V12 (if you want to identify them in the json string).
Any ideas?
Here is the json string
{"RumsaAttributeId":4797,"AttributeFound":true,"AffectedRumsaRooms":[{"$id":"1","RoomName":"STÄD","RoomNumber":"U12102-1150","Building":"U1","PartOfBuilding":"21","Plan":"02","Number":"1150","RoomDescriptions":[],"IsDeleted":false,"PMs":[],"IDNR":"175D_40","Exclude":false,"Department":"VN40 Lokalvård","Comments":"","Area":"23.19","HygeneClass":null,"CeilingHeight":"","UniqueRoomId":"d00e5325-7918-4d01-b273-813a770b46ca-010591d3","SolviegHasOpenedThis":true,"LastSynchedFromRevit":"1900-01-01T00:00:00","LastUpdatedFromRevit":"1900-01-01T00:00:00","Id":25772}],"AffectedLinkedRumsaAttributes":[{"$id":"2","AMACode":"KBC.3211","Malning":"56-03510","AvaliableColors":[{"$id":"3","AvaliableMaterials":[{"$ref":"2"},{"$id":"4","AMACode":"MBE.221","Malning":"-","AvaliableColors":[{"$ref":"3"}],"RoomDescriptions":[],"Code":"V30","ShortDescription":"Kakel, vattenavvisande beklädnad","LongDescription":"-","Comment":"-","PartOfRoom":null,"PartOfRoomId":960,"Id":1438},{"$id":"5","AMACode":"MBE.222","Malning":"-","AvaliableColors":[{"$ref":"3"}],"RoomDescriptions":[],"Code":"V31","ShortDescription":"Kakel, vattentät beklädnad","LongDescription":"-","Comment":"-","PartOfRoom":null,"PartOfRoomId":960,"Id":1439}],"RoomDescriptions":[],"Code":"V31_01","ShortDescription":"Kakel, vattentät beklädnad","LongDescription":"Marazzi SistemC Arch ME83, kulör Bianco(vit)200x200x5 mm. Fog Mapei Ultracolor Plus kulör 111 Silver Grey","Comment":"På 1 fondvägg","PartOfRoom":null,"PartOfRoomId":960,"Id":4797}],"RoomDescriptions":[],"Code":"V12","ShortDescription":"Gipsskivor, hygienklass 2","LongDescription":"Hög standard, hygienklass 2\n","Comment":"-","PartOfRoom":null,"PartOfRoomId":960,"Id":1425},{"$ref":"4"},{"$ref":"5"}]}
I had a similar situation in which I found that due to circular references, the serialization was not completed.
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogForeignKey { get; set; }
[ForeignKey("BlogForeignKey")]
public Blog Blog {get;set;}
}
I just deleted the child to parent relationship and included the foreingkey anotation to the entity set.
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
[ForeignKey("BlogForeignKey")]
public List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogForeignKey { get; set; }
}
Also consider LoopReferenceHandling

How to rename mapping from json being accepted in c# as body parameter?

[HttpPost]
public IHttpActionResult Post([FromBody]Stock stock)
public class Stock
{
public int DealerId { get; set; }
public int StockId { get; set; }
public long Kms { get; set; }
public DateTime MfgYear { get; set; }
}
Sample JSON request:
{
"stock":
{
"DealerId ":234,
"StockId ":123,
"Kms":12324,
"versionId":987,
"MfgYear":2010,
}
}
I need to change c# Stock class variable names i.e. from Kms to Kilometer, MfgYear to ManufacturingYear etc.
When i am posting data from postman to my Stock api, I need to have same parameters in c# as i have it in my json. Is there any way i can change this mapping that would allow me to map json Kms to C# Kilometer?
Simply use the JsonPropertyAttribute:
[JsonProperty(PropertyName = "Kms")]
public int Kilometer { get; set; }

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