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=0bartosz

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);
}