1

I have the following annotated model

public class TypeA
{ 
    public int TypeAId { get; set;  }  

    [Required]
    public TypeB B { get; set; }         

    public string AValue { get; set; }
}


public class TypeB
{ 
    public int TypeBId { get; set; } 

    public string BValue { get; set; }
}

exposed as v3 odata by a WCF Data Service using entity framework. When i attempt to update a TypeA using a DataServiceContext such as

var ctx = new Service.Context(new Uri("http://localhost/TestUpdateService/TestUpdateService.svc"));
var t = ctx.theATypes.Expand(p => p.B).First();
t.AValue = "New value";
ctx.UpdateObject(t);
ctx.SaveChanges();

I get a DbEntityValidationException in the service stating "The B field is required"

the body of the request "MERGE /TestUpdateService/TestUpdateService.svc/theATypes(1) HTTP/1.1" contains the AValue property change but does not contain any of the link information to property B (which is my guess as to why the validation is failing in the service). Am i missing something about updating the data service?

Barett
  • 5,826
  • 6
  • 51
  • 55

2 Answers2

1

I believe what's happening is that OData uses MERGE verb that is more efficient than PUT (PUT requires sending all fields while MERGE sends only changed data), but in your model field "B" is marked as Required, so you get a validation exception on the client side. To test that this is the case you can temporarily remove [Required] attribute from the "B" field and check that the update operation succeeds. If so, you have two options:

  • Remove [Required] attributes from you model on the client side to enable make MERGE work;
  • Ensure that the values of required fields are set prior the SaveChanges call.
Vagif Abilov
  • 9,835
  • 8
  • 55
  • 100
  • removing the attribute certainly allows the update to succeed. however the validation exception is occurring in the data service so i'm not sure i understand what you mean by "remove [required] from the model on the client side. Also, the required values are set prior to save changes.. – Garrett Taiji Jan 23 '15 at 18:24
0

The request URL needs to have $expand=B, so that it also reads .B property value, which helps in following MERGE.

var ctx = new Service.Context(new Uri("http:// localhost /TestUpdateService/TestUpdateService.svc"));

//var t = ctx.theATypes.First();

var t=

(

from s in ctx.theATypes 

select new TypeA(){AValue =s.AValue , B=s.B} 

)
.First();

t.AValue = "New value";

ctx.UpdateObject(t);

ctx.SaveChanges
Jamal
  • 763
  • 7
  • 22
  • 32
challenh
  • 86
  • 1