WebApi系列~按需序列化字段~Hot

本文介绍了一种优化对外API数据传输的方法,特别是在移动设备上减少不必要的数据传输,节省网络带宽和流量。通过在序列化阶段剔除非必需字段,提高了数据传输效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

起初只是一个想法,一次讨论,一个设想,但相信一定可以实现,具体的事情是这样的,有个对外的API项目,它为一些终端设备提供数据,如手机,平板,PC,当然你也可以说它为很多平台提供数据win32,mac,ios,android,对于PC设备来说,接口返回的数据量当然没有那么敏感,但对于移动设备,对这点要求就高些,不需要的数据请不要为我返回,因为那么会发费我很多流量!

是的,这是2010年到未来某个时期的热门话题,网络带宽是收费的,不要随便浪费!

第一次想法失败了

终端-〉请求数据包-〉服务端接口接改并处理-〉数据返回并过滤无用字段

这个模型在我的大脑里呈现,但经过实践的证明,很遗憾,它是无法实现的,因为你不能为每个属性动态去添加一种叫做JsonIgnore的特性(不会被序列化),因为这种特性属于一种元信息,我们在程序运行时,只能获取它,设置它的值,而不能添加或者移除它(反射),当然,你可以从新动态创建一个类,一个类的方法和属性(Emit)

第二次想法成功了

数据层和业务层在服务端去干自己的事,返回自己完整的数据吧,我不去关心它,我关心的是在API返回数据时的动作(序列化),所以第二次想法出来了,将实体对象在进行JSON序列化时进行加工,将不需要的字段从JSON字符串中去掉,就OK了,注意本代码只是第一版,目前还不支持JSON的嵌套属性,这个递归我打算在第二版再实现它,呵呵,不想让它太复杂!

下面是我的代码

复制代码
        /// <summary>
        /// 功能:集合按需要序列化
        /// author:仓储大叔
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="fun"></param>
        /// <returns></returns>
        public static string ToJson(this object type, params string[] param)
        {
            StringBuilder buffer = new StringBuilder();
            if (type.GetType().Name == "List`1")
            {
                buffer.Insert(0, "[");
                foreach (var t in (IEnumerable<object>)type)
                {
                    GeneratorJsonStr(buffer, t, param);
                }
                buffer.Append("]");
            }
            else
            {
                GeneratorJsonStr(buffer, type, param);
            }
            return buffer.ToString();
        }
        /// <summary>
        /// 为对象生成Json字符串
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="t"></param>
        /// <param name="param"></param>
        static void GeneratorJsonStr(StringBuilder buffer, object t, params string[] param)
        {
            var obj = new List<string>();
            foreach (var item in param)
            {
                var p = t.GetType().GetProperty(item, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
                if (p != null)
                {
                    if (p.PropertyType == typeof(string))
                        obj.Add(p.Name + ":\"" + p.GetValue(t) + "\"");
                    else
                        obj.Add(p.Name + ":" + p.GetValue(t));
                }
            }
            if (obj.Count > 0)
                buffer.Append("{" + string.Join(",", obj) + "}");
        }
复制代码
using CY_PUBLIC_LIBRARY.Extension; using DoMain.hp_dto; using Model.sys_model; using System.Transactions; namespace CY_API.Controllers.hController { [Route("api/[controller]")] [Authorize] [ApiExplorerSettings(GroupName = "base_data")] public class HospitalController : BaseApiController { public HospitalController(IFreeSql fsql) : base(fsql) { } /// <summary> /// 新增 /// </summary> /// <param name="hospitalDto">医院和科室信息</param> /// <returns></returns> [HttpPost] public IActionResult AddHospitalWithDepartments([FromBody] hospitalDepartmentDto hospitalDto) { try { // 使用事务确保数据一致性 _fsql.Transaction(() => { // 1. 创建医院 var hospital = new sys_hospital { name = hospitalDto.name, address = hospitalDto.address, image = hospitalDto.image, hospital_label = hospitalDto.hospital_label, is_hot = hospitalDto.is_hot, }; // 插入医院并获取自增ID var hospitalId = _fsql.Insert(hospital).ExecuteIdentity(); // 2. 创建科室 var departments = hospitalDto.hospitalDepartmentListDtos.Select(d=> new sys_hospitaldepartment { name = d.name, hospital_id =(int)hospitalId, content = d.content, //hd_id=d.hd_id }).ToList(); // 批量插入科室 _fsql.Insert(departments).ExecuteAffrows(); }); return this.ReturnOk(); } catch (Exception ex) { throw ex; } } /// <summary> /// 显示医院列表 /// </summary> /// <returns></returns> [HttpGet] public ActionResult<retEnumerable<retHospital>> GetHospital(string name, bool? is_hot, int page=1, int size=5) { try { var query = _fsql.Select<sys_hospital>(); if (!string.IsNullOrEmpty(name)) { query = query.Where(x => x.name.Contains(name)); } if (is_hot.HasValue) { query = query.Where(x => x.is_hot == is_hot.Value); } var hospitals =query.OrderByDescending(x => x.hospital_id).Page(page, size).ToList(); // 获取每个医院的科室信息 var result = hospitals.Select(hospital => new retHospital { hospital_id = hospital.hospital_id, name = hospital.name, address = hospital.address, image = hospital.image, hospital_label = hospital.hospital_label, is_hot = hospital.is_hot, // 获取该医院的科室列表 departments = _fsql.Select<sys_hospitaldepartment>().Where(d => d.hospital_id == hospital.hospital_id).Page(page,size) .ToList(d => new retHospitalDepartment { hd_id = d.hd_id, name = d.name, content = d.content, hospital_id = d.hospital_id }) }).ToList(); return Ok(result.GetRetEnumerable()); } catch (Exception ex) { throw ex; } } /// <summary> /// 删除 /// </summary> /// <param name="id"></param> /// <returns></returns> [HttpDelete("{id}")] public IActionResult DeleteHp(int id) { _fsql.Transaction(() => { _fsql.Update<sys_hospital>(id).Set(e => e.is_del, true).ExecuteAffrows(); }); return this.ReturnOk(); } /// <summary>. /// 修改医院和科室 /// </summary> /// <param name="upd">医院和科室信息</param> /// <returns></returns> [HttpPut] public IActionResult UpdateHospitalWithDepartments([FromBody] updatehospitalDepartment upd) { try { // 使用事务确保数据一致性 _fsql.Transaction(() => { // 1. 更新医院信息 var hospital = new sys_hospital { hospital_id = upd.hospital_id, name = upd.name, address = upd.address, image = upd.image, hospital_label = upd.hospital_label, is_hot =upd.is_hot }; _fsql.Update<sys_hospital>().SetSource(hospital).ExecuteAffrows(); // 2. 更新科室信息 var departments = upd.updhospitalDepartmentListDtos.Select(d => new sys_hospitaldepartment { hd_id = d.hd_id, name = d.name, content = d.content, hospital_id = upd.hospital_id, }).ToList(); // 修改关联科室 _fsql.Update<sys_hospitaldepartment>() .Where(d => d.hospital_id == hospital.hospital_id).SetSource(departments) .ExecuteAffrows(); }); // 返回更新后的医院详情(包含科室) return Ok(upd.hospital_id); } catch (Exception ex) { throw ex; } } } } 为啥我后台测试的时候都是对的,但前端调用接口会报错,修改不成功,而且有时候前端也添加少张表添加进去
最新发布
08-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值