Webapi与实体框架 - 使用客户JSON转换器序列化DbGeography无法正常工作

时间:2013-09-29 00:35:10

标签: json entity-framework asp.net-web-api

我正在使用带有DbGeography空间数据的webapi,并希望序列化为json。 默认情况下,DbGeography序列化为null。所以我为它实现了自己的转换器。 这是我到目前为止所做的,但它似乎没有用。

基本上,使用以下代码,我的DbGeographyConverter.WriteJson方法永远不会被调试,并且Location属性被序列化为null

客户转换器:

public class DbGeographyConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        DbGeography contextObj = value as DbGeography;

        writer.WriteStartObject();
        writer.WritePropertyName("Lat");
        serializer.Serialize(writer, contextObj.Latitude);

        writer.WritePropertyName("Long");
        serializer.Serialize(writer, contextObj.Longitude);
        writer.WriteEndObject();
    }

    public override bool CanConvert(Type objectType)
    {
        if (objectType == typeof(DbGeography))
        {
            return true;
        }

        return false;
    }

    public override bool CanRead
    {
        get
        {
            return true;
        }
    }

    public override bool CanWrite
    {
        get
        {
            return true;
        }
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

在Global.ascx.cs中添加转换

protected void Application_Start()
{
             GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Converters.Add(
 new DbGeographyConverter()

}

最后,将转换器应用于数据模型类属性

public DataModelClass1
{

[JsonConverter (typeof(DbGeographyConverter))]
    public DbGeography Location { get; set; }

}       

2 个答案:

答案 0 :(得分:0)

首先,由于您要将自定义转换器添加到SerializerSettings.Converters集合,因此您无需使用JsonConverterAttribute修饰DataModelClass1的Location属性 - JsonFormatter将运行上述集合,直到找到派生为止你添加的JsonConverter没有属性。

现在回到你的问题 - 你正在测试这个浏览器以及如何测试?如果我推测,我会说你正在使用带有GET请求的Chrome或Firefox,这两个请求都会优先application/xml优先于他们发送到服务器的accept header application/json。出于这个原因,Web API将看到浏览器更喜欢XML而不是JSON,永远不会触及JsonFormatter,更不用说你的自定义JsonConverter了。

这有一些解决方法。在浏览器端,最简单的方法是使用jQuery和specify that you want JSON back生成ajax GET请求。在服务器端,您可以remove application/xml from the SupportedMediaTypes

答案 1 :(得分:0)

我在这上花了很长时间。如果您想从此更改Json for DbGeography的默认输出格式,您只能使用方法

"geography": {
  "coordinateSystemId": 4326,
  "wellKnownText": "POINT (77.6599502563474 12.9602302518557)"
}

与其他类似的东西,如" 77.22,12.8和#34; - 只是一个字符串。

如果您希望在请求中阅读 Json上将类似字符串转换为DbGeography,则以下代码是您之后的代码

public class DbGeographyConverter : JsonConverter
{
    public override bool CanConvert ( Type objectType )
    {
        return objectType.IsAssignableFrom( typeof( string ) );
    }

    public override object ReadJson ( JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer )
    {
        if ( reader.Value == null ) {
            return null;
        }

        return Parser.ToDbGeography( reader.Value.ToString() );
    }

    public override void WriteJson ( JsonWriter writer, object value, JsonSerializer serializer )
    {
        // Base serialization is fine
        serializer.Serialize( writer, value );
    }
}

如果您传入字符串值,这是转换器的代码 - 12,99 这将是你和他妈的

此示例应用程序具有您正在寻找的答案。 https://code.msdn.microsoft.com/windowsazure/HTML-ASPNET-Web-API-Bing-58c97f9f

可以在此处找到此处的转换器代码 https://github.com/Azure-Samples/SQLDatabase-Spatial-WebAPI-BingMaps/blob/master/SpatialTypesWithWebAPI/Models/DbGeographyConverter.cs