HttpPost [FromForm]始终包含null

时间:2018-06-28 11:16:05

标签: c# json asp.net-core

我无法从C#桌面应用程序的IActionResult(ASP.NET Core 2)中绑定[FromForm]。

在我的C#桌面应用程序中,我有以下代码:

b0417C3

我的统计信息课有:

private void SendStats ( object state )
{
    double aCpu = ( ( double )AppDomain.CurrentDomain.MonitoringTotalProcessorTime.Ticks / this.totalRunningTime.Ticks ) * 100;
    double aMemory = ( double )AppDomain.MonitoringSurvivedProcessMemorySize / 1048576;
    string version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();

    Stats anStats = new Stats( this.ID, aCpu, aMemory, version );

    using ( WebRequestHandler handler = new WebRequestHandler() )
    {
        using ( HttpClient client = new HttpClient( handler ) )
        {
            client.BaseAddress = new Uri( STATS_SERVER_URL );
            client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue( "application/json" ) );

            try
            {
                var content = new StringContent( anStats.ToJSONString(), Encoding.UTF8, "application/x-www-form-urlencoded" );

                using ( HttpResponseMessage response = client.PostAsync( STATS_SERVER_URL, content ).Result )
                {
                    if ( response.IsSuccessStatusCode )
                    {
                        // Do nothing
                    }
                } 
            }
            catch ( System.AggregateException ax )
            {
                if ( !( ax.InnerException is HttpRequestException ) )
                    throw;
            }
        }
    }

    this.totalRunningTime += STATS_COLLECTION_PERIOD;
}

在我的ASP.NET Core 2应用程序中,我具有以下代码:

using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.IO;

namespace MyNamespace.Stats
{
    [DataContract]
    public class Stats
    {
        [DataMember]
        private string id;

        [DataMember]
        private double cpu;

        [DataMember]
        private double mem;

        [DataMember]
        private string version;

        public Stats ( string anId, double aCpu, double aMemory, string aVersion )
        {
            this.id = anId;
            this.cpu = aCpu;
            this.mem = aMemory;
            this.Version = aVersion;
        }

        public string ToJSONString ()
        {
             DataContractJsonSerializer aSerializer = new DataContractJsonSerializer ( typeof( Stats ) );

             using ( MemoryStream aMemStream = new MemoryStream() )
             {
                 aSerializer.WriteObject( aMemStream, this );

                 aMemStream.Position = 0;

                 using ( StreamReader aStreamReader = new StreamReader ( aMemStream ) )
                 {
                      return aStreamReader.ReadToEnd();
                 }
            }
       }
   }
}

最后,LegacyStatViewModel具有以下代码:

[HttpPost("{productKey}")]
[Consumes("application/x-www-form-urlencoded")]
public IActionResult Create(string productKey, [FromForm] LegacyStatViewModel item)
{
    NewUsageViewModel aNewUsageViewModel = new NewUsageViewModel
    {
        Cpu = Convert.ToInt32(item.Cpu),
        BinaryVersion = (item.Version == null ? "UNKNOWN" : item.Version),                
        LastConnection = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
        Memory = Convert.ToInt32(item.Mem),
        ProductKey = productKey               
    };

    _context.AspNetNewUsages.Add(aNewUsageViewModel);
    _context.SaveChanges();

    return CreatedAtRoute("GetStat", new { ProductKey = aNewUsageViewModel.ProductKey }, item);
}

IActionResult在桌面应用程序中称为正确。 ProductKey参数具有期望值,但所有项目字段均为null或0。

注意:我无法修改桌面应用程序。

1 个答案:

答案 0 :(得分:1)

  

我无法修改桌面应用程序。

客户端正在发送错误数据。

说它正在发送表单数据,但发送JSON。

由于客户端无法更改,服务器将需要从请求的主体中获取原始数据并进行相应的解析。 (这是设计不良的IMO,因为您现在已经失去了内置框架功能的优势。)

[HttpPost("{productKey}")]
public IActionResult Create(string productKey, [FromBody] string rawData ) {
    LegacyStatViewModel item = JsonConvert.DeserializeObject<LegacyStatViewModel>(rawData);
    if(item != null){
        NewUsageViewModel aNewUsageViewModel = new NewUsageViewModel {
            Cpu = Convert.ToInt32(item.Cpu),
            BinaryVersion = (item.Version == null ? "UNKNOWN" : item.Version),                
            LastConnection = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
            Memory = Convert.ToInt32(item.Mem),
            ProductKey = productKey               
        };

        _context.AspNetNewUsages.Add(aNewUsageViewModel);
        _context.SaveChanges();

        return CreatedAtRoute("GetStat", new { ProductKey = aNewUsageViewModel.ProductKey }, item);
    }
    return BadRequest();
}

此操作仅对该客户端请求正确起作用,因为您知道它实际上是在发送JSON而不是表单编码的数据。