我已经初始化了一个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的解决方法是在找到this issue on 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被传递给服务器。
控制器:
public class BaseODataController:EntitySetController TEntity:class 其中TEntityDto:class 其中TIdentityType:class 其中TService:ICrudService { // ...
protected override TEntityDto UpdateEntity(TIdentityType key,TEntityDto update) { _service.Update(更新); return 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
所以这里的问题是为什么更改没有在Request Payload中传递给服务器?
提前致谢!
答案 0 :(得分:3)
在初始化时,使用maxDataServiceVersion
代替dataServiceVersion
。
我不确定为什么你需要上述黑客攻击,尤其是在使用UPDATE
http://msdn.microsoft.com/en-us/library/dd541276.aspx之类的未知动词时。在OData中,V2有两个允许的HTTP动词MERGE
,V3有PATCH
。设置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有效负载。