Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

jquery - WCF not deserializing JSON input

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

it's hard to tell from just the detail you've provided.

Here is what I suggest:

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! :)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...