42.1 ASP.NET MVC

路由机制 网络介绍链接

按照传统,在很多Web框架中(如经典的ASP、JSP、PHP、ASP.NET等之类的框架),URL代表的是磁盘上的物理文件。例如,当看到请求http://example.com/albums/list.aspx时,我们可以确定该站点目录结构中含有一个albums文件夹,并且在该文件夹下还有一个list.aspx文件。

URL和文件系统之间这种一一对应的关系并不适用于大部分基于MVC的Web框架,如ASP.NET MVC.一般来说,这些框架采用不同的方法将URL映射到某个类上的方法调用,而不是映射到磁盘上的物理文件。

另外,对于MVC应用程序,URL 请求到达的第一个组件是控制器而不是视图,而控制器是没有物理路径的

控制器方法不能重载

路由是从上到下的优先级的!所有

routes.MapRoute("showBlogRoute",
"blog/post/{id}",
new { controller =“CMS”,action = “Show”,id=“”});//如果参数2是POST,则匹配这一条显示这个控制器 routes.MapRoute("blogRoute",
“blog/{action}/{id}",
new { controller = "CMS", action = “Index", id = “”});//除名为POST的参数都显示这个方法 routes.MapRoute(“DefaultRoute”, // 路由名称
"{controller}/{action}/{id}", // 带有参数的 URL
new { controller = "Home", action = "Index", id =“”} // 参数默认值
);

如上代码反过来!则不会匹配到"blog/post/{id}",这一条,直接匹配最后一条

Constraints属性是一个包含针对URL参数的验证规则的字典,就是说,它是用来限定每个参数的规则或Http请求的类型的

使用正则表达式来定义约束,比如下面的例子,如果希望以正确的格式(只允许数字值)指定年月日(正则式)

routes.MapRoute("simple",
"archive/{year}/{month}/{day}",
new{controller="blog",action="search",year="",month="",day=""},
Constraints: new{
year=@"\d{2}|\d{4}",//只能是两位或四位数字,这里的year对应到url里的year
month=@"\d{1,2}",//只能使用一位或两位数字
day=@"\d{1,2}"//只能使用一位或两位数字
});

42.3创建控制器

42.3.2参数

一个参数

public ActionResult test(string name)
{
ViewBag.Message = "测试信息:" + name; //当打开http://localhost/Home/test?name=88832564时 name的值就等于88832564
return View();//<h3>@ViewBag.Message</h3>显示于ViewBag.Message的值
}

多个参数

public string test(int x ,int y)//取路由的参数值(id必须对应路由)
{
return "测试信息:" +(x * y);//url应该为:home/test?x=5&y=8 中间用:“&”
}

以路由参数取值时可用

public ActionResult test(string id)//取路由的参数值(id必须对应路由)
{
ViewBag.Message = "测试信息:" + id; // 这里可以使用home/test?id=regfgfdg或/home/test/regfgfdg
return View();//<h3>@ViewBag.Message</h3>显示于ViewBag.Message的值
}

42.3.3返回数据

public ActionResult test()//取路由的参数值(id必须对应路由)
{
//return Content("hello world","text/plain");//返回无格式正文字符串
//return JavaScript("<script>function foo {alert('foo');}</script>");//返回JavaScript脚本
//return Redirect("http://www.126.com");//跳转网站 重定向
//return RedirectToRoute(new { controller = "Home", action = "About" });//重定向路由
return File("~/Content/Images/timg.jpg", "image/jpg"); //返回文件对象
}
public ActionResult JsonDemo() //反回JSON数据
{
var m = new Menu
{
Id = ,
Text = "Grilled sausage with sauerkraut und potatoes",
Price = 12.90,
Category = "Main"
};
return Json(m, JsonRequestBehavior.AllowGet);
} //以下是menu类
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
public class Menu
{
public int Id { get; set; }
[Required, StringLength()]
public string Text { get; set; }
[DisplayName("Price"), DisplayFormat(DataFormatString = "{0:C}")]
public double Price { get; set; }
[DataType(DataType.Date)]
public DateTime Date { get; set; }
[StringLength()]
public string Category { get; set; }
}

42.4.1 向视图传递数据

在控制器里用ViewBag.data设置在视图里用@ViewBag.data取得,可以理解决ViewBag是一个类或数组,视图通过其进行设置

42.4.2 Razor语法

相关的语法 链接 以下是视图里的相关写法 在ASPX语法中使用<%:ViewBag.MyData %>

@{ //这里可以插入代码
@ViewBag.Message; //这里输出相关字符串
}

42.4.3强类型视图

public ActionResult test()//
{
var menus = new List<Menu>
{
new Menu { Id=, Text="Schweinsbraten mit Knödel und Sauerkraut",Price=6.9, Category="Main" },
new Menu { Id=, Text="Erdäpfelgulasch mit Tofu und Gebäck",Price=6.9, Category="Vegetarian" },
new Menu { Id=, Text="Tiroler Bauerngröst'l mit Spiegelei und Krautsalat", Price=6.9, Category="Main" }
};
return View(menus);//传递menus类给视图

using声明类结构,在视内用model关键之际定义模型,此模型的类型为IEnumerable<Menu>

@using MyWeb.Models
@model IEnumerable<Menu> <div>
<ul>
@foreach (var item in Model)
{
<li>@item.Text</li>
}
</ul>
</div>

42.4.4布局

如果视图不显示布局则使用用

@{
Layout = null;
}

1、默认布局

_ViewStart.cshtml为页面包含全部视图的默认配置 Layout属性设定为共享布局页

布局页:@ReanderBody()为主体 @ViewBag.Title为标提

2、使用分页

布局页写入:@RenderSection("PageNavigation", required: false)
视图页:在代码域中写入HTML分页代码
@section PageNavigation
{
<div>Navigation defined from the view</div>
}

42.4.5部分视图

部分视图示例要使用的结构类存放于Models

public class EventsAndMenus
{
private IEnumerable<Event> events = null;
public IEnumerable<Event> Events
{
get
{
return events ?? (events = new List<Event>()
{
new Event { Id=, Text="Formula 1 G.P. Abu Dhabi, Yas Marina",Day=new DateTime(, , ) },
new Event { Id=, Text="Formula 1 G.P. USA, Austin",Day = new DateTime(, , ) },
new Event { Id=, Text="Formula 1 G.P. Brasil, Sao Paulo",Day = new DateTime(, , ) }
}
);
}
}
private List<Menu> menus = null;
public IEnumerable<Menu> Menus
{
get
{
return menus ?? (menus = new List<Menu>()
{
new Menu { Id=, Text="Baby Back Barbecue Ribs", Price=16.9,
Category="Main" },
new Menu { Id=, Text="Chicken and Brown Rice Piaf", Price=12.9,
Category="Main" },
new Menu { Id=, Text="Chicken Miso Soup with Shiitake Mushrooms",
Price=6.9, Category="Soup" }
});
}
}
}

1、使用服务器端代码中的部分视图

下面的方法是把结构类数据通过控制器发给视图,视图通把结构类数据发给部分视图然后显示出来

// 控制器
public ActionResult test()//
{
return View(new EventsAndMenus());
} //视图,把结构体Model.Events传给viewtes部分视图
@model MyWeb.Models.EventsAndMenus @{
ViewBag.Title = "UseAPartialView21";
} <h2>UseAPartialView1</h2>
<div>this is the main view</div>
<div>
@Html.Partial("viewtest", Model.Events)
</div> //部分视图中:viewtest.cshtml
@using MyWeb.Models
@model IEnumerable<Event>
<h2>
@ViewBag.EventsTitle
</h2>
<table>
@foreach (var item in Model)
{
<tr>
<td>@item.Day.ToShortDateString()</td>
<td>@item.Text</td>
</tr>
}
</table>

2、从控制器中返回部分视图

以下是通过视图调用控制器方法的返回Html代码然后显示在视图里

//视图页:test1.cshtml,调用Viewtest方法的结果返回Html
@Html.Action("viewtest") //控制器:
public ActionResult viewtest()
{
ViewBag.EventsTitle = "Live Events";
return PartialView(new EventsAndMenus().Events);
} //部分视图:viewtest.cshtml
@using MyWeb.Models
@model IEnumerable<Event>
<h2>
@ViewBag.EventsTitle
</h2>
<table>
@foreach (var item in Model)
{
<tr>
<td>@item.Day.ToShortDateString()</td>
<td>@item.Text</td>
</tr>
}
</table>

3、在JQuery中调用部分视图

<script>
  $(function () {
    $("#getEvents").click(function () {
      $("#events").load("/ViewsDemo/ShowEvents");
    });
  });
</script>

<button id="getEvents">Get Events</button>

<div id="events"></div>

42.5 从客户端提交数据

45.5.1模型绑定:方法是从视图提交表单的处理方法!直接模型绑定到Menu类中,然后返回视图

视图页:CreateMenu.cshtml
@{
ViewBag.Title = "Create Menu";
}
<h2>Create Menu</h2>
<form action="/SubmitData/CreateMenu" method="post">
<fieldset>
<legend>Menu1</legend>
<div>Id:</div>
<input name="id" />
<div>Text:</div>
<input name="text" />
<div>Price:</div>
<input name="price" />
<div>Category:</div>
<input name="category" />
<div></div>
<button type="submit">Submit</button>
</fieldset>
</form> 控制器:
[HttpPost]//这里限制方法为HttpPost请求
public ActionResult CreateMenu(Menu m)
{
//var m = new Menu { Id = id, Text = text, Price = price };
    ViewBag.Info = string.Format(
"menu created: {0}, Price: {1}, category: {2}", m.Text, m.Price,
m.Category);
return View("Index");
} 视图页:index.cshtml
<h2>Index</h2>

上面代码可以改为:(以下方法如果有一些不应该更新的属性就不应该使用UpdateModel方法,否则用户可以恶意修改请求更新这些属性)

[HttpPost]//这里限制方法为HttpPost请求
public ActionResult CreateMenu2()
{
var m = new Menu();
UpdateModel<Menu>(m);//使用来自控制器的当前值提供程序的值更新指定的模型实例
ViewBag.Info = string.Format(
"menu created: {0}, Price: {1}, category: {2}", m.Text, m.Price,
m.Category);
return View("Index");
}
视图中改为:<form action="/SubmitData/CreateMenu2" method="post">

42.5.2注释与验证

在模型绑定中通过

if (ModelState.IsValid)//获取包含模型状态和模型绑定验证状态的模型状态字典对象。

来判定模型状态 模型状态通过[StringLength(10)]来验证

当模型为工具生成时,则在别外新增一个MenuMetadata属性与模型相同的有验证的!!

public class MenuMetadata
{
public int Id { get; set; }
[Required, StringLength()]
public string Text { get; set; }
[DisplayName("Price"), DisplayFormat(DataFormatString = "{0:C}")]
public double Price { get; set; }
[DataType(DataType.Date)]
public DateTime Date { get; set; }
[StringLength()]
public string Category { get; set; }
}
//在用工具生的模型的类前面添加
[MetadataType(typeof(ManuMatadata))]
public partial class Menu
{
}

42.6 HTML Helper

帮助文链接 相关说明请查网上  下面为常用的一些代码

  • Html.Actionlink(显示名称,方法)链接到操作方法
  • Html.Action(方法名)返回方法的结果的HTML代码
  • Html.Partial(部分视图页,数据)把数据传递到部分视图页显示并返回
  • Html.DisplayName(显示字符串)
  • Html.Display('模型的名称') 显示模型中相关名称的数据
  • Html.TextBox("Html控件id","值",new{required="required",maxlength=15,@class="CssDemo"}) 定义TextBox控件
  • Html.EditorFor(m=>m)返回表达式中每个属性对应的Html元素
  • Html.EditorForModel()返回模型中返有属性对应的Html元素
  • @using Html.BeginForm("方法名", "控制器名", FormMethod.Post)  {这里为表单,<input type="submit" name="BtnSubmit" value="Login" />} 把表单发送给控制器
  • Html.RenderAction(方法)  ,这里理解只返回方法的结果的意思
  • Html.RenderPartial("部分视图",模型)  可以理解这里是返回视图,

42.6.4创建列表 (下拉列表)

public static class SelectListItemsExtensions //自定义扩展方法
{
public static IEnumerable<SelectListItem> ToSelectListItems(this IDictionary<int, string> dict, int selectedId)
{
return dict.Select(item =>
new SelectListItem
{
Selected = item.Key == selectedId,
Text = item.Value,
Value = item.Key.ToString()
}
);
}
}
public ActionResult test()//控制器方法
{
var cars = new Dictionary<int, string>();
cars.Add(, "Red Bull Racing");
cars.Add(, "Mclaren");
cars.Add(, "sgvd");
return View(cars.ToSelectListItems());
} //视图显示
@model IEnumerable<SelectListItem>
@Html.DropDownList("carslist", Model)

42.6.5强类型化的helper

从控制器传到视图时  相关的链接

@model MyWeb.Models.Menu
@Html.TextBoxFor(m=>m.Text)

24.6.7自定义helper

视图页:通过DispayDay(Model.Date)把模型传致上面的方法中

@model MyWed.Models.Menu
@helper DispayDay(DateTime day)
{
if (day < DateTime.Parse("2018-1-16 2:28:22"))
{
<span>历史日期</span>
}
@String.Format("{0:d}", day);
}
@Html.DisplayFor(m => m.Text)
@DispayDay(Model.Date)

24.6.8 模板

视图中通过DisplayForModel()来显示模板或DisplayFor(m => m.Date)

在视图下面新建DisplayTemplates文件夹,或在共享文件Shared下面新建DisplayTemplates方件夹,在DisplayTemplates方件夹新建类型模板,如Date类型:在目录下新建Date.cshtml,内容如下:

<div class="markRed">
@string.Format("{0:D}", Model)
</div>

Content里面Site.css更改样式:

.markRed{
color:#ff0000;
}

而模型里面

[DataType(DataType.Date)]

注:因EF的问题,转到学习"7天玩转MVC"

C#高级编程42章 MVC的更多相关文章

  1. C# 6 与 .NET Core 1.0 高级编程 - 38 章 实体框架核心(上)

    译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 38 章 实体框架核心(上)),不对的地方欢迎指出与交流. 章节出自<Professional C# 6 ...

  2. C# 6 与 .NET Core 1.0 高级编程 - 38 章 实体框架核心(下)

    译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 38 章 实体框架核心(下)),不对的地方欢迎指出与交流. 章节出自<Professional C# 6 ...

  3. C# 6 与 .NET Core 1.0 高级编程 - 39 章 Windows 服务(下)

    译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 39 章 Windows 服务(下)),不对的地方欢迎指出与交流. 章节出自<Professional C ...

  4. C#高级编程9-第12章 动态语言扩展

    C#高级编程9-第12章 动态语言扩展 dynamic t = new ExpandoObject(); t.Abc = "abc"; t.Value = ; Console.Wr ...

  5. C# 6 与 .NET Core 1.0 高级编程 - 37 章 ADO.NET

    译文,个人原创,转载请注明出处,有不对的地方欢迎指出与交流. 英文原文:Professional C# 6 and .NET Core 1.0 - 37 ADO.NET --------------- ...

  6. C# 6 与 .NET Core 1.0 高级编程 - 39 章 Windows 服务(上)

    译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 39 章 Windows 服务(上)),不对的地方欢迎指出与交流. 章节出自<Professional C ...

  7. C#高级编程9-第8章 委托、lamdba表达式和事件

    委托.lamdba表达式和事件 1.引用方法 函数指针是一个指向内存位置的指针,不是类型安全的.无法判断实际指向.参数和返回类型也无从知晓..NET委托是类型安全的.定义了返回类型和参数类型,不仅包含 ...

  8. C#高级编程9-第13章 异步编程

    异步编程 1)异步编程的重要性 在C#5.0中提供了关键字:async和await 使用异步编程后台运行方法调用,程序的运行过程中就不会一直处于等待中.便于用户继续操作. 异步编程有3种模式:异步模式 ...

  9. C#高级编程9-第1章.NET体系结构

    C#与NET的关系 C#编写的所有代码必须使用.NET FrameWork运行 C#是一种语言,但它本身不是.NET的一部分 C#一些特性,.NET不支持,.NET一些特性,C#不支持 公共语言运行库 ...

随机推荐

  1. NOIp 数学知识点总结

    推荐阅读 NOIp 基础数论知识点总结: https://www.cnblogs.com/greyqz/p/number.html 排列组合 常用公式 排列:\[\displaystyle A_n^m ...

  2. HTTP请求时候总是设置的两个参数ConnectionTimeOut和SocketTimeOut

    在HTTP请求时候总是设置两个参数,就是连接超时和Socket超时 public static final String SO_TIMEOUT = "http.socket.timeout& ...

  3. “美登杯”上海市高校大学生程序设计 E. 小花梨的数组 (线段树)

    https://acm.ecnu.edu.cn/contest/173/problem/E/ 分析: 考虑这样一种情况,如果对一个点连续地做几次乘操作,那么之后紧跟着的除操作只需要将乘操作的次数减少即 ...

  4. C#调取接口时报错:服务器提交了协议冲突. Section=ResponseStatusLine

    private Dictionary<string, Object> GetLocation(string imei) { #region===代码=== string serviceAd ...

  5. Eclipse + pydev插件

    在Eclipse中安装pydev插件 启动Eclipse, 点击Help->Install New Software...   在弹出的对话框中,点Add 按钮.  Name中填:Pydev,  ...

  6. ping局域网主机得到外网IP或另一网段IP

    症状::两个笔记本连接到同一个路由器上, 一个ip是 192.168.1.100,主机名是Lenovo-A, 另一个是192.168.1.109,主机名是Lenovo-B 在Lenovo-A 上pin ...

  7. Dedecms织梦后台登陆验证码不显示几种解决方法

    Dedecms织梦后台登陆验证码不显示几种解决方法,服务器所造成的验证码不显示问题看这里: 方法一:查看服务器的php版本是否与程序版本兼容(织梦程序PHP版本查看方法:打开www.96net.com ...

  8. A AFei Loves Magic

    链接:https://ac.nowcoder.com/acm/contest/338/A来源:牛客网 题目描述 AFei is a trainee magician who likes to stud ...

  9. Leetcode Lect3 时间复杂度/空间复杂度

    时间复杂度 复杂度 可能对应的算法 备注 O(1) 位运算 常数级复杂度,一般面试中不会有 O(logn) 二分法,倍增法,快速幂算法,辗转相除法   O(n) 枚举法,双指针算法,单调栈算法,KMP ...

  10. k3 cloud中列表字段汇总类型中设置了汇总以后没有显示出汇总值

    处理方法,需要bos中的分组列信息中设置求和: 选择对应字段将其从左侧添加到右侧 方法二: 直接针对[价税合计]字段的列表汇总类型进行设置,步骤如下图所示