Reputation: 163
I'm trying to send a complex data type from one process to another using ASP.net MVC. For some reason the receiving end always receives blank (zero/default) data.
My sending side:
static void SendResult(ReportResultModel result)
{
//result contains valid data at this point
string portalRootPath = ConfigurationManager.AppSettings["webHost"];
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(portalRootPath);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage resp = client.PostAsJsonAsync("Reports/MetricEngineReport/MetricResultUpdate", result).Result;
if (!resp.IsSuccessStatusCode) {
//I've confirmed this isn't happening by putting a breakpoint in here.
}
}
My receiving side, in a different class, running in a different process on my local machine:
public class MetricEngineReportController : Controller
{
...
[HttpPost]
public void MetricResultUpdate(ReportResultModel result)
{
//this does get called, but
//all the guids in result are zero here :(
}
...
}
My model is a bit complicated:
[Serializable]
public class ReportResultModel
{
public ReportID reportID {get;set;}
public List<MetricResultModel> Results { get; set; }
}
[Serializable]
public class MetricResultModel
{
public Guid MetricGuid { get; set; }
public int Value { get; set; }
public MetricResultModel(MetricResultModel other)
{
MetricGuid = other.MetricGuid;
Value = other.Value;
}
public MetricResultModel(Guid MetricGuid, int Value)
{
this.MetricGuid = MetricGuid;
this.Value = Value;
}
}
[Serializable]
public struct ReportID
{
public Guid _topologyGuid;
public Guid _matchGuid;
}
Any idea why the data's not arriving? Any help would be much appreciated...
P.S. For some reason I can't seem to catch the http POST message on fiddler, not sure why that is.
Upvotes: 1
Views: 5206
Reputation: 9437
I just had the same problem. It seems that the content-length
header is set to 0 when using the default PostAsJsonAsync
extension method, which causes the server to ignore the request body.
My solution was to install the System.Net.Http.Json
nuget package that uses the new System.Text.Json
serializer.
When you add using System.Net.Http.Json;
, you should be able to use the new extension method PostAsJsonAsync
that works (sets the content-length
header) properly.
namespace System.Net.Http.Json
{
public static class HttpClientJsonExtensions
{
public static Task<HttpResponseMessage> PostAsJsonAsync<TValue>(this HttpClient client, string? requestUri, TValue value, CancellationToken cancellationToken)
{
return client.PostAsJsonAsync(requestUri, value, null, cancellationToken);
}
}
}
Upvotes: 1
Reputation: 163
The problem was twofold:
I needed to specify the type in my JSON post like this:
HttpResponseMessage resp = client.PostAsJsonAsync<MetricResultModel>("Reports/MetricEngineReport/MetricResultUpdate", result.Results[0]).Result;
The components of my model did not have default constructors, which is necessary for the JSON deserialization on the receiving end.
Upvotes: 2
Reputation: 77
Try using "[FromBody]" parameter in Controller's Action. As you post data is passed to body not in url.
[HttpPost]
public void MetricResultUpdate([FromBody] ReportResultModel result)
{
//this does get called, but
//all the guids in result are zero here :(
}
Upvotes: 6