Q: ASP.NET Core MVC 2: NameValueCollection instance is empty on the server side This is client code:
public class Class1
{
    static void Main()
    {
        string data = "Some big string...";
        Work(data);

        Console.WriteLine("Press any key for exit...");
        Console.ReadKey();
    }

    async static void Work(string data)
    {
        var guid = Guid.NewGuid();
        Uri uri = new Uri("http://localhost:61698/Home/Task/" + guid.ToString());

        using (Stream s = StringToStream(data))
        {
            var report = await PostStream(uri, guid, s);
        }
    }

    public static Stream StringToStream(string s)
    {
        MemoryStream stream = new MemoryStream();
        StreamWriter writer = new StreamWriter(stream);
        writer.Write(s);
        writer.Flush();
        stream.Position = 0;
        return stream;
    }

    async static Task<byte[]> PostStream(Uri uri, Guid guid, Stream stream)
    {
        try
        {
            using (StreamReader sr = new StreamReader(stream))
            {
                string text = await sr.ReadToEndAsync();

                var host = Dns.GetHostEntry(Dns.GetHostName());

                IPAddress ip = null;

                foreach (var item in host.AddressList)
                {
                    if (item.AddressFamily == AddressFamily.InterNetwork)
                    {
                        ip = item;
                    }
                }

                var client = new WebClient();

                var values = new NameValueCollection();
                values.Add("Guid", guid.ToString());
                values.Add("IP", ip.ToString());
                values.Add("Data", text);

                var bytes = await client.UploadValuesTaskAsync(uri, values);
                return bytes;
            }
        }
        catch(Exception err)
        {
            Console.Error.WriteLine(err.Message);
            return null;
        }
    }
}

This is controller on the server side:
public class HomeController : Controller
{
    [HttpGet]
    public IActionResult Task(Guid id)
    {
        return Ok();
    }

    [HttpPost]
    public IActionResult Task(NameValueCollection data)
    {
        if (ModelState.IsValid)
        {
            var count = data.Count; // 0
            return Ok();
        }
        else
        {
            return BadRequest();
        }
    }
}

In debug mode I see that NameValueCollection on the server side is empty. Why does it happen & how can I fix it?

A: UploadValuesTaskAsync() sends request in form-urlencoded format:

Content-Type: application/x-www-form-urlencoded
Guid=660d9902-2293-43eb-906f-374adf77a9d6&IP=192.168.100.3&Data=Some+big+string...

Form data is bound to action parameters matched by name. So if your controller has following signature:
[HttpPost]
public IActionResult Task(Guid guid, string ip, string data)

guid, ip and data will be bound correctly to values from request.
If you want to change this behavior and deserialize request data to NameValueCollection, you could try marking action parameter with FromBody attribute:
[HttpPost]
public IActionResult Task([FromBody] NameValueCollection data)

Ufortunatelly, this will give you 415 Unsupported Media Type response. This happens because ASP.NET Core supports only JSON and XML media type formatters out of the box.
You have to add custom media type formatter to make this work. Quick search brought this project on Github. I haven't tried it but at least you could get the idea how to implement it.
