I'm creating a webservice where one can post a new order with multiple lines.
Models
public class Order {
public int OrderID { get; set; }
public string Description { get; set; }
public string Account { get; set; }
public ICollection<OrderLine> OrderLine { get; set; }
}
public class OrderLine {
public int OrderLineID { get; set; }
public int OrderID { get; set; }
public string Product { get; set; }
public double Price { get; set; }
}
Controller
public class OrderController : ApiController
{
[HttpPost]
public string Create(Order order)
{
OrderRepository or = new OrderRepository();
return "Foo";
}
}
With Postman I create a post request in Json like this:
{"Description" : "Abc", "Account" : "MyAccount",
"OrderLine[0]" : {
"ItemCode": "Item1",
"Price" : "10"
}
}
When I run the debugger in Visual Studio, The Order model is populated from the request, but OrderLine is NULL. When I change
public ICollection<OrderLine> OrderLine {get; set;}
to
public OrderLine OrderLine {get; set;}
And my Json string in Postman to
{"Description" : "Abc", "YourReference" : "yourABC", "Account" : "AB1010",
"OrderLine" : {
"ItemCode": "Item1",
"Price" : "10"
}
}
My model gets populated when I post the data. I want to post a collection of OrderLines. What am I doing wrong?
You're POSTing an array of OrderLine so your request needs to contain an array:
"OrderLine" : [{}, {}]
and it should look like this:
{"Description" : "Abc", "YourReference" : "yourABC", "Account" : "AB1010",
"OrderLine" : [{
"ItemCode": "Item1",
"Price" : "10"
},
{
"ItemCode": "Item2",
"Price" : "20"
}]
}
Related
The data in JSON format is sent to api endpoint.
Data sample:
{
"templateId": "dc15e4d1-ccbd-4581-a819-5b7f90b32cc5",
"name": "abc",
"steps": [
{
"id": "34b4f406-120e-4d80-8018-6c780c80a6c4",
"visible": false,
}
]
}
Api gets data in this format:
public class TemplateRequest {
public Guid TemplateId { get; set; }
public string Name { get; set; }
public StepRequest[] Steps { get; set; }
}
StepRequest class:
public class StepRequest {
[ModelBinder(Name = "id")]
public Guid StepId { get; set; }
public bool? Visible { get; set; }
}
The JSON has id key instead of stepId, but I can't get it in controller.
When I check, the StepId is always an empty Guid.
What is wrong here, why the StepId property is not having the value from id key?
Yes, like #daremachine said, it was NewtonSoft and JsonProperty(PropertyName = "id") helped.
I am currently learning how to work with EF Core with a simple one to many setup, where a user can have many items. In terms of retrieving the data from the tables, this is fine with some DTO models; however, when I try and add a user with multiple items via Postman, I noticed that for each item it had duplicated the user that many times (i.e. a user with 3 items will create 3 items and 3 users):
Postman (POST)
{
"username": "xxx",
"dob": "xxx",
"location": "xxx",
"items":[{
"item": "xxx",
"category": "xxx",
"type": "xxx"
},
{
"item": "xxx",
"category": "xxx",
"type": "xxx"
},
{
"item": "xxx",
"category": "xxx",
"type": "xxx"
}]
}
Context:
namespace TestWebApplication.Database
{
public class MyContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Items> Items { get; set; }
public MyContext(DbContextOptions<MyContext> options)
: base(options)
{
// erm, nothing here
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.HasMany(i => i.Items)
.WithOne(u => u.User);
}
public override int SaveChanges()
{
var entities = from e in ChangeTracker.Entries()
where e.State == EntityState.Added
|| e.State == EntityState.Modified
select e.Entity;
foreach (var entity in entities)
{
var validationContext = new ValidationContext(entity);
Validator.ValidateObject(entity, validationContext);
}
return base.SaveChanges();
}
}
}
Controller:
[HttpPost]
[Route("insertuseranditems")]
public ActionResult InsertUserAndItems(User user)
{
if (ModelState.IsValid)
{
using (MyContext myContext = _myContext as MyContext)
{
myContext?.Users?.Add(user);
int changes = myContext.SaveChanges();
if (changes > 0)
{
return Created("User saved", user);
}
}
}
return Accepted();
}
Items:
namespace TestWebApplication.Database
{
public class Items
{
[Key]
public int ItemId { get; set; }
public string Item { get; set; }
public string Category { get; set; }
public string Type { get; set; }
public virtual User User { get; set; }
}
}
Users:
namespace TestWebApplication.Database
{
public class User
{
[Key]
public int UserId { get; set; }
public string UserName { get; set; }
public string Dob { get; set; }
public string Location { get; set; }
public ICollection<Items> Items { get; set; }
}
}
I revisited my code and changed my Items.cs model to:
namespace TestWebApplication.Database
{
public class Items
{
[Key]
public int ItemId { get; set; }
public string Item { get; set; }
public string Category { get; set; }
public string Type { get; set; }
[ForeignKey("User")] // added this
public int? UserId { get; set; } // added this
public virtual User User { get; set; }
}
}
Now, when I send the above json via Postman, I get multiple items with the same user as a Foreign Key.
The site below seemed to help:
The ForeignKey Attribute
There is a model:
public class Model
{
[Required(AllowEmptyStrings = false)]
public string Code { get; set; }
[Required(AllowEmptyStrings = false)]
public string Name { get; set; }
[MaxLength(6), MinLength(6)]
public string Color { get; set; }
[MaxLength(3)]
public string Text { get; set; }
[Required]
public int? User { get; set; }
}
If I pass null data in the User, Color, and Text fields, then the answer is:
{
"code": "VALIDATION",
"fields": [
{
"field": "user",
"error": "REQUIRED"
}
]
}
Why I do not get a complete list of required fields?
I have been tasked with building an API, that as a request, will take a product number which will have a quantity and size , zip code, shipping method.
The customer has a cart and in that cart is the product number, quantity and size
so basically he would send a json request that looks like the below
{
"ShoppingCart": {
"Products": [
{
"Sku": "123",
"Size": "S",
"Quantity": "1"
},
{
"Sku": "456",
"Size": "M",
"Quantity": "2"
},
{
"Sku": "789",
"Size": "L",
"Quantity": "3"
}
],
"ShipToZip": "54452",
"ShipMethod": "Ground"
}
}
is it possible to receive an HTTP json request on my .net core rest webapi that im making.
If so, what would the route look like to send json like that? it'sgoing to be pretty long if they have to put the entire json in the url right?
EDIT:
After doing more research, I find that I can receive a POST request with JSON in the body, from there i should be able to read that json, do some stuff with it, and then return json back right? Am i correct?
After doing more research, I find that I can receive a POST request with JSON in the body, from there i should be able to read that json, do some stuff with it, and then return json back right? Am i correct?
Yes. You are correct. For instance, the following controller action would accept a POST body with the JSON from your question and respond with that same JSON.
public class Product
{
public string Sku { get; set; }
public string Size { get; set; }
public int Quantity { get; set; }
}
public class Cart
{
public List<Product> Product { get; set; }
public string ShipToZip { get; set; }
public string ShipMethod { get; set; }
}
public class CartBody
{
public Cart Cart { get; set; }
}
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// POST api/values
[HttpPost]
public ActionResult<CartBody> Post(CartBody cartBody)
{
return cartBody;
}
}
I guess I did not look hard enough :(
Anyway the more questions I feel like the more exposure some newbie problems will have.
How to receive json in ASP.NET web api?
I got my solution from there,
All I had to do was create a "Model" class like below that matches the exact JSON format being sent, no deserielization needed
public class RequestModel
{
public ShoppingCart RequestShoppingCart { get; set; }
}
public class ShoppingCart
{
public Products[] Products { get; set; }
public int ShipToZip { get; set; }
public string ShipMethod { get; set; }
}
public class Products
{
public string Sku { get; set; }
public string Size { get; set; }
public int Quantity { get; set; }
}
Then from there in my API Controller i can do the following to see it working
[Produces("application/json")]
[Route("api/ShippingCalculator")]
public class ShippingCalculatorController : Controller
{
// POST: api/ShippingCalculator
[HttpPost]
public string Post([FromBody]RequestModel jsonRequest)
{
// Debug.WriteLine(jsonRequest.RequestShoppingCart.Products);
return jsonRequest.RequestShoppingCart.ShipMethod;
}
}
I am receiving a FormatException when trying to load a an Album document from the default RavenDB database:
using (var session = _documentStore.OpenSession())
{
var album = session.Load<Album>(500);
//....
}
The Album JSON document in the database looks like this:
{
"AlbumArtUrl": "/Content/Images/placeholder.gif",
"Genre": {
"Id": "genres/10",
"Name": "Classical"
},
"Price": 8.99,
"Title": "The Best of Beethoven",
"CountSold": 0,
"Artist": {
"Id": "artists/203",
"Name": "Nicolaus Esterhazy Sinfonia"
}
}
And my in-memory entity Album class looks like this:
public class Album
{
public long Id { get; set; }
public string AlbumArtUrl { get; set; }
public DenomralizedGenre Genre { get; set; }
public decimal Price { get; set; }
public string Title { get; set; }
public int CountSold { get; set; }
public DenomralizedArtist Artist { get; set; }
}
public class DenomralizedGenre
{
public int Id { get; set; }
public string Name { get; set; }
}
public class DenomralizedArtist
{
public int Id { get; set; }
public string Name { get; set; }
}
What am I doing wrong here?
Make all your Id strings. You have them as int and long. In RavenDB Id's are strings.
The Id as a string would be Album/24 in RavenDB. The Class name or type plus the HiLo value (created by the client tools) make up the Id.