Open iwate opened 5 years ago
Hey @iwate, great to meet you. Based on how the specification works, you can't have a POST or a PUT that has child entities in navigation properties. Entities are supposed to be created separately and then LINKed together (though I just usually set the ForeignKeyId manually in my payload without attaching the entity, and it works fine).
Because the current behavior is according to spec, we cannot accept a PR that changes this code.
However, if you wanted to look into Delta payload support, we would probably take a PR for that. Thanks!
Actually, if he's referring to a "deep insert" it was added to the OData spec in version 4.0, see section 11.4.2.1 and 11.4.2.2.
Version 4.1 also included a "deep update" (section 11.4.3.1) which would be interesting to see implemented.
I couldn't find any documentation though on how it's handled in Microsoft.AspNet.Odata or if either is supported, so it still might not be a thing that could be easily implemented.
Ah, I was not aware that 4.0 had a "deep insert" spec.... that wasn't allowed in 3.0. I'll bring it up with Mike when we meet for the OData Show next week, but I don't know that we'd be able to support it without unwanted side effects.
4.01's deep updates are now supported in Microsoft.AspNet.OData, but we won't be supporting them in Restier before 1.0 RTMs (which is hopefully in a couple weeks), as it will likely take quite a bit of effort.
I know that the "changeset" design in Restier was supposed to handle that, but it's really hard for me to get my head around, and has little documentation. We really need to just ship 1.0 so we can scrap the codebase and rebuild the pipeline with modern tools. If the interception pipeline were cleaner, then it would be easier to rip apart simple payloads, deep payloads, and delta payloads, and shove the entities through the pipeline.
Does that make sense?
Makes sense to me. Thanks!
Hi, @robertmclaws , @Tiberriver256
Thank you response:) I'm happy to discuss this issue.
Based on how the specification works, you can't have a POST or a PUT that has child entities in navigation properties.
I'm sorry, I did not read specification enough. I'll read it more!
But, currently, OData v3 can create entity with navigation property (Maybe, this behavior is different from the specification and this is custom by MS) Does RESTier break backwards compatibility of this behavior? (I think it can not helped if it does not exist in specification. but... :_(
## Create request with navigation property
POST https://services.odata.org/V3/(S(steuszrxyxno2iu2ms0yjblm))/OData/OData.svc/Products HTTP/1.1
Content-Type: application/json
Accept: application/json
User-Agent: PostmanRuntime/7.16.3
Cache-Control: no-cache
Postman-Token: e4b62e61-ff2e-4004-83f4-4deb8e9db1b4
Host: services.odata.org
Accept-Encoding: gzip, deflate
Content-Length: 293
Connection: close
{
"odata.type":"ODataDemo.Product",
"ID": 1000,
"Name": "Sample",
"Description": "This is sample",
"ReleaseDate": "2019-09-19",
"Rating": 5,
"Price": 10.00,
"ProductDetail": {
"odata.type": "ODataDemo.ProductDetail",
"ProductID": 1000,
"Details": "this is details of sample"
}
}
HTTP/1.1 201 Created
Cache-Control: no-cache
Content-Length: 265
Content-Type: application/json;odata=minimalmetadata;streaming=true;charset=utf-8
Location: https://services.odata.org/V3/(S(steuszrxyxno2iu2ms0yjblm))/OData/OData.svc/Products(1000)
Server: Microsoft-IIS/10.0
X-Content-Type-Options: nosniff
DataServiceVersion: 3.0;
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Access-Control-Allow-Headers: Accept, Origin, Content-Type, MaxDataServiceVersion
Access-Control-Expose-Headers: DataServiceVersion
Date: Thu, 19 Sep 2019 03:54:53 GMT
Connection: close
{"odata.metadata":"https://services.odata.org/V3/(S(steuszrxyxno2iu2ms0yjblm))/OData/OData.svc/$metadata#Products/@Element","ID":1000,"Name":"Sample","Description":"This is sample","ReleaseDate":"2019-09-19T00:00:00","DiscontinuedDate":null,"Rating":5,"Price":10.0}
## Check request for navigation property - It was created!
GET https://services.odata.org/V3/(S(steuszrxyxno2iu2ms0yjblm))/OData/OData.svc/ProductDetails(1000) HTTP/1.1
Accept: application/json
User-Agent: PostmanRuntime/7.16.3
Cache-Control: no-cache
Postman-Token: 5b323c27-504d-438f-aa53-0092e28da533
Host: services.odata.org
Accept-Encoding: gzip, deflate
Connection: close
HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Length: 185
Content-Type: application/json;odata=minimalmetadata;streaming=true;charset=utf-8
Vary: Accept-Encoding
Server: Microsoft-IIS/10.0
X-Content-Type-Options: nosniff
DataServiceVersion: 3.0;
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Access-Control-Allow-Headers: Accept, Origin, Content-Type, MaxDataServiceVersion
Access-Control-Expose-Headers: DataServiceVersion
Date: Thu, 19 Sep 2019 03:56:45 GMT
Connection: close
{"odata.metadata":"https://services.odata.org/V3/(S(steuszrxyxno2iu2ms0yjblm))/OData/OData.svc/$metadata#ProductDetails/@Element","ProductID":1000,"Details":"this is details of sample"}
Actually, if he's referring to a "deep insert" it was added to the OData spec in version 4.0, see section 11.4.2.1 and 11.4.2.2.
The spec is a bit different from my opinion. (odata.bind seems like operation for many to many relationship. My expected behavior is for one to one.) However, I agree to support the feature!
@iwate I've implemented it by accepting all types of EdmStructuredObject and delegating "postprocessing" materialized objects to convention methods OnDeepInsertXYZ, OnDeepUpdateXYZ etc. I'm not up to date with Restier, but it should still work. @robertmclaws nice to see that Restier is not dead :)
https://github.com/OData/RESTier/blob/301b64c04a93a6dce6c3e95b294339f32fd120ca/src/Microsoft.Restier.AspNet/Extensions/Extensions.cs#L94-L99
I want to create a few entities (1to1 relation) in a request. So I need to use it. Or I want to use navigation post in a batch request.
Either's fine, However both ways are not supported.
May you check it if I create PR? Or, Do you already have any plan and you cannot accept the feature?