简体   繁体   English

JSON WCF反序列化DataContracts

[英]JSON WCF Deserialization DataContracts

I have a DataContract that I am attempting to deserialize from some JSON received from a WCF service. 我有一个DataContract ,我正在尝试从WCF服务接收的JSON中反序列化。 I am able to get the root DeviceID and TimeStamp to deserialize without issue, however, I can not get any of the GeoLocations or Videos and VideoFrames to deserialize. 我能够获取根DeviceIDTimeStamp进行反序列化而没有问题,但是,我无法获取任何GeoLocationsVideosVideoFrames进行反序列化。

I have looked around quite a bit and from what I can find this should work. 我已经环顾了四周,从我发现这应该行得通。 I have tweaked around with some of the DataContact attributes quite a bit to try to get this, but still no luck. 我已经对一些DataContact属性进行了一些调整,以尝试实现此目的,但还是没有运气。

I am sending this JSON to a WCF web service. 我正在将此JSON发送到WCF Web服务。

{
    "DeviceId": "74a5f7aa9d4dfd0d",
    "TimeStamp": 1394756724,
    "GeoLocations": [
        {
            "TimeStamp": 1394756724,
            "Latitude": 948.348275,
            "Longitude": 381.3252
        },
        {
            "TimeStamp": 1394756726,
            "Latitude": 98.348275,
            "Longitude": 31.3252
        }
    ],
    "Videos": [
        {
            "VideoFrames": [
                {
                    "TimeStamp": 1234567789,
                    "Base64EncodedFrame": "dajflahfaskfasld"
                },
                {
                    "TimeStamp": 1234567789,
                    "Base64EncodedFrame": "dajflahfaskfasld"
                }
            ]
        }
    ]
}

The web service interface looks Like this. Web服务界面看起来像这样。

[OperationContract]
[WebInvoke(Method = "POST",
    ResponseFormat = WebMessageFormat.Json,
    BodyStyle = WebMessageBodyStyle.Wrapped,
    UriTemplate = "json")]
String JSONData();

The web service attempts to deserialize the object to this model. Web服务尝试将对象反序列化为该模型。

[DataContract(Namespace="")]
public class VideoFrame
{
    [Key]
    public int VideoFrameId { get; set; }

    [DataMember(Order = 0, IsRequired = false)]
    public int TimeStamp { get; set; }

    [DataMember(Order = 1, IsRequired = false)]
    public string Base64EncodedFrame { get; set; }
}

[DataContract(Namespace = "")]
public class Video
{
    [Key]
    public int VideoId { get; set; }

    [DataMember(Order = 0, IsRequired = false)]
    public virtual List<VideoFrame> VideoFrames { get; set; }
}

[DataContract(Namespace="")]
public class GeoLocation
{
    [Key]
    public int GeoLocationId { get; set; }

    [DataMember(Order = 0, IsRequired = true)]
    public int TimeStamp { get; set; }

    [DataMember(Order = 1, IsRequired = true)]
    public double Latitude { get; set; }

    [DataMember(Order = 2, IsRequired = true)]
    public double Longitude { get; set; }
}

[DataContract(Name="root", Namespace="")]
public class DeviceUpdate
{
    [Key, Column(Order = 0)]
    [DataMember (Order=0, IsRequired=true)]
    public string DeviceId { get; set; }

    [Key, Column(Order = 1)]
    [DataMember(Order=1, IsRequired=true)]
    public int TimeStamp { get; set; }

    [DataMember(Order = 2, IsRequired = true)]
    public virtual List<GeoLocation> GeoLocations { get; set; }

    [DataMember(Order = 3, IsRequired = true)]
    public virtual List<Video> Videos { get; set; }
}

The web service code is: Web服务代码为:

DeviceUpdate dataObject = OperationContext.Current.RequestContext.RequestMessage.GetBody<DeviceUpdate>();

Webconfig: Webconfig:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="BugsBunny.RestService" behaviorConfiguration="ServiceBehavior">
        <endpoint address="" binding="webHttpBinding" contract="BugsBunny.IRestService" behaviorConfiguration="web"></endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="web">
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true" />
  </system.webServer>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
  <system.web>
    <customErrors mode="Off"/>
  </system.web>
</configuration>

This may help too, I pulled the actual XML that it is attempting to process after the JSON is revived: 这也可能会有所帮助,在JSON复活后,我提取了它尝试处理的实际XML:

<root type="object">
  <DeviceId type="string">74a5f7aa9d4dfd0d</DeviceId>
  <TimeStamp type="number">1394756724</TimeStamp>
  <GeoLocations type="array">
    <item type="object">
      <TimeStamp type="number">1394756724</TimeStamp>
      <Latitude type="number">948.348275</Latitude>
      <Longitude type="number">381.3252</Longitude>
    </item>
    <item type="object">
      <TimeStamp type="number">1394756726</TimeStamp>
      <Latitude type="number">98.348275</Latitude>
      <Longitude type="number">31.3252</Longitude>
    </item>
  </GeoLocations>
  <Videos type="array">
    <item type="object">
      <VideoFrames type="array">
        <item type="object">
          <TimeStamp type="number">1234567789</TimeStamp>
          <Base64EncodedFrame type="string">dajflahfaskfasld</Base64EncodedFrame>
        </item>
        <item type="object">
          <TimeStamp type="number">1234567789</TimeStamp>
          <Base64EncodedFrame type="string">dajflahfaskfasld</Base64EncodedFrame>
        </item>
      </VideoFrames>
    </item>
  </Videos>
</root>

Ok, I have found a way to make this work. 好的,我找到了一种使这项工作成功的方法。

I have changed the web-service implementation to this: 我已将Web服务实现更改为:

DeviceUpdate dataObject = OperationContext.Current.RequestContext.RequestMessage.GetBody<DeviceUpdate>(new DataContractJsonSerializer(typeof(DeviceUpdate)));

And added: 并添加:

RequestFormat = WebMessageFormat.Json

to the service interface attributes. 服务接口属性。

This allows all objects to populate in the data contact. 这允许所有对象填充在数据联系人中。

Thank you for everyone's help. 谢谢大家的帮助。

Here you will not get the geo location because BodyStyle bare does not include the namespace while the wrapped does it so you can get the other properties also. 在这里,您将不会获得地理位置,因为BodyStyle裸机不包含名称空间,而包装程序则包含名称空间,因此您还可以获取其他属性。

try this 尝试这个

[OperationContract]
[WebInvoke(Method = "POST",
    ResponseFormat = WebMessageFormat.Json,
    BodyStyle = WebMessageBodyStyle.Wrapped,
    UriTemplate = "/json")]
String JSONData();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM