通过WCF返回字典

时间:2013-09-24 08:38:38

标签: c# json wcf dictionary

我正在尝试通过Dictionary作为WCF输出JSON。我遇到的第一个问题JSON充斥着'Key''Value'元素,但是我使用自己的JsonDictionary(来自StackOverflow的代码)修复了这个问题。

我现在得到的是:

{
    "_x0030_": {
        "__type": "Car:#WcfService",
        "Brand": "Ford",
        "Model": "Focus"
    },
    "_x0031_": {
        "__type": "Car:#WcfService",
        "Brand": "Renault",
        "Model": "Megane"
    }
}

__type__与我无关(很好,它可以删除,但目前不是我的重点)。问题是索引。例如,整数转换为' x0030 '为0。 我希望有:

{
    "0": {
        "__type": "Car:#WcfService",
        "Brand": "Ford",
        "Model": "Focus"
    },
    "1": {
        "__type": "Car:#WcfService",
        "Brand": "Renault",
        "Model": "Megane"
    }
}

我在MSDN上看到这是默认行为,但没有解决方法如何防止这种情况。有什么想法吗?

我的代码:

//Interface
[WebGet(UriTemplate = "car", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
JsonDictionary<int, Car> GetCars();

//Implementation
public class CarService : ICarService
{
    private JsonDictionary<int, Car> cars = new JsonDictionary<int, Car>();
    private int lastIndex = 0;        

    public CarService()
    {
        cars.Add(lastIndex++, new Car("Ford", "Focus"));
        cars.Add(lastIndex++, new Car("Renault", "Megane"));
    }

    public JsonDictionary<int, Car> GetCars()
    {
        return cars;
    }
}

[DataContract]
public class Car
{
    public Car(string brand, string model)
    {
        this.Brand = brand;
        this.Model = model;
    }

    [DataMember]
    public string Brand { get; private set; }

    [DataMember]
    public string Model { get; private set; }
}

[Serializable]
[KnownType(typeof(Car))]
public class JsonDictionary<TKey, TValue> : ISerializable
{
    public Dictionary<TKey, TValue> dictionary;

    public JsonDictionary()
    {
        dictionary = new Dictionary<TKey, TValue>();
    }

    public JsonDictionary(SerializationInfo info, StreamingContext context)
    {
        dictionary = new Dictionary<TKey, TValue>();
    }

    public TValue this[TKey key]
    {
        get { return dictionary[key]; }
        set { dictionary[key] = value; }
    }

    public void Add(TKey key, TValue value)
    {
        dictionary.Add(key, value);
    }

    public bool ContainsKey(TKey key)
    {
        return dictionary.ContainsKey(key);
    }

    public bool Remove(TKey key)
    {
        return dictionary.Remove(key);
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        foreach (TKey key in dictionary.Keys)
        {
            info.AddValue(key.ToString(), dictionary[key]);
        }
    }
}

<?xml version="1.0"?>
<configuration>

  <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="WcfService.CarService">
        <endpoint 
          behaviorConfiguration="restfulBehaviour" 
          binding="webHttpBinding" 
          contract="WcfService.ICarService">
        </endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost/carservice"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="restfulBehaviour">
          <webHttp defaultOutgoingResponseFormat="Json"/>
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
        <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>    
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <directoryBrowse enabled="true"/>
  </system.webServer>
  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel"
              switchValue="Information, ActivityTracing"
              propagateActivity="true">
        <listeners>
          <add name="traceListener"
              type="System.Diagnostics.XmlWriterTraceListener"
              initializeData="d:\WebTrace.svclog"  />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>
</configuration>

0 个答案:

没有答案