I am trying to post an complex object which include several list/arrays of strings, via an jQuery ajax call. Only the scalar properties of the object seems to get mapped, not the arrays.
I've done some searching around, but cannot find any examples or solutions to this exact scenario.
web API method:
[HttpPost]
public IHttpActionResult Save(MenuSearchGuideEntry model)
{
//Do stuff
return Ok("");
}
MenuSearchGuideEntry object:
[Table("MENUSOEGNING_GUIDE")]
public class MenuSearchGuideEntry
{
[Key]
[Column("RAEKKEID")]
[Display(Name="Række id")]
public Decimal RowId { get; set; }
[Display(Name = "Label id")]
[Column("LABELID")]
public int? LabelId { get; set; }
[Column("ACTION")]
[Display(Name = "Action")]
public string JsonAction { get; set; }
[Column("FORCESEARCH")]
[Display(Name = "Tving søgning")]
public bool ForceSearch { get; set; }
[Column("ORD")]
[Display(Name = "Søgeord")]
public string SearchKeysString { get; protected set; }
public List<string> SearchKeys
{
get
{
return ToStringList(SearchKeysString, ' ');
}
set
{
SearchKeysString = value.Aggregate<string>((a, b) => a + " " + b);
}
}
[Column("SKJULTEFIRMAER")]
[Display(Name = "Skjulte firmaer")]
public string HiddenCompaniesString { get; protected set; }
public List<string> HiddenCompanies
{
get
{
return ToStringList(HiddenCompaniesString, ' ');
}
set
{
HiddenCompaniesString = value.Aggregate<string>((a, b) => a + " " + b);
}
}
[Column("SKJULTEDOMAENER")]
[Display(Name = "Skjulte domæner")]
public string HiddenDomainsString { get; protected set; }
public List<string> HiddenDomains
{
get
{
return ToStringList(HiddenDomainsString, ' ');
}
set
{
HiddenDomainsString = value.Aggregate<string>((a, b) => a + " " + b);
}
}
[Column("PRIORITET")]
[Display(Name = "Prioritet")]
public int? Priority { get; set; }
private List<string> ToStringList(string separatedString, char separator)
{
return string.IsNullOrEmpty(separatedString)
? new List<string>()
: eparatedString.Split(separator).ToList();
}
}
jQuery Ajax call:
function ajaxPost(data, url, redierctUrl) {
$.ajax({
url: url,
data: JSON.stringify(data),
type: 'POST',
contentType: 'application/json',
success: function () {
window.location.href = redierctUrl;
},
error: function (msg) {
}
});
}
object posted via Ajax:
{
"RowId":"1920",
"priority":"",
"labelId":"9999",
"forcesSearch":"False",
"jsonAction":"KBA TEST",
"SearchKeys":["ZZZ","YYY","XXX"],
"HiddenDomains":["VAU","THG","MEK",""],
"HiddenCompanies":["MGM"]
}
I've played around with this a bit. I believe what is happening is that Wep Api
uses the getter
of the List<string>
properties (getting a new empty list) and then adding strings to the list. Once Web Api
is done adding the strings to the list, the list is just left without references and gets garbage collected. The setter
does not seem to get called.
If you don't want to change you model to actually have real List<string>
members, then you can get around this by returning null
instead of new List<string>
from the ToStringList
method. Then, when Web API
uses the getter and gets null, it will call the setter later on.
Still, I think you'd be well advised to store the SearchKeys
etc in real List<string>
members in the class, and then instead have a property that returns the contents of the list as space separated words:
[Column("ORD")]
[Display(Name = "Søgeord")]
public string SearchKeysString { get { return SearchKeys.Aggregate<string>((a, b) => a + " " + b); } }
public List<string> SearchKeys { get; set; }