You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将SqlGeography类型(Microsoft.SqlServer.Types)作为Web引用传递?

解决ASMX Web引用中SqlGeography类型序列化不完整的问题

ASMX默认使用的XmlSerializer无法完整序列化SqlGeography这类复杂的自定义类型,只能识别其简单的公共属性(比如STSrid),这就是客户端生成的类仅包含该属性的原因。以下是几种可行的解决方法:

方法1:手动扩展客户端生成的分部类

客户端生成的SqlGeography是分部类,可以在客户端项目中新增一个分部类文件,补充序列化/反序列化逻辑,通过WKT(Well-Known Text)格式传递完整地理数据:

public partial class SqlGeography
{
    // 新增用于传递完整地理数据的WKT属性
    public string Wkt { get; set; }

    // 将当前对象转换为SqlGeography实例
    public Microsoft.SqlServer.Types.SqlGeography ToSqlGeography()
    {
        return string.IsNullOrEmpty(Wkt) 
            ? null 
            : Microsoft.SqlServer.Types.SqlGeography.STGeomFromText(
                new System.Data.SqlTypes.SqlChars(Wkt), this.STSrid);
    }

    // 从SqlGeography实例初始化当前对象的静态方法
    public static SqlGeography FromSqlGeography(Microsoft.SqlServer.Types.SqlGeography geo)
    {
        if (geo == null) return null;
        return new SqlGeography
        {
            STSrid = (int)geo.STSrid,
            Wkt = geo.STAsText().ToString()
        };
    }
}

服务端需要将SqlGeography转换为带Wkt属性的对象返回,客户端再通过ToSqlGeography()方法还原为原生类型。

方法2:服务端使用可序列化的包装类

在ASMX服务项目中创建一个包装类,封装SqlGeography的必要数据(WKT、STSrid),服务端方法返回该包装类而非直接返回SqlGeography:

public class SqlGeographyWrapper
{
    public int STSrid { get; set; }
    public string Wkt { get; set; }

    // 从SqlGeography实例初始化包装类
    public static SqlGeographyWrapper FromSqlGeography(Microsoft.SqlServer.Types.SqlGeography geo)
    {
        if (geo == null) return null;
        return new SqlGeographyWrapper
        {
            STSrid = (int)geo.STSrid,
            Wkt = geo.STAsText().ToString()
        };
    }

    // 将包装类转换为SqlGeography实例
    public Microsoft.SqlServer.Types.SqlGeography ToSqlGeography()
    {
        return Microsoft.SqlServer.Types.SqlGeography.STGeomFromText(
            new System.Data.SqlTypes.SqlChars(Wkt), STSrid);
    }
}

服务端方法示例:

[WebMethod]
public SqlGeographyWrapper GetLocation()
{
    var geo = Microsoft.SqlServer.Types.SqlGeography.Point(47.6062, -122.3321, 4326);
    return SqlGeographyWrapper.FromSqlGeography(geo);
}

客户端添加Web引用后,即可通过包装类获取完整的地理数据,再转换为原生SqlGeography类型。

方法3:改用DataContractSerializer(进阶)

ASMX默认使用XmlSerializer,可通过在服务类上标注[DataContractFormat]切换为DataContractSerializer。但由于SqlGeography是第三方类型,需配合数据契约包装类或DataContractSurrogate处理序列化逻辑,该方法复杂度较高,适合有一定WCF序列化经验的场景。

方法4:升级至WCF(长期方案)

如果项目允许,建议将ASMX服务升级为WCF服务。WCF对复杂类型的序列化支持更完善,可通过配置DataContractSerializer或NetDataContractSerializer直接传递SqlGeography类型,同时客户端需适配WCF服务引用。

内容的提问来源于stack exchange,提问作者Peet Brits

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 18:40:11