1

我已经初始化了一个 jaydata 上下文:

$data.initService('/odata/$metadata', { dataServiceVersion: '3.0' }).then(function (context) {
    if (!mycontext)
        mycontext= context;

   //this is a hack
    mycontext.prepareRequest = function (r) {
        if (r[0].method == "PATCH") {
            r[0].method = 'PUT';
            r[0].headers['X-HTTP-METHOD'] = 'UPDATE';
        }
    };

    vm.roles = mycontext.Role.toLiveArray();
    vm.users = mycontext.User.toLiveArray();
});

mycontext.prepareRequest 的解决方法是在 github 上发现此问题后完成的

已成功显示已初始化角色和用户的列表。但是我在更新实体时仍然遇到问题:

vm.updateRole = function (r) {
    r.Name = 'NewUpdatedName';
    zivacontext.Role.attach(r);
    r.entityState = $data.EntityState.Modified;
    zivacontext.saveChanges().then(function (result) {
        debugger;
    });

};

请求被重定向到下面提供的控制器的 UpdateEntity 方法,但是只设置了实体的 Id 属性。其他属性为 NULL,如果请求被重定向到 PatchEntity 方法(当未应用变通方法破解时),更改的字段也不会传递给增量。在这两种情况下的请求有效负载中(无论是否被破解),只有 Id 被传递给服务器。

控制器:

公共类 BaseODataController : EntitySetController where TEntity : class where TEntityDto : class where TIdentityType : class where TService : ICrudService { // ...

protected override TEntityDto UpdateEntity(TIdentityType key, TEntityDto update) { _service.Update(update); 返回 base.UpdateEntity(key, update); }

    protected override TEntityDto PatchEntity(TIdentityType key, Delta<TEntityDto> patch)
    {
        return base.PatchEntity(key, patch);
    }

// ... }

此外,在调试时,我可以看到实体已跟踪更改:

r: RoleDto
  $$hashKey: "00I"
  Description: (...)
  Id: (...)
  Name: (...)
  ValidationErrors: (...)
  _ValidationErrors: Array[0]
  _changedProperties: Array[2]
    0: MemberDefinition
    1: MemberDefinition
       configurable: true
       dataType: function String() { [native code] }
       definedBy: function RoleDto(){
       enumerable: true
       kind: "property"
       name: "Name"
       originalType: "Edm.String"
       type: function String() { [native code] }
       __proto__: MemberDefinition
       length: 2
       __proto__: Array[0]
_entityState: 30
_isDirty: true
_isNew: false

我唯一不明白的是为什么 ValidationErrors 在 _changedProperties 中:

_changedProperties: Array[2]
  0: MemberDefinition
    configurable: true
    dataType: function Array() { [native code] }
    definedBy: function Entity(){
    elementType: function ValidationError(){
    enumerable: false
    kind: "property"
    monitorChanges: true
    name: "ValidationErrors"
    notMapped: true
    originalElementType: function ValidationError(){
    originalType: function Array() { [native code] }
    storeOnObject: true
    type: function Array() { [native code] }
    __proto__: MemberDefinition

所以这里的问题是为什么更改没有在请求有效负载中传递给服务器?

提前致谢!

4

1 回答 1

3

在您的初始化中使用maxDataServiceVersion而不是dataServiceVersion.

我不确定您为什么需要上述技巧,尤其是在将其与诸如UPDATE http://msdn.microsoft.com/en-us/library/dd541276.aspx之类的未知动词一起使用时。MERGE在 OData 中,V2 和PATCHV3有两个允许的 HTTP 动词。一旦你设置maxDataServiceVersion: 3.0了 JayData 就会发出正确的PATCH请求。

您正在使用的hack应该应用于不同的情况,其中客户端、代理、路由器不支持这两个动词。在这种情况下,您将改为发送 POST 请求并将所需的动词设置为X-HTTP-Method. 这种方法通常被称为动词隧道,参见例如http://msdn.microsoft.com/en-us/library/dd541471.aspx

$data.initService('/odata', { maxDataServiceVersion: '3.0' }).then(function (context) {
    if (!mycontext)
        mycontext= context;

   //this hack shouldn't be used here
   // mycontext.prepareRequest = function (r) {
   //     if (r[0].method == "PATCH") {
   //         r[0].method = 'PUT';
   //         r[0].headers['X-HTTP-METHOD'] = 'UPDATE';
   //     }
   // };


    vm.roles = mycontext.Role.toLiveArray();
    vm.users = mycontext.User.toLiveArray();
});

根据评论更新

我会通过控制台检查上下文。确保ctx全球可用,例如

window.ctx = context;

通过 ID 附加一些东西,例如

var role = ctx.Role.attachOrGet({ID: 'GUID or Int'});

role.将允许您访问实体属性,例如假设Status接受 Int 的属性

role.Status = 1; //Set role.Status to 1

上次运行ctx.saveChanges()。如果一切设置正确,JayData 将向/odata/Role/GUID端点发送一个 PATCH 请求,并将更改作为 JSON 有效负载。

于 2014-01-18T11:23:55.360 回答