C#带坐标的POST端点请求模型问题及Cosmos DB存储需求
符合坐标验证要求的C#模型(适配Cosmos DB)
原模型使用List<double>存储坐标点,无法限制数组必须包含恰好两个数值,也无法阻止非数组类型的非法输入。下面是修正后的方案,通过自定义坐标类型+序列化转换器实现严格验证,同时兼容Cosmos DB的存储需求。
1. 自定义坐标类型与序列化转换器
创建Coordinates类封装经纬度,通过自定义JSON转换器实现数组与对象的双向映射,并在反序列化时验证数组格式:
使用Newtonsoft.Json的实现
using Newtonsoft.Json; using System.ComponentModel.DataAnnotations; // 封装经纬度,添加范围验证确保合法 public class Coordinates { [Range(-90, 90, ErrorMessage = "纬度必须在-90到90之间")] public double Latitude { get; set; } [Range(-180, 180, ErrorMessage = "经度必须在-180到180之间")] public double Longitude { get; set; } } // 自定义转换器,处理数组与Coordinates对象的序列化/反序列化 public class CoordinatesConverter : JsonConverter<Coordinates> { public override Coordinates ReadJson(JsonReader reader, Type objectType, Coordinates existingValue, bool hasExistingValue, JsonSerializer serializer) { // 验证输入是否为数组类型 if (reader.TokenType != JsonToken.StartArray) throw new JsonSerializationException("坐标必须是数组类型"); var values = serializer.Deserialize<double[]>(reader); // 验证数组长度是否为2 if (values?.Length != 2) throw new JsonSerializationException("坐标必须是包含两个数值的数组"); return new Coordinates { Latitude = values[0], Longitude = values[1] }; } public override void WriteJson(JsonWriter writer, Coordinates value, JsonSerializer serializer) { // 序列化时转回双元素数组,兼容Cosmos DB存储格式 serializer.Serialize(writer, new[] { value.Latitude, value.Longitude }); } }
使用System.Text.Json的实现(适用于.NET Core/.NET 5+)
using System.Text.Json; using System.Text.Json.Serialization; using System.ComponentModel.DataAnnotations; public class Coordinates { [Range(-90, 90, ErrorMessage = "纬度必须在-90到90之间")] public double Latitude { get; set; } [Range(-180, 180, ErrorMessage = "经度必须在-180到180之间")] public double Longitude { get; set; } } public class CoordinatesSystemTextJsonConverter : JsonConverter<Coordinates> { public override Coordinates Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.StartArray) throw new JsonException("坐标必须是数组类型"); var values = JsonSerializer.Deserialize<double[]>(ref reader, options); if (values?.Length != 2) throw new JsonException("坐标必须是包含两个数值的数组"); return new Coordinates { Latitude = values[0], Longitude = values[1] }; } public override void Write(Utf8JsonWriter writer, Coordinates value, JsonSerializerOptions options) { writer.WriteStartArray(); writer.WriteNumberValue(value.Latitude); writer.WriteNumberValue(value.Longitude); writer.WriteEndArray(); } }
2. 修正后的请求模型
public class Location { // 根据使用的JSON库选择对应的转换器 [JsonConverter(typeof(CoordinatesConverter))] // Newtonsoft.Json // [JsonConverter(typeof(CoordinatesSystemTextJsonConverter))] // System.Text.Json public Coordinates Point { get; set; } } public class HazardReport { public string Id { get; set; } public string OrgId { get; set; } public List<string> Hazards { get; set; } public Location Location { get; set; } }
方案说明
- 严格验证:反序列化时会自动检查输入是否为双元素数组,非法格式(如单个数值、长度不为2的数组)会抛出序列化异常,直接拦截非法请求。
- 经纬度合法性:通过
Range注解确保纬度在[-90,90]、经度在[-180,180]范围内,符合地理坐标规范。 - Cosmos DB兼容:序列化后输出的JSON结构与原请求一致(
point为双元素数组),可以直接存储到Cosmos DB,无需额外格式转换。
内容的提问来源于stack exchange,提问作者Rakesh Pattanayak
相关产品推荐
相关产品推荐

