2
votes

I am attempting to pass a complex object to ServiceStack, using a jQuery AJAX call to a GET request.

Code appears below:

Model:

public class Filter
{
    #region constructors

    public Filter()
    {
    }

    #endregion

    #region properties

    [AutoIncrement]
    [PrimaryKey]
    public int ID { get; set; }
    public bool? Huddles { get; set; }
    public List<Activity> Activities { get; set; }
    public string[] Looker { get; set; }
    public string LookerGender { get; set; }
    public string[] Lookee { get; set; }
    public string LookeeGender { get; set; }
    public DateTime? MinDate { get; set; }
    public DateTime? MaxDate { get; set; }
    public bool? ASAP { get; set; }
    [References(typeof(ZipCode))]
    public int? ZipCode { get; set; }
    public int? Radius { get; set; }

    #endregion
}

Service:

[Route("/v1/upfors/search")]
public class SearchUpFors 
{
    public Filter Filter { get; set; }
}

public class UpForService : Service
{
    public List<UpForView> Get(SearchUpFors request)
    {
        OrmLiteConfig.DialectProvider = MySqlDialect.Provider;
        string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["ufsbe"].ConnectionString;
        using (IDbConnection db = connectionString.OpenDbConnection())
        {
            //TO DO
            //Build where clause based on filter properties
            List<UpForView> allUpFors;
            //If Activity(ies) selected, get filtered list
            if (request.Filter.Activities.Count > 0)
            {
                string[] activityNames = new string[request.Filter.Activities.Count];
                int i=0;
                foreach (Activity activity in request.Filter.Activities)
                {
                    activityNames[i] = activity.Name;
                    i++;
                }
                allUpFors = db.Select<UpForView>(q => Sql.In(q.Activity, activityNames));
            }
            else
                allUpFors = db.Select<UpForView>();
            return allUpFors;
        }
    }

}

Client-side Code: This populates the complex object and passes it to the ServiceStack service as JSON.

    $('#frmFilter').submit(function (e) {
        e.preventDefault();
        var data = {};
        var activities = [];
        $('#ddlActivity :selected').each(function (i, selected) {
            activities.push({ ID: $(selected).val(), Name: $(selected).text() });
        });
        data["Activities"] = activities;
        data["ZipCode"] = $('#txtZipCode').text();
        data["Radius"] = $('#txtRadius').text();
        $.ajax({
            url: "service url here",
            type: "GET",
            data: "{'Filter':" + JSON.stringify(data) + "}",
            contentType: "application/json",
            dataType: "xml"
        });
    });

THE ISSUE:

The object gets created in the service, but all properties of request.Filter are null, even the Activities object.

Any advice would be greatly appreciated...

1
Sending complex objects in a HttpGet request is troublesome, try using a HttpPost request.Wim
I agree with @Wim. Normally if you are using your own service then make the object simple or use post. You can use complex object too but from client send simple object and then map with complex object on server end that will make your work little easier. Let me know if you need more details.kunjee

1 Answers

1
votes

SerivceStack is expecting you to send your complex type formatted in JSV not JSON.

You can either format the request in JSV instead of JSON with something like JSV.js from the ServiceStack project or implement your own Request Binder to deserialize the JSON.

public override void Configure(Container container)
{
    RequestBinders.Add(typeof (SearchUpFors), (IHttpRequest httpReq) => {
        var filter = JsonSerializer.DeserializeFromString<Filter>(httpReq.QueryString.Get("Filter"));
        return new SearchUpFors {Filter = filter};
     });
}