【问题标题】:Can I validate an entity before saving the changes?我可以在保存更改之前验证实体吗?
【发布时间】:2010-09-23 19:07:17
【问题描述】:

我有一个非常简单的 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:

这是收到消息时的 ChangeInterceptor:

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

【问题讨论】:

    标签: c# json wcf-data-services odata


    【解决方案1】:


    我下载了您的示例,重现了您的问题,并且现在可以使用此解决方法查看最新的更新值。
    当我在内部对此进行调查时,您能否更改您的代码以使用 Merge 动词而不是 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);
    }
    });

    【讨论】:

    • 非常感谢!这是 WCF 数据服务和 EF 的问题,还是这是预期的行为?我刚刚开始使用 WCF 数据服务,如果可能的话,我想遵循最佳实践。
    • 您好 Andy,这是 WCF 数据服务服务器运行时中的一个错误。我们似乎将过时的值传递给用户运行时,并在内部使用客户端发送的最新值。如果您也想验证 PUT 的值,请考虑覆盖 ObjectContext 上的 SaveChanges 方法并在那里进行验证。这是此方法的 MSDN 文档:msdn.microsoft.com/en-us/library/bb336792.aspx
    【解决方案2】:

    WCF 有一些不错的扩展,你可以编写像 MessageInspector 和 ParameterInspector。 我确信其中之一可以帮助您在服务器甚至开始处理请求之前验证内容。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        嗯……你说personChanging是数据库版本,那肯定是更新版本。

        我的测试(以及产品团队的人员)告诉我,它应该是通过网络传来的版本。会不会有其他问题?

        例如,您的属性可以是 Firstname 而不是 FirstName?

        【讨论】:

        • 据此(msdn.microsoft.com/en-us/library/dd744842.aspx)您是正确的,该参数应该是发送的那个。然而,事实并非如此。此外,属性名称是正确的,并且更新有效,我只是无法验证它。我在这里上传了我的测试项目:andyjmay.com/test/2921612/ODataTest.zip
        猜你喜欢
        • 1970-01-01
        • 2021-08-08
        • 1970-01-01
        • 2023-03-03
        • 2013-04-22
        • 1970-01-01
        • 1970-01-01
        • 2016-05-26
        • 1970-01-01
        相关资源
        最近更新 更多