This get posted to the server as departments are null
JavaScrtipt code:
var departments = [{ DepartmentName : "Name", DepartmentId : 1}];
Restangular.all('records/StartNewDate').post(departments);
Web Api Controller
public HttpResponseMessage StartNewDate(DepartmentViewModel[] departments)
{
....
....
}
Server Model
public class DepartmentViewModel
{
public int DepartmentId { get; set; }
public string DepartmentName { get; set; }
}
You have to JSON.stringify the object before you send it in the payload:
return Restangular.all('records/StartNewDate').post(JSON.stringify(departments));
Related
I'm building a one to many relation web API with .NET and got error 400.
I have two tables:
public class CarBrand
{
public int CarBrandId { get; set; }
public string Name { get; set; }
[JsonIgnore]
public List<CarModel> CarModels { get; set; } = new List<CarModel>();
}
public class CarModel
{
public int CarModelId { get; set; }
public string ModelName { get; set; }
public int CarBrandId { get; set; }
[JsonIgnore]
public CarBrand CarBrand { get; set; } = new CarBrand();
}
My Controller is:
[HttpPost]
public async Task<ActionResult<CarModel>> PostCarModel(CarModel carModel)
{
_context.CarModels.Add(carModel);
await _context.SaveChangesAsync();
return CreatedAtAction("GetCarModel", new { id = carModel.CarModelId }, carModel);
}
But when I make a POST request and try to add CarModel, I get error 400:
CarBrand:[
"This Field is required!"
]
Thanks!
I have a simple RESTful API and this is the post route handler I'm trying to apply AutoMapper in:
[HttpPost]
[Route("[action]")]
public async Task<IActionResult> CreateHotel([FromBody]Hotel hotelCreateDto)
{
var hotel = _mapper.Map<Hotel>(hotelCreateDto);
var createdHotel = await _hotelService.CreateHotel(hotel);
var hotelReadDto = _mapper.Map<HotelReadDto>(createdHotel);
return CreatedAtAction("GetHotelById", new { id = hotelReadDto.Id }, hotelReadDto);
}
So in the request I get a hotelCreateDto which looks like that:
public class HotelCreateDto
{
[StringLength(50)]
[Required]
public string Name { get; set; }
[StringLength(50)]
[Required]
public string City { get; set; }
}
and I map this to Hotel entity:
public class Hotel
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[StringLength(50)]
[Required]
public string Name { get; set; }
[StringLength(50)]
[Required]
public string City { get; set; }
}
and a new hotel object is created in the next line. However when hotelReadDto is going to be assigned to the new mapped object, a 500 error occurs: "AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping."
Could you catch a mistake here? I don't know where I'm doing wrong.
Edit: there'S also this things after the error above: "Mapping types:
Object -> HotelReadDto
System.Object -> HotelFinder.DTO.DTOs.HotelReadDto"
Edit2: Here is the code in the Configure Services:
services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
And in the Profile class:
public class HotelProfile : Profile
{
public HotelProfile()
{
CreateMap<Hotel, HotelReadDto>();
CreateMap<HotelCreateDto, Hotel>();
}
}
Add this in your services in startup :
it's reusable and cleaner
public void ConfigureServices(IServiceCollection services)
{
services.AddAutoMapper(Assembly.GetExecutingAssembly());
}
add these interface and class in your project
public interface IMapFrom<T>
{
void Mapping(Profile profile) => profile.CreateMap(typeof(T), GetType());
}
using AutoMapper;
using System;
using System.Linq;
using System.Reflection;
public class MappingProfile : Profile
{
public MappingProfile()
{
ApplyMappingsFromAssembly(Assembly.GetExecutingAssembly());
}
private void ApplyMappingsFromAssembly(Assembly assembly)
{
var types = assembly.GetExportedTypes()
.Where(t => t.GetInterfaces()
.Any(i =>i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapFrom<>)))
.ToList();
foreach (var type in types)
{
var instance = Activator.CreateInstance(type);
var methodInfo = type.GetMethod("Mapping")
?? type.GetInterface("IMapFrom`1").GetMethod("Mapping");
methodInfo?.Invoke(instance, new object[] { this });
}
}
}
and your dto be like this (map hotel to HotelDto):
public class HotelCreateDto : IMapFrom<HotelCreateDto>
{
[StringLength(50)]
[Required]
public string Name { get; set; }
[StringLength(50)]
[Required]
public string City { get; set; }
public void Mapping(Profile profile)
{
profile.CreateMap<Hotel,HotelCreateDto>();
}
}
I am new in programming. I read a tutorial about the .net core API, but I noticed every tutorial only shows how to pass an entity class as parameter. If I want to pass a combination of entity class as below, does it mean I need to submit multiple post request to server?
JSON:
{
"postId": "123",
"postText": "test item",
"items": [
{
"itemId": "t3st",
"postId": null
},
{
"itemId": "t3st3",
"postId": null
}
] }
C#:
public class Post
{
[Key]
public string postId { get; set; }
public string postText { get; set; }
}
public class Item
{
[Key]
public string itemid{ get; set; }
public string postId { get; set; }
}
public IActionResult Post([FromBody] Post post)
{
return Ok(data);
}
public class Post
{
[Key]
public string postId { get; set; }
public string postText { get; set; }
public List<Item> items {get; set;}
}
public class Item
{
[Key]
public string itemid{ get; set; }
public string postId { get; set; }
}
You need to change your object like above
and then you need to return type List<Post>
You can create a viewModel to parse you json to an object as well. like this.
public class Post
{
[Key]
public string postId { get; set; }
public string postText { get; set; }
public IEnumerable<Item> items {get; set;}
}
public class Item
{
[Key]
public string itemid{ get; set; }
public string postId { get; set; }
}
public IActionResult Post([FromBody] Post post)
{
var entity = JsonConvert.DeserializeObject<PostViewModel>(post.ToString())
return Ok(data);
}
I have web api controller where I try to do something like this:
public IHttpActionResult Get()
{
var Rooms = db.Rooms.Select(r => new {
Id = r.Id,
Name = r.Name,
ChairNum = r.СhairNum,
Requests = r.Requests.ToList()
}).ToList();
return Ok(new { results = Rooms });
}
In Model I have this:
public partial class Room
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Room()
{
this.Requests = new HashSet<Request>();
}
public int Id { get; set; }
public string Name { get; set; }
public int СhairNum { get; set; }
public bool IsProjector { get; set; }
public bool IsBoard { get; set; }
public string Description { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Request> Requests { get; set; }
}
I tried to pass this data in service. But I have serialization error, when I call http://localhost:99999/api/Rest.
<ExceptionMessage>
The "ObjectContent`1" type could not serialize the response text for the content type "application / json; charset = utf-8".
</ ExceptionMessage>
What is the best way to pass the data like in model into json?
It helped to put in WebApiConfig:
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);
I have a booking app, which accepts a single "booking" object, and works ok. My question is, how do I convert this to accept multiple records (from JSON):
Booking.cs
namespace MvcApplication4.Models
{
public class Booking
{
[Key()]
public long ID { get; set; }
public long? HID { get; set; }
public long RID { get; set; }
public string Occ { get; set; }
public DateTime CI { get; set; }
public DateTime CO { get; set; }
public long? CID { get; set; }
}
}
BookingsContext.cs
namespace MvcApplication4.Models
{
public class BookingsContext : DbContext
{
public BookingsContext() : base("name=BookingsContext")
{
}
public DbSet<Booking> Bookings { get; set; }
}
}
BookingsController.cs
// POST api/Bookings
public HttpResponseMessage PostBooking(Booking booking)
{
if (ModelState.IsValid)
{
// Add the booking
db.Bookings.Add(booking);
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, booking);
response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = booking.RID }));
return response;
}
}
The JSON currently passed is:
var comment = {ID:0, HID: $('#HID').val(), RID:$('#RID').val(), Occ:$('#Occ').val(), CI:$('#CI').val(), CO:$('#CO').val(), CID:$('#CID').val()},{ID:0, HID: $('#HID').val(), RID:$('#RID').val(), Occ:$('#Occ').val(), CI:$('#CI').val(), CO:$('#CO').val(), CID:$('#CID').val()};
How can I pass multiple records to the controller, so that I don't have to call the JSON Post method may times?
You could modify the signature of your action to take an array of Booking:
public HttpResponseMessage PostBooking(Booking[] bookings)
{
...
}
and then send an array of booking from the client:
var bookings =
[
{
ID: 0,
HID: 'hid1',
RID: 'rid1',
Occ: 'occ1',
CI: 'ci1',
CO: 'co1',
CID: 'cid1'
},
{
ID: 1,
HID: 'hid2',
RID: 'rid2',
Occ: 'occ2',
CI: 'ci2',
CO: 'co2',
CID: 'cid2'
}
];