Reputation: 29710
I have a WCF service defined as follows:
Imports System.ServiceModel
Imports System.ServiceModel.Web
<ServiceContract()>
Public Interface ILayoutService
<OperationContract()>
<WebInvoke(Method:="POST",
BodyStyle:=WebMessageBodyStyle.WrappedRequest,
RequestFormat:=WebMessageFormat.Json,
ResponseFormat:=WebMessageFormat.Json)>
Sub SaveLayout(ByVal layout As Layout)
<OperationContract()>
Function GetLayout() As Layout
End Interface
The Layout
class is defined as:
Imports System.Runtime.Serialization
<DataContract()>
Public Class Layout
<DataMember()>
Public Property Columns As New List(Of ContentColumn)
End Class
<DataContract()>
Public Class ContentColumn
<DataMember()>
Public Property Name As String = "Column Name"
<DataMember()>
Public Property Position As Integer
<DataMember()>
Public Property Modules As New List(Of ContentModule)
End Class
<DataContract()>
Public Class ContentModule
<DataMember()>
Public Property Name As String = "Module Name"
<DataMember()>
Public Property Position As Integer
End Class
The implementation of ILayoutService is as follows:
Imports System.ServiceModel.Activation
Imports System.Web.Script.Serialization
<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Required)>
Public Class LayoutService
Implements ILayoutService
Public Sub SaveLayout(ByVal layout As Layout) Implements ILayoutService.SaveLayout
Dim l As New Layout
Dim left, center, right As New ContentColumn
left.Name = "Left Column"
left.Position = 0
center.Name = "Center Column"
center.Position = 1
right.Name = "Right Column"
right.Position = 2
Dim topLeft, centerLeft, bottomLeft, topCenter, centerCenter, bottomCenter, topRight, centerRight, bottomRight As New ContentModule
topLeft.Name = "Top Left"
topLeft.Position = 0
centerLeft.Name = "Center Left"
centerLeft.Position = 1
bottomLeft.Name = "Bottom Left"
bottomLeft.Position = 2
topCenter.Name = "Top Center"
topLeft.Position = 0
centerCenter.Name = "Center Center"
centerCenter.Position = 1
bottomCenter.Name = "Bottom Center"
bottomCenter.Position = 2
topRight.Name = "Top Right"
topRight.Position = 0
centerRight.Name = "Center Right"
centerRight.Position = 1
bottomRight.Name = "Bottom Right"
bottomRight.Position = 2
left.Modules.Add(topLeft)
left.Modules.Add(centerLeft)
left.Modules.Add(bottomLeft)
center.Modules.Add(topCenter)
center.Modules.Add(centerCenter)
center.Modules.Add(bottomCenter)
right.Modules.Add(topRight)
right.Modules.Add(centerRight)
right.Modules.Add(bottomRight)
l.Columns.Add(left)
l.Columns.Add(center)
l.Columns.Add(right)
Dim json As New JsonResult
json.Data = l
Dim serializer As New JavaScriptSerializer
Dim output = serializer.Serialize(json.Data)
End Sub
Public Function GetLayout() As Layout Implements ILayoutService.GetLayout
Dim l As New Layout
Dim c As New ContentColumn
Dim m As New ContentModule
c.Modules.Add(m)
l.Columns.Add(c)
Return l
End Function
End Class
I implemented SaveLayout()
so I can get the literal JSON that would be (de)serialized. I'm using that to test invoking this service via jQuery:
$(document).ready(function () {
$("#saveLayout").click(function () {
var layout = buildLayout();
var jsonLayout = $.toJSON(layout);
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
url: "/Services/LayoutService.svc/SaveLayout",
data: jsonLayout,
dataType: "json",
success: function (result) {
alert(result.d.Columns[0].Name);
},
error: function (xhr, ajaxOptions, thrownError) {
var jsonFault = JSON.parse(xhr.responseText);
alert(jsonFault.Message);
}
});
return false;
});
});
function buildLayout() {
var layout = { "Columns": [
{ "Name": "Left Column", "Position": 0, "Modules": [
{ "Name": "Top Left", "Position": 0 },
{ "Name": "Center Left", "Position": 1 },
{ "Name": "Bottom Left", "Position": 2}]
},
{ "Name": "Center Column", "Position": 1, "Modules": [
{ "Name": "Top Center", "Position": 0 },
{ "Name": "Center Center", "Position": 1 },
{ "Name": "Bottom Center", "Position": 2}]
},
{ "Name": "Right Column", "Position": 2, "Modules": [
{ "Name": "Top Right", "Position": 0 },
{ "Name": "Center Right", "Position": 1 },
{ "Name": "Bottom Right", "Position": 2}]
}]
};
return layout;
}
The layout returned by buildLayout()
is the exact JSON returned by the serialize()
call in the VB code. For some reason, when I invoke the web service, the input parameter layout
in SaveLayout()
is Nothing. Something must be failing on deserialization. Any idea why?
Upvotes: 1
Views: 1748
Reputation: 1918
it's hard to tell from just the detail you've provided.
Here is what I suggest:
Enable tracing on the service side, generate tracing logs, and analyze with SvcTraceViewer. To do this, follow the instructions at this MSDN article on using the service trace viewer.
Turn on debug exceptions. This is done by turning in includeExceptionDetailInFaults, which you can do by following the instructions here.
Use Fiddler to monitor the wire traffic on both the client side and the service side.
Generally, once you do this, you should plenty of more info on what's going funky at the service side and can diagnose the issue pretty quickly. Try it, and please report back! :)
Upvotes: 1