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

Web API 2中如何为Created ActionResult定义序列化以截断属性

解决Web API 2中Created响应截断指定属性的问题

你已经找对方向啦——自定义CamelCasePropertyNamesContractResolver就是Web API里控制Json序列化规则的核心方式,咱们把你没写完的代码补全,再配上配置步骤就能实现需求:

1. 完善自定义ContractResolver与截断逻辑

首先要实现一个自定义的ContractResolver,并搭配IValueProvider来处理ItemDescriptions属性的截断:

public class ItemContractResolver : CamelCasePropertyNamesContractResolver
{
    // 可根据需求调整最大截断长度
    private readonly int _maxDescriptionLength = 100;

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty property = base.CreateProperty(member, memberSerialization);

        // 定位到ItemDescriptions属性
        if (member.Name == nameof(Item.ItemDescriptions) && property.PropertyType == typeof(string))
        {
            // 替换属性的ValueProvider,用我们的截断逻辑
            property.ValueProvider = new TruncatedStringValueProvider(member, _maxDescriptionLength);
        }

        return property;
    }
}

// 自定义ValueProvider,负责具体的字符串截断
public class TruncatedStringValueProvider : IValueProvider
{
    private readonly MemberInfo _member;
    private readonly int _maxLength;

    public TruncatedStringValueProvider(MemberInfo member, int maxLength)
    {
        _member = member;
        _maxLength = maxLength;
    }

    public object GetValue(object target)
    {
        // 获取原始属性值
        var originalValue = (_member as PropertyInfo)?.GetValue(target) as string;
        if (string.IsNullOrEmpty(originalValue)) return originalValue;

        // 执行截断:超过长度则截断并添加省略号
        return originalValue.Length > _maxLength 
            ? originalValue.Substring(0, _maxLength) + "..." 
            : originalValue;
    }

    public void SetValue(object target, object value)
    {
        // 反序列化场景如果不需要处理,直接赋值即可;有特殊需求可以在这里扩展
        (_member as PropertyInfo)?.SetValue(target, value);
    }
}

2. 配置Web API使用自定义规则

全局生效(所有Json响应都截断该属性)

在WebApiConfig.cs里替换默认的序列化规则:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // 其他路由、过滤器配置...

        // 绑定自定义ContractResolver到Json格式化器
        config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new ItemContractResolver();
    }
}

仅在Created响应中生效(不影响其他接口)

如果不想全局修改,只想在返回Created响应时应用截断,可以手动构造HttpResponseMessage来指定序列化规则:

public async Task<IHttpActionResult> PostItem(Item item)
{
    // 业务逻辑:保存item到数据库、生成Id等...

    // 单独配置当前响应的序列化规则
    var serializerSettings = new JsonSerializerSettings
    {
        ContractResolver = new ItemContractResolver(),
        Formatting = Formatting.Indented
    };

    // 手动序列化item
    var serializedItem = JsonConvert.SerializeObject(item, serializerSettings);
    var content = new StringContent(serializedItem, Encoding.UTF8, "application/json");

    // 构造Created响应,设置Location头
    var response = Request.CreateResponse(HttpStatusCode.Created, content);
    response.Headers.Location = new Uri(Request.RequestUri + "/" + item.Id);
    
    return ResponseMessage(response);
}

额外说明

  • 如果需要更灵活的截断逻辑(比如按单词边界截断、忽略HTML标签等),只需要修改TruncatedStringValueProvider.GetValue里的代码即可。
  • 如果你之前的代码卡在CreateProperty方法,核心就是通过替换ValueProvider来介入属性的序列化过程,这是Json.NET里自定义属性序列化的标准方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:39:11