Serialization/Deserialization of System.Type in WebAPI Project with resource model PUT
Code looks fine, this issue could be on the client side; i.e. how you're serializing it from the Front end/Client
while calling/sending to the backend API
.
Double check thats you are using contentType:"application/json"
& using JSON.stringify
method to convert it to JSON string when you send it.
Look here and here similar issue
Update 2: In your blazor entity try adding a key attribute
public class BlazorEntityModel{ [Key] // add this to force it to recognize it as key public int Id { get; set; } // Commenting this out makes PUT work. public string FirstName { get; set; } public string LastName { get; set; } public string Address { get; set; }}
Update 3: Configure/override the serialization handling
Can you try to add the following in your global.asax
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
If this works, let me know we may have to move to a DTO or VM so we trace and loops/circular refs.
One way to handle that is to use two classes with inheritance.
public class MyObject { public string FirstName { get; set; } public string LastName { get; set; } public string Address { get; set; }}public class CreatedVersionOfMyObject : MyObject { public int Id { get; set; }}
Then your controller can easily expose multiples endpoints with those entitities
[Route("objects")] public class MyObjectControLler : Controller { [Route("{id}")] [HttpGet] [ProducesResponseType((int)HttpStatusCode.NotFound)] [ProducesResponseType((int)HttpStatusCode.InternalServerError)] [ProducesResponseType(typeof(CreatedVersionOfMyObject), (int)HttpStatusCode.OK)] public Task<IActionResult> GetByIdAsync(Guid id) { // Do what you have to do to retrieve the object by id } [Route("{id}")] [HttpDelete] [ProducesResponseType((int)HttpStatusCode.NotFound)] [ProducesResponseType((int)HttpStatusCode.InternalServerError)] [ProducesResponseType((int)HttpStatusCode.NoContent)] public Task<IActionResult> DeleteByidAsync(Guid id) { // Do what you have to do to delete the object by id } [Route("{id}")] [HttpPut] [ProducesResponseType((int)HttpStatusCode.NotFound)] [ProducesResponseType((int)HttpStatusCode.InternalServerError)] [ProducesResponseType(typeof(MyObject), (int)HttpStatusCode.OK)] public Task<IActionResult> PutAsync([FromRoute]Guid id, [FromBody]MyObject theModifiedObject) { // Do what you have to do to retrieve the object by id } [Route("")] [HttpPost] [ProducesResponseType((int)HttpStatusCode.NotFound)] [ProducesResponseType((int)HttpStatusCode.InternalServerError)] [ProducesResponseType(typeof(CreatedVersionOfMyObject), (int)HttpStatusCode.Created)] public Task<IActionResult> PostAsync(MyObject theModifiedObject) { // Do what you have to do to create the object and return the version with the id } }
Finally, regarding the mapping you can also easily handle that (see original doc https://docs.automapper.org/en/stable/Mapping-inheritance.html)
CreateMap<BaseEntity, BaseDto>() .ForMember(dest => dest.SomeMember, opt => opt.MapFrom(src => src.OtherMember));CreateMap<DerivedEntity, DerivedDto>() .IncludeBase<BaseEntity, BaseDto>();