.NET Core Controller inheritance - json

I looked for this question, and altough there are similar questions asked, I could not find an answer.
So I have a problem. I have 2 classes:
public class Person {
public string name{ get; set; }
}
public class Doctor: Person{
public string specialization{ get; set; }
}
And I have controller:
[HttpPost]
...
public virtual IActionResult PostPerson([FromBody]Person person)
{ ... }
How can I make it so that if I send JSON like this:
{"specialization":"obgyn"}
that I get Doctor object in my controller?
Do I need to make custom binding (is there an example? however I have much much more classes like this (100ts) so I would not like to do it for each class specifically) or set JsonOptions in Startup.cs, or something third??
Thank you.

So the way to get this working is t oadd in your Startup.cs file a JSonOptions:
opts.SerializerSettings.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All;
This would then add $type properties to response, and would also read $type from incoming Json Messages. Unfortunatly, my clients wish changed because he does not want to identify the class by that field, but a custom another one, so this solution is not for me, but the answer my still help someone

Related

Cannot Bind Json to Object

I am having an issue while trying the WebAPI of net core.
For some reason my object always comes empty no matter what I try. I've checked several other SO questions regarding this but cannot find a solution for what I am facing.
My model:
My controller (getting the null object):
And the POSTMAN request:
I've tried both with and without the [FromBody] option as I've seen in other SO questions that some people solved their issues with it.
Any ideas?
All the auto-implemented properties must have an public modifier before them to for JSON.NET to safely deserialize them.
public class APIRequest
{
string Action { get; set; }
}
Because in the above example no access modifier is given, thereby making it as private, so the default value of the property is assigned which is default(string) that is null.
public class APIRequest
{
public string Action { get; set; }
}
By default all class members are private and the class itself is internal, so you have to mark your property with public modifier.

How to select class for collection member in fasterxml JSON conversion

In my REST application I am using fasterxml to serialize and deserialize POJOs to JSON. I run into problems with collections such as List in a case like this.
public class JsonRequest {
public int anumber;
public String astring;
public List<XyzClass> data;
}
The properties anumber and astring convert back and forth just fine without any annotations. For **data*, although the compiler can see that the List elements are (should be) XyzClass that information is not available to the jackson framework, so it doesn't know what class to use when deserializing the elements.
For some reason I can't make sense of the documentation as to which annotation to use to fix this. The #JsonDeserialize annotation doesn't help this. Can anyone point me in the right direction?
After some research I finally found out how to make this work.
public class JsonRequest {
public int anumber;
public String astring;
#JsonDeserialize(contentAs = XyzClass.class) // <-- Added
public List<XyzClass> data;
}
To answer the questions in comments above, the code for XyzClass is just a trivial POJO like:
public class XyzClass {
public String name;
public int age;
}
What was tripping me up is that I was looking for an annotation to the effect of #JsonDeserializeContentAs(class = XyzClass.class) which doesn't exist because I missed the fact that #JsonDeserilize had a contentAs option.
Hopefully this posting will save someone else the same trouble.

Entity Type Has No Key Defined

Another 'Entity Type 'x' has no key defined' question, but I've set the [Key] attribute on a property so I'm a bit confused.
Here's my entity and context classes:
namespace DoctorDB.Models
{
public class Doctor
{
[Key]
public string GMCNumber;
[Required]
public string givenName;
[Required]
public string familyName;
public string MDUNumber;
public DateTime MDUExpiry;
public string MDUCover;
}
public class DoctorContext : DbContext
{
public DbSet<Doctor> Doctors { get; set; }
}
}
When I go to create my controller, I've selected to create it with the Entity Framework methods using this entity and context:
and I get this error:
My only thought is whether you can't successfully use [Key] on a string property. If you can't then fair enough, I'll work round it, but I'd be grateful if someone could confirm this one way or the other.
You need to change GMCNumber to a property not a field.
To help clarify, this line:
public string GMCNumber;
needs to become:
public string GMCNumber { get; set; }
I encountered the same error message when I had defined the property as private.
I ran into this post after facing a similar issue today. The problem was that I was attempting to create the scaffold after adding the [Key] attribute to my model and without compiling. Once I compiled with the [Key] attribute the scaffolding generated just fine.

Template with Required Attribute Knowledge

This seems very basic but I'm struggling to find a solution I'm happy with at the minute. All I want to do is add a class with the name "Required" to any fields that have a required property against them so:
public class Dummy{
[Required]
public string Name {get; set;}
}
Would be called with
#Html.EditorFor(model=>model.Name)
and would output something like
<input id="Name *Data-VAL and other attribs* class="Required" />
With all the inbuilt unobtrusive goodness etc. I'm using Razor and MVC 3. Any help much appretiated
You may take a look at the following blog post which explains how you could write a custom DataAnnotationsModelMetadataProvider to achieve this.
using System.ComponentModel.DataAnnotations; //You need to import this namespace
public class Dummy {
[Required]
public string Name { get; set; }
}
Further reference: http://www.asp.net/mvc/tutorials/validation-with-the-data-annotation-validators-cs

Cannot get my html input array to serialize into a List<string> in Asp.Net mvc

I am attempting to implement a tagging system into my asp.net MVC project. When a user edits or adds a task, they can add any amount of tags they want before submitting. I am using the Jquery Tagit plugin, so when a user adds a new tag an input field is created that looks like:
<input type="hidden" style="display:none;" value="tag1" name="Tags[]">
When the user presses the submit button after adding a few tags, the browser sends the following querystring to the server (retrieved via fiddler):
IsNew=True&Id=2222&Title=Test+Title&Description=Test+Description&Tags%5B%5D=Tag1&Tags%5B%5D=blah&Tags%5B%5D=another-tag
Now my viewmodel that I am serializing this data into has the following structure:
public class KnowledgeBaseTaskViewModel
{
public int Id { get; set; }
[Required(AllowEmptyStrings=false, ErrorMessage="Task title is required")]
[StringLength(500)]
public string Title { get; set; }
[Required(AllowEmptyStrings=false, ErrorMessage="Task description is required")]
[StringLength(500)]
public string Description { get; set; }
public List<string> Tags { get; set; }
public bool IsNew { get; set; } // Needed to determine if we are inserting or not
}
Finally my receiving action has the following signature:
[HttpPost]
public ActionResult EditTask(KnowledgeBaseTaskViewModel task)
The issue is that my tag list is not serializing correctly, and my List Tags is null. I have looked at various questions on this site on how to serialize arrays but I still cannot see what I am doing wrong. Any help is greatly appreciated.
It sounds like what you've got should work, but try changing the type of Tags property from List to IList. the model binder might not be using the concrete List<> type.
also, check out this article by Phil Haack: http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx