I'm looking to send complex objects to my .NET Core API without FromBody tags.
What I am looking to do is simple with JQuery, but I can't figure out for the life of me how to duplicate the logic from a C# Web API Client.
For the sake of testing, I have a fairly simple object.
[Serializable]
public class FilterModel
{
public int? PageSize { get; set; }
public int Page { get; set; }
}
For the sake of testing, we also have an extremely simple controller method
[HttpPost("TEST")]
public virtual int GetTEST(Common.FilterModel filter, Common.FilterModel filter2)
{
return ((filter.Page * filter.PageSize ?? 0) + (filter2.Page * filter2.PageSize ?? 0));
}
Obviously the use case for the code would me more complex, but I am just trying to get the values at this time.
The JQuery to call this method is fairly straight forward and works flawlessly:
var myData = {"filter":{"pageSize":3,"page":2},
"filter2":{"pageSize":19,"page":1}};
$.ajax({
type: 'POST',
url: '/api/Authentication/TEST',
data: myData
}).done(function (data, statusText, xhdr) {
JsonResponse = data;
console.log(data);
}).fail(function (xhdr, statusText, errorText) {
//console.log(JSON.stringify(xhdr));
});
But trying to duplicate that logic from an HttpClient results in 0; the model is always empty when received on the API side. I've tried a few different methods, from JSON Serializing an ArrayList/Dictionary to what I'm adding below, but I'm hitting a dead end unsure where I went wrong.
HttpClient client = new HttpClient
{
BaseAddress = new Uri("http://localhost:65447/")
};
ApiCommon.FilterModel filter = new ApiCommon.FilterModel()
{
PageSize = 10,
Page = 1
};
ApiCommon.FilterModel filter2 = new ApiCommon.FilterModel()
{
PageSize = 9,
Page = 41
};
MultipartFormDataContent mpContent = new MultipartFormDataContent();
StringContent content = new StringContent(JsonConvert.SerializeObject(filter));
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
mpContent.Add(content, "filter");
content = new StringContent(JsonConvert.SerializeObject(filter2));
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
mpContent.Add(content, "filter2");
var retval =
JsonConvert.DeserializeObject<int>(
client.PostAsync("/api/Authentication/TEST", mpContent)
.Result.Content.ReadAsStringAsync().Result);
Console.WriteLine(retval);
Is there any way to imitate the JQuery call to work through an HttpClient? Am I missing something critical here?
EDIT: After getting fiddler to pick it up, this is the raw data for each, I am going to try to match this with my changes.
JQuery fiddler
ePOST http://localhost:65447/api/Authentication/TEST HTTP/1.1
Host: localhost:65447
Connection: keep-alive
Content-Length: 86
Accept: */*
Origin: http://localhost:65447
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://localhost:65447/TestHarness
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
filter%5BpageSize%5D=3&filter%5Bpage%5D=2&filter2%5BpageSize%5D=19&filter2%5Bpage%5D=1
C# fiddler
POST http://local.dev:65447/api/Authentication/TEST HTTP/1.1
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/json; charset=utf-8
Host: local.dev:65447
156
{"filter":{"<IncludeFullData>k__BackingField":false,"<SortBy>k__BackingField":"","<PageSize>k__BackingField":10,"<Page>k__BackingField":1,"<Operation>k__BackingField":""},"filter2":{"<IncludeFullData>k__BackingField":false,"<SortBy>k__BackingField":"","<PageSize>k__BackingField":9,"<Page>k__BackingField":41,"<Operation>k__BackingField":""}}
0