0

I've seen one or two posts on this same topic but neither solution that worked for those questions worked for me so I'm going to ask here.

I have an angular 2 (2.4) app that is calling an .netCore (1.0) Web API.

My Get Requests to the web api work fine. My web api allows all methods on it (it does restrict origin, but because the get works, I'm under the impression that that is not the issue).

My request gets to the API but the request content is not deserialized into the parameter object. The parameter on the webapi is always null.

Currently my web api method is (for testing purposes):

 [HttpPost]        
    public Member Post([FromBody] DocMe.Model.Provider.Member member)
    {
        return member;
    }

My request looks like this:

enter image description here

My code to generate the request from Angular is:

public post(url: string, data: any): Observable<Response> {       
    this.headers = new Headers();
    this.headers.append('Content-Type', 'application/json');
    this.headers.append('Accept', 'application/json');

    let token = this.authService.GetToken();

    if (token !== '') {
        this.headers.append('Authorization', 'Bearer ' + token);
    }     
    return this.http.post(url, JSON.stringify(data), { headers: this.headers });
}

The Request Payload in the devtools image accurately represents the contents of the data object passed in to the method.

When I debug the method, I see the call get past the signature but with the "member" parameter = null. The request payload matches the properties of the Member type (exception here being that the payload is camelCase whereas the Member Type is PascalCase).

My POCO definition is:

public class Member
{
    public Member()
    {
        this.Id = Guid.NewGuid();
        this.MemberTypeId = 1;
        this.Deleted = false;

        this.MemberPractices = new HashSet<MemberPractice>();
        this.Educations = new HashSet<Education>();
        this.Insurances = new HashSet<Insurance>();
        this.Languages = new HashSet<Language>();
        this.Specialties = new HashSet<Specialty>();
        this.WorkHours = new HashSet<WorkHour>();
        this.WorkHoursOverrides = new HashSet<WorkHoursOverride>();
    }

    [Key]        
    [Display(Name = "Id")]
    public Guid Id { get; set; } // uniqueidentifier, not null        
    [Display(Name = "Member Type Id")]
    public int MemberTypeId { get; set; } // int, not null
    [MaxLength(50)]
    [StringLength(50)]
    [Display(Name = "NPI")]
    public string NPI { get; set; } // varchar(50), null
    [MaxLength(100)]
    [StringLength(100)]
    [Display(Name = "First Name")]
    public string FirstName { get; set; } // nvarchar(100), null
    [MaxLength(100)]
    [StringLength(100)]
    [Display(Name = "Last Name")]
    public string LastName { get; set; } // nvarchar(100), null
    [MaxLength(256)]
    [StringLength(256)]
    [Display(Name = "Contact Email")]
    public string ContactEmail { get; set; } // nvarchar(256), null
    [MaxLength(10)]
    [StringLength(10)]
    [Display(Name = "Gender")]
    public string Gender { get; set; } // varchar(10), null
    [MaxLength]
    [Display(Name = "Biography")]
    public string Biography { get; set; } // varchar(max), null
    [MaxLength(450)]
    [StringLength(450)]
    [Display(Name = "Identity Id")]
    public string IdentityId { get; set; } // nvarchar(450), null        
    [Display(Name = "Deleted")]
    public bool Deleted { get; set; } // bit, not null
    [Display(Name = "Deleted Date")]
    public DateTime? DeletedDate { get; set; } // datetime, null
    [Display(Name = "Deleted By")]
    public Guid? DeletedBy { get; set; } // uniqueidentifier, null

    [ForeignKey("Id")]
    public LkupMemberType LkupMemberType { get; set; }
    public ICollection<MemberPractice> MemberPractices { get; set; }
    public ICollection<Education> Educations { get; set; }
    public ICollection<Insurance> Insurances { get; set; }
    public ICollection<Language> Languages { get; set; }
    public ICollection<Specialty> Specialties { get; set; }
    public ICollection<WorkHour> WorkHours { get; set; }
    public ICollection<WorkHoursOverride> WorkHoursOverrides { get; set; }
}

My front end model that is responsible for filling the Request Payload is:

export class ProviderModel {
public id: string;
public npi: string;
public firstName: string;
public lastName: string;
public contactEmail: string;
public gender: string;
public biography: string;
public specialties: SpecialityModel[];
public educations: EducationModel[];
public insurances: InsuranceModel[];
public languages: LanguageModel[];

constructor() {
    this.id = null;
    this.specialties =  [];
    this.educations = [];
    this.insurances = [];
    this.languages = [];
}
}

Given how new .net core is, I'm not sure if I'm doing something wrong or if there is a bug of some sort that I may have stumbled upon.

I've been staring at this problem for a few days so I wanted to put this out there to test my sanity and hopefully have it resolved so I can move on from something that should be relatively trivial.

JakeHova
  • 1,189
  • 2
  • 15
  • 36

1 Answers1

1

Update:I suspect HashSet is the problem. Consider writing your own JsonConverter for HashSet.

======

Have you configured SerializerSettings for your Web APIs to resolve Camel casing?

 services.AddMvc().AddJsonOptions(options =>
                  {
                      options.SerializerSettings.ContractResolver =
                          new CamelCasePropertyNamesContractResolver();
                  });
Adil
  • 3,248
  • 1
  • 22
  • 27
  • I originally had it assigned to the DefaultContractResolver(). I changed it to CamelCasePropertyNamesContractResolver just to see if that would work and I have the same issue. – JakeHova Feb 25 '17 at 08:22
  • Is there a better way to handle Lists of objects coming in so that I don't have to write a custom converter for them? Could using a List type instead of a HashSet work better? – JakeHova Feb 25 '17 at 08:38
  • My expectation is that List should work out of box... but then you won't have HashSet functionality. If List is good enough for you then may be consider getting rid of HashSet. This post may help you: http://stackoverflow.com/questions/28672082/asp-net-entity-framework-6-hashset-or-list-for-a-collection – Adil Feb 25 '17 at 08:39
  • In general, I keep my DTOs separate than Entity models. – Adil Feb 25 '17 at 08:42
  • In my case the issue was that the Id for the POCO was not null and I was passing a null in for that value. I'm guessing it couldn't cast it at that point so it just defaulted to null. – JakeHova Feb 25 '17 at 20:00