MVC - 11(上).DTO

时间:2023-02-03 20:04:45

1.重要:javaScriptSerializer 无法识别被序列化的对象里各种属性是否存在  循环依赖

(System,Web.Script.Serialization.JavaScriptSerializer)

所以,我们不能使用javaScriptSerializer 去序列化 EF 实体对象A 。

因为javaScriptSerializer 会循环 EF 实体对象 A 里的每个属性,想要根据此属性生成对应的Json字符串,但是,EF 实体A 的外键(导航)属性如果被访问,则自动去数据库获取,而这个导航属性对应的实体类 B 中可能又包含指向实体 A 的类型,那么,EF又会去加载 A 的数据,然后 A里又包含B。。。。。陷入死循环。。。

(参考2013-5-31-mvc)

MVC - 11(上).DTO

2.后台如果取数据需要转换成json发送到前台如图,Class就不能获取数据。所以我们需要采用DTO

MVC - 11(上).DTO

2.1.前台ajax请求Student数据

Stu/Index.cshtml
Stu/Index.cshtml

@{
ViewBag.Title = "学员列表";
}
@section headSection{
<script type="text/javascript">
$(function () {
//0.关闭Jquery的浏览器缓存
$.ajaxSetup({ cache: false });
loadPageList(1);
}); //根据页码 异步请求数据
function loadPageList(pageIndex) {
$.get("/Stu/List/" + pageIndex, null, function(jsonData) {
alert(jsonData.msg);
},"json");
}
</script>
}
<table border="1" cellspacing="0" cellpadding="0" width="100%">
<tr>
<th>ID</th>
<th>班级名</th>
<th>姓名</th>
<th>性别</th>
<th>操作</th>
</tr>
<tr> </tr>
</table>

2.2.后台获取数据

//根据页码加载数据 此方法的Id其实是页码
public ActionResult List(int id)
{
//页码
int pageIndex = id;
//页容量
int pageSize = 2;
//2.1 根据页码获取分页数据 List<Models.Student> list = db.Students.Include("Class").OrderBy(s => s.StudentID)
.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(); //2.2 获取总行数
int rowCount = db.Students.Count();
//2.3 计算总页数
int pageCount = Convert.ToInt32(Math.Ceiling((rowCount*1.0)/pageSize)); return null;
}

3.这个时候我们来创建DTO

MVC - 11(上).DTO

注意:

1.去掉virtual

public virtual Class Class { get; set; }

2.//public class Class{...} //报错
    //这里ClassDTO.cs不能是用Class.cs同名类,因为EF不认识,会报下列错误

//CLR到EDM的类型映射不明确,因为多个CLR类型与EDM类型“Class”匹配,

MVC - 11(上).DTO

StudentDTO.cs

StudentDTO.cs
StudentDTO.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace _06MVCAjax_CodeFirst.Models.DTO
{
//public class Student{...} //报错
//这里StudentDTO.cs不能是用Student.cs同名类,因为EF不认识,会报下列错误
//CLR到EDM的类型映射不明确,因为多个CLR类型与EDM类型“Student”匹配,
public class StudentDTO
{
public int StudentID { get; set; }
public Nullable<int> Cid { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public Nullable<int> Isdel { get; set; }
public Nullable<System.DateTime> AddTime { get; set; } //注意这里是ClassDTO类型
public ClassDTO Class { get; set; }
}
}

ClassDTO.cs

ClassDTO.cs
ClassDTO.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace _06MVCAjax_CodeFirst.Models.DTO
{
//public class Class{...} //报错
//这里ClassDTO.cs不能是用Class.cs同名类,因为EF不认识,会报下列错误
//CLR到EDM的类型映射不明确,因为多个CLR类型与EDM类型“Class”匹配,
public class ClassDTO
{
public ClassDTO()
{
this.Students = new List<Student>();
}
public int Cid { get; set; }
public string CName { get; set; }
public Nullable<int> CCount { get; set; }
public string CImg { get; set; }
public string CIsdel { get; set; }
public Nullable<System.DateTime> Addtime { get; set; }
public ICollection<Student> Students { get; set; }
}
}

4.将EF查询出来的 EF实体集合 转换成 Dto(Data Transfer Object)数据传输类型

List<Models.DTO.StudentDTO> list = db.Students.Include("Class").OrderBy(s => s.StudentID)
.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList()
.Select(s => new Models.DTO.StudentDTO() {StudentID=s.StudentID,Cid=s.Cid}).ToList(); //将EF查询出来的 EF实体集合 转换成 Dto(Data Transfer Object)数据传输类型

.Select(s => new Models.DTO.StudentDTO() {StudentID=s.StudentID,Cid=s.Cid}).ToList();

//将EF查询出来的 EF实体集合 转换成 Dto(Data Transfer Object)数据传输类型

如果自己在类里面写个方法,把它转换为DTO,就不用每次写一样的这么麻烦了。所以我们在Models文件夹添加一个类

注意:

1.partial class Class

2.ClassPart.cs 返回类型是DTO.ClassDTO

3.StudentPart.cs 里面 Class = this.Class.ToDto()

这里要注意的是 StudentDTO.cs 类文件里面的 public ClassDTO Class { get; set; }

不然会报错,无法将类型“_06MVCAjax_CodeFirst.Models.DTO.ClassDTO”隐式转换为“_06MVCAjax_CodeFirst.Models.Class”

ClassPart.cs

ClassPart.cs
ClassPart.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace _06MVCAjax_CodeFirst.Models
{
public partial class Class
{
/// <summary>
/// 将 ED的班级对象转成 DTO 的班级对象
/// </summary>
/// <returns></returns>
public DTO.ClassDTO ToDto()
{
return new DTO.ClassDTO()
{
Cid = this.Cid,
CName = this.CName,
CCount = this.CCount,
CImg = this.CImg,
CIsdel = this.CIsdel,
Addtime = this.Addtime
};
}
}
}

StudentPart.cs

StudentPart.cs
StudentPart.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace _06MVCAjax_CodeFirst.Models
{ public partial class Student
{
/// <summary>
/// 将 EF Student实体转换成 DTO 学员实体
/// </summary>
public DTO.StudentDTO ToDto()
{
return new DTO.StudentDTO()
{
StudentID = this.StudentID,
Cid = this.Cid,
Name = this.Name,
Gender = this.Gender,
Isdel = this.Isdel,
AddTime = this.AddTime,
Class = this.Class.ToDto()
};
}
}
}

5.将数据封装到 PagedDataModel 实体

写个类PagedDataModel<T>

PagedDataModel.cs

PagedDataModel.cs
PagedDataModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace _06MVCAjax_CodeFirst.Models
{
/// <summary>
/// 分页数据实体
/// </summary>
public class PagedDataModel<T>
{
/// <summary>
/// 封装数据
/// </summary>
public List<T> PageData { get; set; }
/// <summary>
/// 页码
/// </summary>
public int PageIndex { get; set; }
/// <summary>
/// 页容量
/// </summary>
public int PageSize { get; set; }
/// <summary>
/// 总页数
/// </summary>
public int PageCount { get; set; }
/// <summary>
/// 总行数
/// </summary>
public int RowCount { get; set; }
}
}

6.将分页数据实体 封装到 json标准格式实体中

JsonModel.cs

JsonModel.cs
JsonModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace _06MVCAjax_CodeFirst.Models
{
/// <summary>
/// Json数据实体
/// </summary>
public class JsonModel
{
public object Data { get; set; }
public string Msg { get; set; }
public string Statu { get; set; }
public string BackUrl { get; set; }
}
}

7.最后的控制器里的List方法

StuController.cs

StuController.cs
StuController.cs

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Mvc; namespace _06MVCAjax_CodeFirst.Controllers
{
public class StuController : Controller
{
//
// GET: /Stu/ private Models.SingleTestContext db = new Models.SingleTestContext(); public ActionResult Index()
{
return View();
} //根据页码加载数据 此方法的Id其实是页码
public ActionResult List(int id)
{
//页码
int pageIndex = id;
//页容量
int pageSize = 2;
//2.1 根据页码获取分页数据 List<Models.DTO.StudentDTO> list = db.Students.Include("Class").OrderBy(s => s.StudentID)
.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList()
.Select(s => s.ToDto()).ToList(); //将EF查询出来的 EF实体集合 转换成 Dto(Data Transfer Object)数据传输类型 //2.2 获取总行数
int rowCount = db.Students.Count();
//2.3 计算总页数
int pageCount = Convert.ToInt32(Math.Ceiling((rowCount * 1.0) / pageSize)); //2.4 将数据封装到 PagedDataModel 实体
Models.PagedDataModel<Models.DTO.StudentDTO> dataModel = new Models.PagedDataModel<Models.DTO.StudentDTO>()
{
PageData = list,
PageCount = pageCount,
PageIndex = pageIndex,
PageSize = pageSize
RowCount = rowCount};
//2.5 将分页数据实体 封装到 json标准格式实体中
Models.JsonModel jsonModel = new Models.JsonModel()
{
Data = dataModel,
Msg = "成功",
Statu = "OK"
};
//System.Web.Script.Serialization.JavaScriptSerializer js = new System.Web.Script.Serialization.JavaScriptSerializer();
//string x = js.Serialize(jsonModel);
//2.6 生成json 格式数据,Json方法是Controller类(控制器类)提供的
//JsonRequestBehavior.AllowGet 一般啊只使用post传输,如果使用get,需要设置AllowGet
return Json(jsonModel, JsonRequestBehavior.AllowGet);
}
}
}

string x = js.Serialize(jsonModel);

MVC - 11(上).DTO

8.遇见的错误

8.1.get请求报错

MVC - 11(上).DTO

//2.6 生成json 格式数据,Json方法是Controller类(控制器类)提供的

//JsonRequestBehavior.AllowGet 一般啊只使用post传输,如果使用get,需要设置AllowGet

return Json(jsonModel, JsonRequestBehavior.AllowGet);

8.2.查询的时候没加ToList(),不识别ToDto()方法

MVC - 11(上).DTO

MVC - 11(上).DTO

显示结果查看下一篇:

MVC - 11(下).jquery.tmpl.js 接收JSON类型数据循环

MVC - 11(上).DTO的更多相关文章

  1. 返璞归真 asp&period;net mvc &lpar;11&rpar; - asp&period;net mvc 4&period;0 新特性之自宿主 Web API&comma; 在 WebForm 中提供 Web API&comma; 通过 Web API 上传文件&comma; &period;net 4&period;5 带来的更方便的异步操作

    原文:返璞归真 asp.net mvc (11) - asp.net mvc 4.0 新特性之自宿主 Web API, 在 WebForm 中提供 Web API, 通过 Web API 上传文件, ...

  2. MVC文件上传-使用jQuery&period;FileUpload和Backload组件实现文件上传

    本篇使用客户端jQuery-File-Upload插件和服务端Badkload组件实现多文件异步上传.MVC文件上传相关兄弟篇: 处理文件上传的服务端组件Backload 用于处理文件上传的服务端组件 ...

  3. ASP&period;NET MVC 文件上传和路径处理

    ASP.NET MVC 文件上传和路径处理总结 目录 文件的上传和路径处理必须解决下面列出的实际问题: 1.重复文件处理 2.单独文件上传 3.编辑器中文件上传 4.处理文章中的图片路径 5.处理上传 ...

  4. MVC文件上传与下载

    MVC文件上传与下载 MVC文件上传与下载 想想自己从毕业到工作也有一年多,以前公司的任务的比较重,项目中有的时候需要用到什么东西都去搜索一下,基础知识感觉还没有以前在学校中的好.最近开始写博客,真的 ...

  5. MVC 图片上传 带进度条(转)

    MVC 图片上传小试笔记 form.js 这个插件已经是很有名的,结合MVC的html辅助方法异步上传就很简单了.jQuery Form Plugin :http://www.malsup.com/j ...

  6. Newtonsoft&period;Json C&num; Json序列化和反序列化工具的使用、类型方法大全 C&num; 算法题系列&lpar;二&rpar; 各位相加、整数反转、回文数、罗马数字转整数 C&num; 算法题系列&lpar;一&rpar; 两数之和、无重复字符的最长子串 DateTime Tips c&num;发送邮件,可发送多个附件 MVC图片上传详解

    Newtonsoft.Json C# Json序列化和反序列化工具的使用.类型方法大全   Newtonsoft.Json Newtonsoft.Json 是.Net平台操作Json的工具,他的介绍就 ...

  7. MVC图片上传详解 IIS &lpar;安装SSL证书后&rpar; 实现 HTTP 自动跳转到 HTTPS C&num;中Enum用法小结 表达式目录树 &OpenCurlyDoubleQuote;村长”教你测试用例 引用provinces&period;js的三级联动

    MVC图片上传详解   MVC图片上传--控制器方法 新建一个控制器命名为File,定义一个Img方法 [HttpPost]public ActionResult Img(HttpPostedFile ...

  8. MVC文件上传07-使用客户端jQuery-File-Upload插件和服务端Backload组件裁剪上传图片

    本篇通过在配置文件中设置,对上传图片修剪后保存到指定文件夹. 相关兄弟篇: MVC文件上传01-使用jquery异步上传并客户端验证类型和大小  MVC文件上传02-使用HttpPostedFileB ...

  9. MVC文件上传06-使用客户端jQuery-File-Upload插件和服务端Backload组件自定义控制器上传多个文件

    当需要在控制器中处理除了文件的其他表单字段,执行控制器独有的业务逻辑......等等,这时候我们可以自定义控制器. MVC文件上传相关兄弟篇: MVC文件上传01-使用jquery异步上传并客户端验证 ...

随机推荐

  1. jQuery原生框架-----------------事件

    jQuery.extend({ // 绑定事件 addEvent: function( ele, type, fn ) { // ele不是DOM,type不是字符串,fn不是函数,打包打走 if( ...

  2. Odoo安装

    打开终端机0. sudo passwd root #设定超级使用者密码1. sudo apt-get update #更新软件源2. sudo apt-get dist-upgrade #更新软件包, ...

  3. 微信web页面返回刷新

    问题:在微信web页面开发的过程中,会遇到返回上一个页面数据没有刷新的情况. 解决方案:在该页面监控用户的浏览,每次加载都刷新页面. window.onpageshow = function(even ...

  4. 在delphi中生成GUID

    什么是 GUID ? 全球唯一标识符 (GUID) 是一个字母数字标识符,用于指示产品的唯一性安装.在许多流行软件应用程序(例如 Web 浏览器和媒体播放器)中,都使用 GUID. GUID 的格式为 ...

  5. Go-MySQL-Driver

    1.下载Go-Mysql-Driver go get github.com/go-sql-driver/mysql 2.引入import import( "database/sql&quot ...

  6. 从客户端&lpar;f&equals;&quot&semi;&lt&semi;zhaoyuntang&period;com&quot&semi;&rpar;中检测到有潜在危险的 Request&period;Form 值。

    从客户端(f="<yi733.com")中检测到有潜在危险的 Request.Form 值. 解决办法1:在aspx页面头部加 ValidateRequest="f ...

  7. Ubuntu终端点击确定按钮的方法

    Ubuntu终端里出现需要点击 确定 按钮的时候,直接鼠标点击 确定 是不生效的,这个时候需要利用tab键选中这个 确定 按钮,然后回车键就可以了.

  8. WPF中使用BitmapImage处理图片文件&lpar;转&rpar;

    (1)图片从文件导入 BitmapImage image = new BitmapImage(); image.BeginInit(); image.UriSource = new Uri(filen ...

  9. 【刷题】BZOJ 5008 方师傅的房子

    Description 方师傅来到了一个二维平面.他站在原点上,觉得这里风景不错,就建了一个房子.这个房子是n个点的凸多边形 ,原点一定严格在凸多边形内部.有m个人也到了这个二维平面.现在你得到了m个 ...

  10. HDUOJ-------1753大明A&plus;B(大数之小数加法)

    大明A+B Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...