alwaysVBNET alwaysVBNET - 2 months ago 7
jQuery Question

Pass multiple objects from Ajax to WebMethod

I am passing information from my

form
to my
WebMethod
. The goal is to populate the
UseInfo
object with the data from the form and also populate some properties I have added on the
NewUser
class which are also passed from the ajax request.

When I have as an input parameter the
UserInfo
, the object populates successfully after the ajax post. However, if I have the NewUser object, only the property
Relationship
gets populated but the
UserInfo
object appears as Nothing.

Any ideas what I'm doing wrong? Do I need to give a different structure to my class
NewUser
?

NewUser class

Public Class NewUser

Public Property UserInfo As UserInfo
Get
Return _UserInfo
End Get
Set(value As UserInfo)
_UserInfo = value
End Set
End Property
Private _UserInfo As UserInfo

Public Property Relationship As String
Get
Return m_Relationship
End Get
Set(value As String)
m_Relationship = value
End Set
End Property
Private m_Relationship As String

End Class


WebMethod

<HttpPost>
<ValidateAntiForgeryToken>
<DnnModuleAuthorize(AccessLevel:=SecurityAccessLevel.View)>
Public Function AddUserDependant(<FromBody> oNewUser As NewUser) As HttpResponseMessage
Try
If Me.UserInfo.IsInRole("Carer") Then
UsersControllerOmni.CreateDnnUser(oNewUser.UserInfo)

Return Request.CreateResponse(HttpStatusCode.OK)
Else
Return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "")
End If
Catch ex As Exception
Return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex)
End Try

End Function


AJAX

$.ajax({
type: "POST",
cache: false,
url: serviceUrl + "/ModuleTask/AddUserDependant",
beforeSend: sf.setModuleHeaders,
contentType: "application/json; charset=utf-8",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: $("form").serialize()
}).done(function (result) {


}).fail(function (xhr, result, status) {
alert(result);
});

Answer

The problem is that you are sending and encoded form string to your WebAPI service with the $("form").serialize(). This will convert the form to a string "field1=value1&field2=value2&field3=value3" to an object on your WebAPI request. So .NET will try to convert that to a simple object.

In order to get your request to fit into the object you have, I would suggest changing your ajax to send content type 'json'.

Then add a method to control the form serialization to the client object.

$.ajax({
      type: "POST",
      cache: false,
      url: serviceUrl + "/ModuleTask/AddUserDependant",
      beforeSend: sf.setModuleHeaders,
      contentType: "application/json; charset=utf-8",
      dataType: 'json',
      data: $('form').serializeUserRequest()
}).done(function (result) {
}).fail(function (xhr, result, status) {
      alert(result);
});

Notice the custom function, serializeUserRequest(), that produces the json request object that matches the server-side WebAPI parameter.

$.fn.serializeUserRequest = function()
{
    var requestObj = { "UserInfo": {}, "Relationship": {} };
    var formData = this.serializeArray();
    $.each(formData , function(i, fd) {
        if (fd.name.indexOf("rel_") == 0) {
          var fld = fd.name.substring(4);
          requestObj.Relationship[fld] = fd.value;
        } else {
          requestObj.UserInfo[fd.name] = fd.value;
        }
    });
    return requestObj;
};

For this to work, my assumption is that you make your form field names the same as the UserInfo/Relationship object properties (IE: "DisplayName", "FirstName", etc). Also, in order to split the form attributes between those two root objects, I added "rel_" to the fields that map to the Relationship object and all other field names will map to the UserInfo.

Example:

<input type="text" name="rel_Name" maxlength="50" size="50"/>
Comments