2
votes

I have a problem with post requests to OData controller when the json data contains more properties than required by Post method defined in OData controller. So called over-posting is supposed to be allowed for MVC controllers, but it seems that OData controllers don't accept it. Please review to following sample.

I have a simple entity class:

public class Skill
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [StringLength(100)]
    public string Name { get; set; }

    public SkillAffiliation ApplicableTo { get; set; }
}
  • SkillAffiliation is an enum.

And a simple OData controller with Post method that looks like this:

public IHttpActionResult Post(Skill skill)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    _dbContext.Skills.Add(skill);
    _dbContext.SaveChanges();

    return Created(skill);
}

The problem is that I use a third party web controls collection, and the control that is supposed to use my OData controller adds an additional json property, basically the POST request looks like this:

{"Name":"TEST2","ApplicableTo":"Vehicle","ApplicableTo_input":"Vehicle"}

So there is an extra ApplicableTo_input property - this unfortunately causes a model validation error. The ModelState.IsValid property is set to false, and there is an error message "The property 'ApplicableTo_input' does not exist on type 'Mango.Models.Skill'. Make sure to only use property names that are defined by the type." Adding this extra property is obviously a bug in their solution and will be fixed with next release, however until that time comes I have to find some workaround.

I've already tried to add [Bind(Exclude="ApplicableTo_input")] attribute to my post action parameter, but it doesn't seem to work. Any ideas?

1
could you provide a sample to reproduce it (without DB)? - Artiom
Is the skill parameter by any chance null? - TheSchmu
Yes the skill parameter in the Post method of my odata controller is null and the ModelState.IsValid == false. - bartosz
Here you can download a sample illustrating my problem: dropbox.com/s/pmqrj4q7101z6ai/Sample_20150417.zip?dl=0 - bartosz

1 Answers

1
votes

Make SkillWrapper an open entity by add an dictionary property.

public class SkillWrapper 
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [StringLength(100)]
    public string Name { get; set; }

    public SkillAffiliation ApplicableTo { get; set; }

    public IDictionary<string, object> CustomerProperties { get; set; }
}

Use Skill to store value and save in DB.

public IHttpActionResult Post(SkillWrapper skill)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    var value = new Skill();
    ...//get property value form skill
    _dbContext.Skills.Add(value);
    _dbContext.SaveChanges();

    return Created(value);
}