POSTing JSON to WCF REST Endpoint
I'm working on implementing PUT, POST, and DELETE for my service. But every time I try to send some json up to the server, get the error 'Cannot create an abstract class.' I generated my request data by running an instance of my object through a DataContractJsonSerializer
, adding the __type field, and wrapping it in {"obj": mydata}.
I can run this back through a DataContractJsonSerializer
that expects a BaseObj and it works fine:
{"__type":"RepositoryItem:http:\/\/objects\/","Insert_date":null,"Modified_date":null,"insert_by":null,"last_modify_user_id":null,"modified_by":null, "external_id":"1234","internal_id":54322,"school_id":45,"type_name":0, "vendor_id":57}
My service contract is decorated with a ServiceKnownType
attribute with the RepositoryItem
and BaseObj
included in the list.
I'm POSTing using jquery
$.ajax({
type: "POST",
url: "http://localhost/slnSDK/service.svc/create/repositoryitem.json?t=" + token,
data: data,
success: function(result) {
$("#input").html(result);
},
error: function(xhr, result, err) {
$("#htmloutput").html(xhr.responseText);
},
dataType: "json",
contentType: "application/json"
});
I have the following endpoint exposed:
<OperationContract(Action:=Api2Information.Namespace & "createJson")> _
<WebInvoke(Method:="POST", _
BodyStyle:=WebMessageBodyStyle.Bare, _
RequestFormat:=WebMessageFormat.Json, _
responseFormat:=WebMessageFormat.Json, _
UriTemplate:="/create/{objType}.json?t={token}")> _
Function createJson(ByVal objType As String, ByVal obj As BaseObj, ByVal token As String) As Integer
And the following objects (IBaseObj was omitted as it can be inferred by its implementor)
<DataContract(Namespace:="http://objects/")> _
Public Class RepositoryItem : Inherits BaseObj
' members backing properties have been omitted.
Public Sub New()
...
<DataMember()> _
Public Property type_name() As eType
...
' Override this to expose it as a property on the WebAPI
<DataMember()> _
Public Overrides Property internal_id() As Integer?
...
<DataMember()> _
Public Property external_id() As String
...
<DataMember()> _
Public Property vendor_id() As Integer
...
End Class
<DataContract(Namespace:="http://objects/")> _
<Serializable()> _
Public MustInherit Class BaseObj : Implements IBaseObj
' members backing properties have been omitted.
<DataMember()> _
Public Overridable Property insert_by() As String Implements IBaseObj.Insert_by
...
<DataMember()> _
Public Overridable Property Insert_date() As Nullable(Of Date) Implements IBaseObj.Insert_date
...
<DataMember()> _
Public Overridable Property modified_by() As String Implements IBaseObj.Modified_by
...
<DataMember()> _
Public Overridable Property Modified_date() As Nullable(Of Date) Implements IBaseObj.Modified_date
...
<DataMember()> _
Public Overridable Property last_modify_user_id() As Nu开发者_开发知识库llable(Of Integer) Implements IBaseObj.Last_modify_user_id
...
End Class
Fiddler output from POST:
POST http://localhost/slnSDK/service.svc/create/repositoryitem.json?t= HTTP/1.1
Host: localhost
Connection: keep-alive
Referer: http://localhost/apitest.html
Content-Length: 265
Origin: http://localhost
X-Requested-With: XMLHttpRequest
Content-Type: application/json
Accept: application/json, text/javascript, */*; q=0.01
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.7 (KHTML, like Gecko) RockMelt/0.8.36.79 Chrome/7.0.517.44 Safari/534.7
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: ASP.NET_SessionId=ywyooz45mi3c4d55h4ld4bec; x=lHOtsYBHvS/fKE7JQWzFTw==; y=XhfNVfYYQynJrIZ/odWFOg==
{"obj":{"__type":"RepositoryItem:http:\/\/objects\/","Insert_date":null,"Modified_date":null,"insert_by":null,"last_modify_user_id":null,"modified_by":null, "external_id":"1234","internal_id":54322,"school_id":45,"type_name":0, "vendor_id":57}}
Any help you can provide would be great. Thanks!
Good volume of info, but always a difficult one to debug remotely, a couple of tips:
removed fiddler tip (as I can see you are using it)
In your ajax post:
success: function(result) {
$("#input").html(result);
},
You should be using result.d to get the message contents.
success: function(result) {
$("#input").html(result.d);
},
The insert_by field is null in the debug message, from the fragment it doesn't look like null is acceptable (as String? instead of as String).
精彩评论