1

I'm trying to serialize a dozen or so inputs and post this to a ASP.Net webmethod.

My question is rather than manually deserialize the JSON string and populate the object class can this be done automatically? I'll be receiving a single object not a list of objects.

I've been trying for days to accomplish this with no success, scouring lots of posts and just not finding any obvious examples to this. Sorry if I've overloaded with info just trying to cover everything.

Any help, ideas or direction is appreciated.

JQuery

            function pushOwnerData(formData) {  //formData is array of inputs
            // [used for debug purposes]
            //var test = "{owner: " + JSON.stringify(formData) + "}";
            // JSON.stringify({ formData: formData })
            //{ myOwner: JSON.stringify(formData) },
            // [end debug tinkering]
            var request = $.ajax({
                url: 'records_v1.2.aspx/UpdateOwnerInfo',
                method: "POST",
                data: "{myOwner: " + JSON.stringify(formData) + "}",
                contentType: "application/json; charset=utf-8",
                dataType: "json"
            });
            request.done(function (r) {
                console.log('success');
            });
            request.fail(function (jqXHR, textStatus) {
                console.log("pushOwnerData Request failed: " + textStatus);
            });

        }


        function editOwnerDialog() {
            var ownerDiv = getOwnerContent();
            $(ownerDiv).dialog({   
                modal: true,
                draggable: false,
                resizable: false,
                show: 'fold',
                hide: 'blind',
                width: 500,
                height: 350,
                dialogClass: 'ui-dialog-osx',
                title: "Edit Owner",
                buttons: {
                    "Save Changes": function () {
                        if (validateOwnerData()) {
                            // serialize to an array to be passed to a webmethod
                            var fields = $(".divTableBody").find("select,textarea,input").serializeArray();
                            var id = $('.owner_detail').find('.id').html();
                            fields.push({ name: "id", value: id });
                            // [used for debug purposes]
                            // var jsonFields = JSON.stringify(fields); 
                            // var test = $(".divTableBody").find("select,textarea,input").serialize(); 
                            // var jsonTest = JSON.stringify(test); 
                            // [end debug tinkering]
                            var result = pushOwnerData(fields);
                        } else {
                            return false;
                        }
                    },
                    "Cancel": function () {
                        $(this).dialog("destroy");
                    }
                },
                open: function () {
                    // create a mask for phone class
                    $('#owner_phone').mask("(999) 999-9999");
                },
                close: function () {
                    $(this).dialog("destroy");
                }

            });
        };

Ex of JSON data

[{"name":"prefix","value":""},{"name":"address1","value":"1234 Stone Mountain Rd"},{"name":"first","value":"Amy"},{"name":"address2","value":"Suite 18"},{"name":"middle","value":"Marie"},{"name":"city","value":"atlanta"},{"name":"last","value":"Smith"},{"name":"state","value":"GA"},{"name":"suffix","value":""},{"name":"postalcode","value":"65472"},{"name":"phone","value":"(850) 775-3131"},{"name":"email","value":"baba@hotmail.com"},{"name":"id","value":"2501"}]

Snip of Owner class (properties have same names as json keys)

    Private _id As Integer
    <DataMember()>
    Public Property id() As Integer
        Get
            Return _id
        End Get
        Set(ByVal value As Integer)
            _id = value
        End Set
    End Property

    Private _last As String
    <DataMember()>
    Public Property last() As String
        Get
            If Not _last = "" Then
                _last = Microsoft.VisualBasic.StrConv(_last, VbStrConv.ProperCase)
            End If
            Return _last
        End Get
        Set(ByVal value As String)
            _last = value
        End Set
    End Property

    Private _first As String
    <DataMember()>
    Public Property first As String
        Get
            If Not _first = "" Then
                _first = Microsoft.VisualBasic.StrConv(_first, VbStrConv.ProperCase)
            End If
            Return _first
        End Get
        Set(ByVal value As String)
            _first = value
        End Set
    End Property

Webmethod trying to populate my owner class without having to include all properties as method variables (ByVal first as string, ...etc), is this possible?

I've tried (ByVal myOwner as List(of Owner)) also which gets the method called but I end up with a list of empty objects the length of the JSON variables

    <WebMethod()> _
Public Shared Function UpdateOwnerInfo(ByVal myOwner As Owner) As String
    Dim result As Boolean = False
    'ToDo
    Return result
End Function
  • Try wrapping myowner in double quotes like `data: "{\"myOwner\": " + JSON.stringify(formData) + "}",`. Also, in webmethod the input argument datatype should be `List(Of Owner)`or IEnumerable(Of Owner)` – Mohsin Mehmood Jun 08 '18 at 15:37
  • I appreciate the response @Mohsin, I've still got something wrong and end up with 12 Owner classes with properties that are empty. Any idea's? New JSON string looks like `{"myOwner": [{"name":"prefix","value":""},{"name":"address1"...` – John Shepherd Jun 08 '18 at 22:09
  • For testing, you can create a new class with only two properties `name` and `value` and then change the argument datatype to ListOf that new class. See if that helps – Mohsin Mehmood Jun 08 '18 at 22:13
  • I'm getting lost with ListOf because it's a single object with 13 properties, not a list of objects. When I change the webmethod as suggested with ListOf I'm ending up with a ListOf objects the exact same length of the amount of keys I'm sending in the JSON string and all objects are empty. Seems like it's the format of the JSON that's coming from the stringify function causing it not to deserialize into the object properly. – John Shepherd Jun 09 '18 at 17:44
  • Have you tried creating a new class with only two properties as suggested in my previous comment? – Mohsin Mehmood Jun 09 '18 at 18:25
  • Yes I did and even went further, created a whole new page to isolate the test. I hardcoded an object with two properties `var formData= { firstName: 'John', lastName: 'Doe' };` and named the properties of the class same as the key names. Using a webmethod without ListOf and it populates the class properties right. So I'm thinking it's the way the serializeArray() function creates the `{"name":"","value":""}` pairs that's not allowing the proper deserialization. As if i need a JSON string that looks like `{"formData":{"firstName":"John","lastName":"Doe"}}`. Does that make sense? – John Shepherd Jun 09 '18 at 18:41
  • Forgot I also change the data param of the ajax call to `data: JSON.stringify({ formData: formData }),` – John Shepherd Jun 09 '18 at 18:46
  • So one more suggestion, try changing the datatype of your webmethod parameter to be an array of `Owner` class or your newly created class like `Public Shared Function UpdateOwnerInfo(ByVal myOwner() As Owner) As String` – Mohsin Mehmood Jun 09 '18 at 19:01
  • Ok tried that, changing back to a .serializeArray() function giving a stringify string of `{"formData":[{"name":"firstName","value":"John"},{"name":"lastName","value":"Doe"}]}` and I end up with an array of empty Owner objects. Almost seems like I can't use the jQuery.serializeArray() function and instead build an object from my inputs with key's that match the classes property names so I have `{"firstName":"John","lastName":"Doe"}}` format stringify. Thanks again for your input, I've been struggling with this for days. – John Shepherd Jun 09 '18 at 19:18

1 Answers1

0

From what I can conclude it's the resulting format from JQuery.serializeArray() that results in a [{"name":"firstName","value":"John"},{"name":"lastName","value":"Doe"}] name : value key pair format which is rejected by the webmethod.

The webmethod seems to consume a format only where the key is the type property name ie: {"firstName":"John","lastName":"Doe"} this works and populates my class without issue.

I stumbled across another post here Stackoverflow Link that someone provided a format function that will convert a $('#mydiv').serialize() into a json string that can be consumed by the webmethod. Not sure if there's a better way or if my inexperience resulted in pushing a square block through a round hole but this worked for me.

Full disclosure:

HTML

<form id="form1" runat="server">
<div class="myForm">
    First name: <input type="text" class="first" name="firstName" />
    Last name: <input type="text" class="last" name="lastName" />
</div>
<button id="go">
    Go</button>
</form>

JQuery

jQuery(document).ready(function ($) {


    $("#go").click(function () {
        //var formData = { firstName: 'John', lastName: 'Doe' };
        var formData = $(".myForm").find("input").serialize();
        pushOwnerData(formData);
    });

    function pushOwnerData(formData) { 
        var json1 = "{\"formData\":" + toSimpleJson(formData) + "}";    
        var request = $.ajax({
            url: 'testJSON.aspx/UpdateOwnerInfo',
            method: "POST",
            data: json1,
            contentType: "application/json; charset=utf-8",
            dataType: "json"
        });
        request.done(function (r) {
            alert('success');
        });
        request.fail(function (jqXHR, textStatus) {
            alert("pushOwnerData Request failed: " + textStatus);
        });

    }


    function toSimpleJson(serializedData) {
        var ar1 = serializedData.split("&");
        var json = "{";
        for (var i = 0; i < ar1.length; i++) {
            var ar2 = ar1[i].split("=");
            json += i > 0 ? ", " : "";
            json += "\"" + ar2[0] + "\" : ";
            json += "\"" + (ar2.length < 2 ? "" : ar2[1]) + "\"";
        }
        json += "}";
        return json;
    }
});

Webmethod

Imports System.Data
Imports System.Web.Services
Imports System.Configuration
Imports System.Data.SqlClient

Partial Class testJSON
    Inherits System.Web.UI.Page

        <WebMethod()> _
        Public Shared Function UpdateOwnerInfo(ByVal formData As OwnerTest) As String
            Dim result As Boolean = False

            Return result
        End Function
End Class

Simple class

Public Class OwnerTest
    Public Property firstName As String
    Public Property lastName As String
End Class