Odata 使用Breezejs发布批处理请求
我一直在尝试使用Breezejs和WebAPI OData控制器发布一个实体。Odata 使用Breezejs发布批处理请求,odata,breeze,asp.net-web-api,Odata,Breeze,Asp.net Web Api,我一直在尝试使用Breezejs和WebAPI OData控制器发布一个实体。 以下是配置: config.Routes.MapODataRoute( routeName: "odata", routePrefix: "odata", model: model, batchHandler: new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer)); 其中模型非常简单: public class ServiceMetadat
以下是配置:
config.Routes.MapODataRoute(
routeName: "odata",
routePrefix: "odata",
model: model,
batchHandler: new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));
其中模型非常简单:
public class ServiceMetadata
{
public int ServiceMetadataId { get; set; }
public string ServiceName { get; set; }
public string Description { get; set; }
public ObjectState? State { get; set; }
public DateTime? LastUpdated { get; set; }
}
并通过默认设置进行映射:
ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
客户端使用AngularJs也非常简单,部分来自Todo示例:
实际过帐使用默认的createEntity()方法完成:
整个事情看起来像:
serviceMetadatas.createServiceMetadata({
ServiceName: $scope.newServiceName,
Description: $scope.newServiceDescription
});
serviceMetadatas.saveChanges();
但是,没有将请求传输到正确的控制器(从EntitySetController继承的ServiceMetadatasController)或任何其他控制器。
HTTP请求如下所示:
POST http://localhost:8081/odata/$batch HTTP/1.1
Host: localhost:8081
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0
Accept: multipart/mixed
Accept-Language: he-IL,he;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DataServiceVersion: 2.0
Content-Type: multipart/mixed; charset=UTF-8;boundary=batch_4f09-d7cf-dd99
MaxDataServiceVersion: 2.0
Referer: http://localhost:9000/
Content-Length: 580
Origin: http://localhost:9000
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
--batch_4f09-d7cf-dd99
Content-Type: multipart/mixed; boundary=changeset_ca0c-06b7-ddbe
--changeset_ca0c-06b7-ddbe
Content-Type: application/http
Content-Transfer-Encoding: binary
POST ServiceMetadatas HTTP/1.1
Content-ID: 1
DataServiceVersion: 2.0
Accept: application/atomsvc+xml;q=0.8, application/json;odata=verbose;q=0.5, */*;q=0.1
Content-Type: application/json;odata=verbose
MaxDataServiceVersion: 2.0
{"ServiceMetadataId":-1,"ServiceName":"sdf sdf","Description":"sd fgs df","LastUpdated":null}
--changeset_ca0c-06b7-ddbe--
--batch_4f09-d7cf-dd99--
答复如下:
HTTP/1.1 202 Accepted
Cache-Control: no-cache
Pragma: no-cache
Content-Type: multipart/mixed; boundary=batchresponse_966d4460-e00e-4900-b1c9-85b17081cfac
Expires: -1
Server: Microsoft-IIS/8.0
Access-Control-Allow-Origin: http://localhost:9000
Access-Control-Allow-Credentials: true
DataServiceVersion: 2.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcVG9tZXJcRG9jdW1lbnRzXFZpc3VhbCBTdHVkaW8gMjAxMlxQcm9qZWN0c1xFYXN5Qml6eVxFYXN5Qml6eS5XZWJBUElcb2RhdGFcJGJhdGNo?=
X-Powered-By: ASP.NET
Date: Sun, 15 Sep 2013 14:32:39 GMT
Content-Length: 443
--batchresponse_966d4460-e00e-4900-b1c9-85b17081cfac
Content-Type: multipart/mixed; boundary=changesetresponse_44da5dcf-877d-4041-a82b-c51d06a4e9a4
--changesetresponse_44da5dcf-877d-4041-a82b-c51d06a4e9a4
Content-Type: application/http
Content-Transfer-Encoding: binary
HTTP/1.1 406 Not Acceptable
Content-ID: 1
--changesetresponse_44da5dcf-877d-4041-a82b-c51d06a4e9a4--
--batchresponse_966d4460-e00e-4900-b1c9-85b17081cfac--
知道这是怎么回事吗?
B.T.W获取请求非常有效
附言。
在看了两个演示之后,我认为考虑到WebApi和OData,使用BreezeJS将是直截了当的。我必须说,配置这个JS库远不容易。我希望它将很难设置,但易于使用 谢谢 @UPDATE见贾维尔的精彩答案 在深入挖掘breeze代码上的allllot之后,我意识到问题深入到breezejs的createChangeRequests()中,就在这里:
request.requestUri = entity.entityType.defaultResourceName;
其中,由于某种原因,DefaultResourceName完全忽略指向此实体的路径。
长话短说,以下是需要解决的问题:
manager.metadataStore.getEntityType(ENTITY_TYPE).setProperties({defaultResourceName: THE_MISSING_PART_FROM_THE_URL + ENTITY_TYPE});
manager.createEntity(ENTITY_TYPE, values);
不是很好,但仍然有效 不确定这是否是您的问题,但Microsoft的ODataModelBuilder没有实现完整的OData模型。特别是,它不会生成外键约束。MS已意识到这一点,并计划在以后的版本中对其进行更新。在此之前,最好使用WCF数据服务创建OData端点 问题在于内部请求的url。url需要与主机相对。假设您的服务托管在
host/service
(在我们的例子中,服务将等效于odata前缀),因此通常您发送请求,如host/service/Customers
或/service/Customers
发出批处理请求时,内部请求中的URL可能是绝对的,也可能是相对于主机的。问题在于,在您的请求中,url是相对于服务根而不是主机的ServiceMetadatas
Web API将相对url解释为主机/服务元数据
,而不是主机/服务/服务元数据
,这就是导致错误的原因
根据您的Repo项目,以下请求可以正常工作:
POST http://localhost:6974/odata/$batch HTTP/1.1
Host: localhost:6974
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0
Accept: multipart/mixed
Accept-Language: he-IL,he;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DataServiceVersion: 2.0
Content-Type: multipart/mixed; charset=UTF-8;boundary=batch_4f09-d7cf-dd99
MaxDataServiceVersion: 2.0
Referer: http://localhost:9000/
Content-Length: 565
Origin: http://localhost:9000
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
--batch_4f09-d7cf-dd99
Content-Type: multipart/mixed; boundary=changeset_ca0c-06b7-ddbe
--changeset_ca0c-06b7-ddbe
Content-Type: application/http
Content-Transfer-Encoding: binary
POST odata/ServiceMetadatas HTTP/1.1
Content-ID: 1
DataServiceVersion: 2.0
Accept: application/atomsvc+xml;q=0.8, application/json;odata=verbose;q=0.5, */*;q=0.1
Content-Type: application/json;odata=verbose
MaxDataServiceVersion: 2.0
{"ServiceMetadataId":-1,"ServiceName":"sdf sdf","Description":"sd fgs df"}
--changeset_ca0c-06b7-ddbe--
--batch_4f09-d7cf-dd99--
相关响应如下所示:
HTTP/1.1 202 Accepted
Cache-Control: no-cache
Pragma: no-cache
Content-Type: multipart/mixed; boundary=batchresponse_6779b5e5-6e40-4363-9a98-5a33d062da28
Expires: -1
Server: Microsoft-IIS/8.0
DataServiceVersion: 2.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcamFjYWx2YXJcRG93bmxvYWRzXE9EYXRhQmF0Y2gtbWFzdGVyXENsZWFuV2ViQXBpUHJvamVjdFxvZGF0YVwkYmF0Y2g=?=
X-Powered-By: ASP.NET
Date: Tue, 17 Sep 2013 16:48:50 GMT
Content-Length: 872
--batchresponse_6779b5e5-6e40-4363-9a98-5a33d062da28
Content-Type: multipart/mixed; boundary=changesetresponse_b63ca946-ce66-43e6-a78f-d44a5b8f2d5c
--changesetresponse_b63ca946-ce66-43e6-a78f-d44a5b8f2d5c
Content-Type: application/http
Content-Transfer-Encoding: binary
HTTP/1.1 201 Created
Location: http://localhost:6974/odata/ServiceMetadatas(-1)
Content-ID: 1
Content-Type: application/json; odata=verbose; charset=utf-8
DataServiceVersion: 2.0
{
"d":{
"__metadata":{
"id":"http://localhost:6974/odata/ServiceMetadatas(-1)","uri":"http://localhost:6974/odata/ServiceMetadatas(-1)","type":"CleanWebApiProject.Models.ServiceMetadata"
},"ServiceMetadataId":-1,"ServiceName":"sdf sdf","Description":"sd fgs df"
}
}
--changesetresponse_b63ca946-ce66-43e6-a78f-d44a5b8f2d5c--
--batchresponse_6779b5e5-6e40-4363-9a98-5a33d062da28--
我在控制器中所做的唯一更改如下(与批处理无关):
公共类ServiceMetadatasController:EntitySetController
{
受保护的覆盖ServiceMetadata CreateEntity(ServiceMetadata实体)
{
返回实体;
}
受保护的覆盖int GetKey(ServiceMetadata实体)
{
返回entity.ServiceMetadataId;
}
公共覆盖IQueryable Get()
{
返回新列表
{
新建ServiceMetadata(){ServiceName=“Service1”,Description=“Desc1”},
新建ServiceMetadata(){ServiceName=“Service2”,Description=“Desc1”}
}.AsQueryable();
}
}
我希望这能解决您的问题,如果您是手动为内部请求生成url,或者是breezejs为您生成url,也请告诉我,这样我就可以跟进并确保它得到修复。新答案是。。使用
webApiOData
数据服务代替“OData”:
几点注意事项-看起来您正试图发布类型为X的数据,而服务器期望类型为Y。就配置而言,想想创建和设置您自己的数据库会有多困难。您如何得出类型不同的结论?谢谢查看描述为什么要获得406汉克的部分,但它并没有真正起到帮助作用。问题似乎是OData强制您获得正确的内容类型,或者它抛出了一个406汉克。如果您说您的内容属于任何类型,但服务器接受不同的数据类型,它将抛出406。我以前没有使用过OData,但我猜你要么在Breeze中使用了错误的适配器,要么设置了OData控制器以接受错误的内容类型。这是正确的!!杰出的我仍然要用它来制造微风,我希望它能很快发挥作用。这是你回答问题的最佳时机。我刚想试试OP编辑部分发布的黑客补丁,但是我看到了你的答案。新的数据服务工作得很好。谢谢这对我有用。我建议任何人先试试这个,比这里的任何东西都简单得多。
POST http://localhost:6974/odata/$batch HTTP/1.1
Host: localhost:6974
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0
Accept: multipart/mixed
Accept-Language: he-IL,he;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DataServiceVersion: 2.0
Content-Type: multipart/mixed; charset=UTF-8;boundary=batch_4f09-d7cf-dd99
MaxDataServiceVersion: 2.0
Referer: http://localhost:9000/
Content-Length: 565
Origin: http://localhost:9000
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
--batch_4f09-d7cf-dd99
Content-Type: multipart/mixed; boundary=changeset_ca0c-06b7-ddbe
--changeset_ca0c-06b7-ddbe
Content-Type: application/http
Content-Transfer-Encoding: binary
POST odata/ServiceMetadatas HTTP/1.1
Content-ID: 1
DataServiceVersion: 2.0
Accept: application/atomsvc+xml;q=0.8, application/json;odata=verbose;q=0.5, */*;q=0.1
Content-Type: application/json;odata=verbose
MaxDataServiceVersion: 2.0
{"ServiceMetadataId":-1,"ServiceName":"sdf sdf","Description":"sd fgs df"}
--changeset_ca0c-06b7-ddbe--
--batch_4f09-d7cf-dd99--
HTTP/1.1 202 Accepted
Cache-Control: no-cache
Pragma: no-cache
Content-Type: multipart/mixed; boundary=batchresponse_6779b5e5-6e40-4363-9a98-5a33d062da28
Expires: -1
Server: Microsoft-IIS/8.0
DataServiceVersion: 2.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcamFjYWx2YXJcRG93bmxvYWRzXE9EYXRhQmF0Y2gtbWFzdGVyXENsZWFuV2ViQXBpUHJvamVjdFxvZGF0YVwkYmF0Y2g=?=
X-Powered-By: ASP.NET
Date: Tue, 17 Sep 2013 16:48:50 GMT
Content-Length: 872
--batchresponse_6779b5e5-6e40-4363-9a98-5a33d062da28
Content-Type: multipart/mixed; boundary=changesetresponse_b63ca946-ce66-43e6-a78f-d44a5b8f2d5c
--changesetresponse_b63ca946-ce66-43e6-a78f-d44a5b8f2d5c
Content-Type: application/http
Content-Transfer-Encoding: binary
HTTP/1.1 201 Created
Location: http://localhost:6974/odata/ServiceMetadatas(-1)
Content-ID: 1
Content-Type: application/json; odata=verbose; charset=utf-8
DataServiceVersion: 2.0
{
"d":{
"__metadata":{
"id":"http://localhost:6974/odata/ServiceMetadatas(-1)","uri":"http://localhost:6974/odata/ServiceMetadatas(-1)","type":"CleanWebApiProject.Models.ServiceMetadata"
},"ServiceMetadataId":-1,"ServiceName":"sdf sdf","Description":"sd fgs df"
}
}
--changesetresponse_b63ca946-ce66-43e6-a78f-d44a5b8f2d5c--
--batchresponse_6779b5e5-6e40-4363-9a98-5a33d062da28--
public class ServiceMetadatasController : EntitySetController<ServiceMetadata, int>
{
protected override ServiceMetadata CreateEntity(ServiceMetadata entity)
{
return entity;
}
protected override int GetKey(ServiceMetadata entity)
{
return entity.ServiceMetadataId;
}
public override IQueryable<ServiceMetadata> Get()
{
return new List<ServiceMetadata>
{
new ServiceMetadata() {ServiceName = "Service1", Description = "Desc1"},
new ServiceMetadata() {ServiceName = "Service2", Description = "Desc1"}
}.AsQueryable();
}
}
breeze.config.initializeAdapterInstances({
dataService : 'webApiOData'
});