我可以在保存更改之前验证实体吗?

问题描述:

我有一个非常简单的WCF数据服务应用程序,我正在做一些基本的CRUD操作。对于正在更改的实体集,我有ChangeInterceptor,但ChangeInterceptor中的对象是数据库中的当前状态,而不是HTTP PUT中发送的内容。 有没有办法在保存之前验证对象的属性?我可以在保存更改之前验证实体吗?

这里是我的ChangeInterceptor:

[ChangeInterceptor("People")] 
public void OnChangePerson(Person personChanging, UpdateOperations updateOperations) { 
    switch (updateOperations) { 
     case UpdateOperations.Change: 
      // personChanging is the database version here, not the changed version. 
      break; 
     default: 
      break; 
    } 
} 

这里是我的客户端代码(jQuery的):

var data = { 
    FirstName: "NewFN", 
    LastName: "NewLN" 
}; 
$.ajax({ 
    type: "PUT", 
    url: serviceUrl + "/People(" + personID + ")", 
    contentType: "application/json", 
    dataType: "json", 
    data: JSON.stringify(data), 
    success: function (data) { 
     alert("Success!"); 
    }, 
    error: function (error) { 
     alert("An error occured"); 
    } 
}); 

这里是JSON被发送到服务器: alt text

以下是收到消息时的ChangeInterceptor: alt text

我已经上传的代码为这个项目在这里:http://andyjmay.com/test/2921612/ODataTest.zip

+0

+1 for include source。 – jfar 2010-09-27 03:25:21


我下载了您的示例,重新解决了您的问题,并能够使用此解决方案查看最新更新值。
虽然我在内部调查了这个问题,但是您可以更改代码以使用合并动词而不是PUT吗?
通过此更改,您现在应该可以在通过jQuery客户端更新值时看到最新的实体值传入ChangeInterceptors。

$.ajax({
beforeSend: function (xhrObj) {
xhrObj.setRequestHeader("X-Http-Method", "MERGE");
},
type: "POST",
url: serviceUrl + "/People(" + personID + ")",
contentType: "application/json",
dataType: "json",
data: JSON.stringify(data),
success: function (data) {
GetAllPeople();
},
error: function (error) {
alert(error);
}
});

+0

非常感谢!这是WCF数据服务和EF的问题,还是这种预期的行为?我刚刚开始使用WCF数据服务,如果可能,我想遵循最佳做法。 – 2010-09-28 13:16:55

+0

嗨,Andy,这是WCF数据服务服务器运行时中的一个错误。 我们似乎将过时的值传递给用户运行时并在内部使用客户端发送的最新值。 如果您想验证PUT的值,请考虑在ObjectContext上重写SaveChanges方法并在其中进行验证。以下是此方法的MSDN文档:http://msdn.microsoft.com/en-us/library/bb336792.aspx – 2010-09-28 14:11:02

WCF得到了一些很好的扩展,你可以编写MessageInspector和ParameterInspector。 我确定其中的一个人可以帮助您在服务器开始处理请求之前验证内容。

嗯...你说personChanging是数据库版本,它肯定应该是更新后的版本。

我的测试(和产品团队中的人)告诉我,它应该是通过电线传输的版本。其他事情可能会出错吗?

例如,您的财产可以是名字而不是名字?

+0

根据此(msdn.microsoft.com/en-us/library/dd744842.aspx)您是正确的,该参数应该是发送的。但事实并非如此。此外,属性名称是正确的,更新的作品,我只是无法验证它。我在这里上传了我的测试项目:http://andyjmay.com/test/2921612/ODataTest.zip – 2010-09-24 12:53:32

如果服务是基于EF的,并且请求是PUT,那么将提供旧值(这与EF提供程序的实现方式有关,可能是一个错误,我们将进一步研究) 。您可以通过发送MERGE请求来解决此问题。我证实,在那种情况下,它按预期工作(你会得到新的值)。 MERGE有一些不同的语义,但它可能适用于你。 PUT会覆盖实体,所以如果您没有为给定属性发送值,它将被重置为默认值。 MERGE只用来自有效载荷的值修改现有的实体,所以如果某个属性不在有效载荷中,它的值将保持不变。