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

如何在Service层不使用Model反序列化JSON列表并绑定ViewModel?

解决Service层不依赖Model时的JSON反序列化问题

我来帮你搞定这个问题!你现在的核心需求是让Service层完全不依赖Model,同时把它返回的JSON数据正确反序列化成ViewModel里的List<Employee>对吧?咱们先梳理下你之前代码里的问题,再给出正确的修改方案:

之前代码的核心问题

  1. 手动拼接JSON格式错误:你之前手动拼的JSON字符串里,字符串类型的字段(比如Name、Location)没有加双引号,这会导致JSON格式非法,反序列化失败。
  2. 反序列化类型不匹配:Controller里你用了JsonConvert.DeserializeObject<Employee>(...),但Service返回的是一个列表的JSON,应该对应List<Employee>类型,类型不匹配会直接报错。
  3. Service层仍依赖Model:你之前的Service代码里还保留了using listTest.Models;,这就没做到完全不依赖Model的要求。

正确的修改方案

1. 修正Service层代码(完全移除Model依赖)

这里我们用dynamic+ExpandoObject来构建数据,最后直接序列化整个列表,避免手动拼接JSON的错误,同时完全移除对Model的引用:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using System.Data;
using Newtonsoft.Json;
using System.Dynamic;

namespace listTest.Service
{
    public class DBService
    {
        private readonly static string cnstr = ConfigurationManager.ConnectionStrings["connection1"].ConnectionString;
        SqlConnection conn = new SqlConnection(cnstr);

        public string getData()
        {
            List<dynamic> DataList = new List<dynamic>();
            string sql = @"select * from Employee";
            try
            {
                conn.Open();
                SqlCommand cmd = new SqlCommand(sql, conn);
                SqlDataReader dr = cmd.ExecuteReader();
                while (dr.Read())
                {
                    dynamic empObj = new ExpandoObject();
                    // 保持Id的数值类型,避免后续反序列化时的类型转换问题
                    empObj.Id = Convert.ToInt32(dr["Id"]);
                    empObj.Name = dr["Name"].ToString();
                    empObj.Age = dr["Age"].ToString();
                    empObj.Location = dr["Location"].ToString();
                    empObj.Sex = dr["Sex"].ToString();
                    DataList.Add(empObj);
                }
            }
            catch (Exception e)
            {
                throw new Exception(e.Message.ToString());
            }
            finally
            {
                conn.Close();
            }
            // 直接序列化整个动态对象列表,生成合法的JSON数组
            return JsonConvert.SerializeObject(DataList);
        }
    }
}

2. 修正Controller层代码(正确反序列化)

只需要把反序列化的目标类型改成List<Employee>,和ViewModel里的EmployeeDataList类型匹配:

using System;
using System.Web.Mvc;
using listTest.Service;
using listTest.ViewModels;
using Newtonsoft.Json;
using listTest.Models;

namespace listTest.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult EmpList()
        {
            DBService service = new DBService();
            ViewModel data = new ViewModel();
            // 关键:反序列化成List<Employee>,匹配ViewModel的属性类型
            data.EmployeeDataList = JsonConvert.DeserializeObject<List<Employee>>(service.getData());
            return View(data);
        }
    }
}

更类型安全的替代方案(可选)

如果你觉得dynamic不够类型安全,可以在Service层定义一个内部DTO(数据传输对象),只在Service内部使用,这样既不依赖外部Model,又能保证类型安全:

在Service里添加一个内部类:

namespace listTest.Service
{
    public class DBService
    {
        // 内部DTO,仅Service层使用
        private class EmployeeDto
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public string Age { get; set; }
            public string Location { get; set; }
            public string Sex { get; set; }
        }

        // 剩余Service代码不变,只是把dynamic换成EmployeeDto
        public string getData()
        {
            List<EmployeeDto> DataList = new List<EmployeeDto>();
            string sql = @"select * from Employee";
            try
            {
                conn.Open();
                SqlCommand cmd = new SqlCommand(sql, conn);
                SqlDataReader dr = cmd.ExecuteReader();
                while (dr.Read())
                {
                    var empDto = new EmployeeDto();
                    empDto.Id = Convert.ToInt32(dr["Id"]);
                    empDto.Name = dr["Name"].ToString();
                    empDto.Age = dr["Age"].ToString();
                    empDto.Location = dr["Location"].ToString();
                    empDto.Sex = dr["Sex"].ToString();
                    DataList.Add(empDto);
                }
            }
            // ... 剩余代码和之前一致
        }
    }
}

这样Controller层的反序列化代码不需要修改,依然可以正常把JSON转换成List<Employee>。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 12:47:47