Web Api忽略了用于处理DbGeography的自定义JsonConverter

4
主要问题出在这里。我试图将嵌套的Json数据发送到我的Web API。我有一个自定义的JSON转换器用于我的DbGeography类型。然而,当我发送请求时,似乎我的自定义转换器从未被调用。我得到的错误是:无法将对象类型Object转换为DbGeography。我正在使用数据库优先EF作为我的数据模型。注释掉locationAccountCreated属性后,其他一切都正常工作,并且数据成功持久化到数据库中。
任何帮助将不胜感激。
请查看下面的相关代码
控制器
[Route("Create")]
[HttpPost]
public HttpResponseMessage PostNewAccount([FromBody]IDictionary<string, object> formData) 
{
    if (formData != null)
    {
        var nValueCol = formData;

        var account = new Account()
        { 
            Email = (string)nValueCol["email"],
            Password = (string)nValueCol["password"],
            AgreedToTerms = Convert.ToBoolean(nValueCol["agreesToTerms"]),
            LocationAccountCreated = (DbGeography)nValueCol["userLocation"]//source of error
            //LocationAccountCreated = (DbGeography)(IDictionary<string, IDictionary<string, double>>)nValueCol["userLocation"] 
        };

       //...rest of code unrelated to problem
}

自定义转换器

public class DbGeographyConverter : JsonConverter
{
    private const string LATITUDE_KEY = "latitude";
    private const string LONGITUDE_KEY = "longitude";
    public override bool CanConvert(Type objectType)
    {
        return objectType.Equals(typeof(DbGeography));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if(reader.TokenType == JsonToken.Null) // checks if token is null.
        {
            return default(DbGeography);
        }

        var jObject = JObject.Load(reader);

        if (!jObject.HasValues || (jObject.Property(LATITUDE_KEY)) == null || (jObject.Property(LONGITUDE_KEY)) == null) //checks if Json Object is null, and if longitude or latitude properties are null
        {
            return default(DbGeography);
        }

        string wellKnownText = string.Format("POINT({0} {1})", jObject[LATITUDE_KEY], jObject[LONGITUDE_KEY]);
        return DbGeography.FromText(wellKnownText, DbGeography.DefaultCoordinateSystemId);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var dbGeography = value as DbGeography;

        serializer.Serialize(writer, dbGeography == null || dbGeography.IsEmpty ? null : new { latitude = dbGeography.Latitude.Value, longitude = dbGeography.Longitude.Value });
    }
}


public class QueryLocationMetadata
{
    [JsonConverter(typeof(DbGeographyConverter))]
    public virtual System.Data.Entity.Spatial.DbGeography LocationAccountCreated { get; set; }
}

Partial Class

[MetadataType(typeof(QueryLocationMetadata))]
public partial class Account
{        
}

Global.asax

protected void Application_Start()
{
    var config = GlobalConfiguration.Configuration;

    //Registering routes from the WebApi.Config file
    GlobalConfiguration.Configure(Config.WebApiConfig.Register);


    //Registering Autofac
    GlobalConfiguration.Configure(Config.AutofacConfig.Initialize);

//Registering Formatter
    config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new DbGeographyConverter());
}

Fiddler请求

http://localhost:9576/Account/Create

User-Agent: Fiddler
Content-type: application/json
Host: localhost:9576
Content-Length: 316


{
  "email":"e02f6rt7fgvujtgv@myuct.ac.za",
  "firstName":"myFName",
  "lastName":"myFName",
  "dateOfBirth":"1992-02-18",
  "password":"password",
  "agreesToTerms":true,
  "userName" : "Cool User",
  "gender" : "Female",
  "userLocation": {"geopoint":{"latitude" : 40.334910, "longitude" :  -32.254586}}
}
1个回答

2
尝试将其作为第一个提供者插入:
config.Formatters.JsonFormatter.SerializerSettings.Converters.Insert(0, new DbGeographyConverter());

我使用你的转换器代码在Web Api 2控制器中尝试了这个操作:
public void Post([FromBody]System.Data.Entity.Spatial.DbGeography value)

还要注意数字格式问题。WKT 部分可能需要像这样:

string wellKnownText = string.Format("POINT({0} {1})", jObject[LATITUDE_KEY].Value<double>().ToString(System.Globalization.NumberFormatInfo.InvariantInfo), jObject[LONGITUDE_KEY].Value<double>().ToString(System.Globalization.NumberFormatInfo.InvariantInfo));

1
嗨Kagelos,我试过你的建议了,还是不起作用,不太确定我在这个问题上哪里出错了。当你按照上面的方式尝试转换器时,它是否起作用了? - user6201138

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接