在C#中为WCF服务传入的标准JSON添加前缀标签的实现方案
WCF服务端标准JSON转定制化JSON方案(最小代码改动)
需求背景
当前WCF服务的创建订单方法依赖带xy1:/xy2:前缀、@符号的定制化JSON处理逻辑,现在需要改为接收标准JSON,在服务端自动转换为原有定制化格式,避免修改核心业务代码。
核心思路
利用WCF的消息拦截器(IDispatchMessageInspector),在请求到达业务方法前拦截并转换JSON格式,让后续业务逻辑完全复用原有代码,实现最小改动。
具体实现步骤
1. 实现消息拦截器
创建实现IDispatchMessageInspector的类,在BeforeReceiveRequest方法中完成JSON转换:
using System.IO; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Dispatcher; using Newtonsoft.Json; using Newtonsoft.Json.Linq; public class JsonTransformInspector : IDispatchMessageInspector { public object AfterReceiveReply(ref Message reply, object correlationState) { return null; } public object BeforeReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) { if (request.IsEmpty || !request.Properties.ContainsKey("HttpRequestMessage")) return null; // 读取原始请求JSON var requestMessage = (HttpRequestMessageProperty)request.Properties["HttpRequestMessage"]; using (var reader = new StreamReader(requestMessage.GetBodyReader())) { string rawJson = reader.ReadToEnd(); var standardJson = JObject.Parse(rawJson); // 转换为定制化JSON结构 var customJson = TransformToCustomJson(standardJson); // 替换请求内容为转换后的JSON var newMessage = Message.CreateMessage(request.Version, request.Headers.Action, new MemoryStream(System.Text.Encoding.UTF8.GetBytes(customJson.ToString()))); newMessage.Properties.CopyProperties(request.Properties); request = newMessage; } return null; } private JObject TransformToCustomJson(JObject standardJson) { var customRoot = new JObject(); // 处理顶层createOrder节点,添加xy1:前缀和命名空间属性 var createOrder = standardJson["createOrder"] as JObject; var customCreateOrder = new JObject { ["@test:xy1"] = "http://www.testing.com/schema/order", ["@test:xy2"] = "http://www.testing.com/schema/customer" }; // 处理order节点:添加xy1:前缀,属性加@ var standardOrder = createOrder["order"] as JObject; var customOrder = new JObject(); foreach (var prop in standardOrder.Properties()) { customOrder[$"@{prop.Name}"] = prop.Value; } customCreateOrder["xy1:order"] = customOrder; // 处理customer节点:添加xy2:前缀,Id属性加@,子属性加xy2:前缀 var standardCustomer = createOrder["customer"] as JObject; var customCustomer = new JObject(); foreach (var prop in standardCustomer.Properties()) { if (prop.Name == "Id") { customCustomer[$"@{prop.Name}"] = prop.Value; } else { customCustomer[$"xy2:{prop.Name}"] = prop.Value; } } customCreateOrder["xy2:customer"] = customCustomer; customRoot["xy1:createOrder"] = customCreateOrder; return customRoot; } }
2. 注册拦截器到服务
通过服务行为(ServiceBehavior)注册拦截器,避免修改配置文件:
using System.ServiceModel.Description; public class JsonTransformBehavior : IServiceBehavior { public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) { } public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { foreach (var endpointDispatcher in serviceHostBase.ChannelDispatchers) { foreach (var endpoint in ((ChannelDispatcher)endpointDispatcher).Endpoints) { endpoint.DispatchRuntime.MessageInspectors.Add(new JsonTransformInspector()); } } } public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { } } // 在服务宿主中添加行为 var host = new ServiceHost(typeof(OrderService)); host.Description.Behaviors.Add(new JsonTransformBehavior()); host.Open();
3. 适配复杂JSON扩展
如果实际JSON结构更复杂,可以扩展TransformToCustomJson方法:
- 用递归处理嵌套节点
- 维护前缀映射表(比如
order对应xy1:,customer对应xy2:) - 配置需要添加
@符号的属性列表
验证方案
- 发送标准JSON请求到服务端
- 在拦截器中打印转换前后的JSON,确认结构与原定制化JSON一致
- 验证原有创建订单逻辑正常执行,结果符合预期
内容的提问来源于stack exchange,提问作者shehzad ch
相关产品推荐
相关产品推荐

