ASP.NET MVC--控制器

控制器

Controller给View传递数据的方式

1,ViewData:

ViewData["name"]="rupeng";
string s =(string)ViewData["name"]

这样的键值对的方式进行数据传送

2,ViewBag:
    ViewBag是dynamic类型的参数,是对ViewData一个动态类型封装,用起来更方便,和ViewData共同操作一个数据。

ViewBag.name="";
@ViewBag.name。

用ViewBag传递数据非常方便,但是因为ASP.Net MVC中的“Html辅助类”等对于ViewBag有一些特殊约定,一不小心就跳坑了(http://www.cnblogs.com/rupeng/p/5138575.html),所以尽量不要用ViewBag,而是使用Model。

3、Model:
    可以在Controller中通过return View(model)赋值,然后在cshtml中通过Model属性来访问这个对象;
    如果在cshtml中通过“@model 类型”(注意model小写)指定类型,则cshtml中的Model就是指定的强类型的,这样的cshtml叫“强类型视图”;
    如果没有指定“@model 类型”, 则cshtml中的Model就是dynamic。

Action的参数

ASP.Net MVC5会自动对参数做类型转换
对于boolean类型的参数(或者Model的属性),如果使用checkbox,则value必须是“true”,否则值永远是false。对于double、int等类型会自动进行类型转换
一个Controller可以有多个方法,这些方法叫Action。通过“Controller名字/方法名”访问的时候就会执行对应的方法。
Action的三种类型的参数:
普通参数、Model类、FormCollection
1,普通参数:
      Index(string name,int age)。框架会自动把用户Get请求的QueryString或者Post表单中的值根据参数名字映射对应参数的值,
      适用于查询参数比较少的情况。
      注意:int类型的可空问题
2,Model类。叫ViewModel。

3,FormCollection,采用fc[“name”]这种方法访问,类似于HttpHandler中用context[“name”]。适用于表单元素不确定、动态的情况

4,Action的方法不能重载,所以一个Controller中不能存在两个同名的Action
错误代码:
public ActionResult T1(string name)和public ActionResult T1(int Age)不能同时存在

特殊情况:
给Action方法上标注[HttpGet]、[HttpPost],注意当发出Get或者Post请求的时候就会执行相应标注的方法,变相实现了同名的Action

常见的应用方法:
把需要展示的初始页面的Action标注为[HttpGet],把表单提交的标注为[HttpPost]

5,Action参数可以一部分是普通参数,一部分为Model代码示例:

public ActionResult T1(string name,Classes className)

6,Action参数如果在请求中没有对应的值,就会去默认值:
    Model类的形式则取默认值:int是0、boolean是false、引用类型是null。
    普通参数的形式:取默认值会报错,如果允许为空,要使用int?,也可以使用C#的可选参数语法来设定默认值 示例代码:

Index(string name="tom");

7,上传文件的参数用HttpPostedFileBase类型,

View的查找

1,return View()会查找Views的Controller名字的Action的名字的cshtml

2,return View(“Action1”),查找Views的Controller名字下的“Action1.cshtml”,如果找不到则到特殊的shared文件夹下找“Action1.cshtml”

3、return View(“Action1”)中如何传递model?return View(“Action1”,model)。
   陷阱:如果model传递的是string类型,则需要return View(“Action1”,(object)str)为什么?看一下重载!
   注意:
      return View(“Action1”)不是重定向,浏览器和服务器之间只发生了一次交互,地址栏还是旧的Action的地址。
      这和重定向return Redirct(“/Index/Action1”);不一样
   应用:
      执行报错,return View(“Error”,(object)msg) 通用的报错页面。为了防止忘了控制重载,封装成一个通用方法。

其他类型的ActionResult

1,View()是一个方法,它的返回值是ViewResult类型,ViewResult继承自ActionResult,如果在确认返回的是View(),返回值写成ViewResult也行,但是一般没这个必要,因为那样就不灵活了。因为ViewResult还有其他子类

2,RedirectResult,重定向,最终就是调用response.Redirect()。用法:

return Redirect("http://www.rupeng.com");//重定向到rupeng
return Redirect("~/1.html");//重定向到

3,ContentResult 返回程序中直接拼接生成的文本内容

return Content(string content,string contentType)

4,文件 return File();
  1,return File(byte[] fileContents,string contentType);//返回byte[]格式的数据
  2,return File(byte[] fileContents,string contentType,fileDownLoadName);//fileDownLoadName:设定浏览器端弹出的建议保存的文件名
  3,return File(Stream fileStream, string contentType) 返回Stream类型的数据(框架会帮着Dispose,不用也不能Dispose)
  4,FileStreamResult
    return File(Stream fileStream,string contentType,string fileDownLoadName)
  5, File(string fileName, string contentType)// 返回文件名指定的文件,内部还是流方式读取文件;
  6, File(string fileName, string contentType, string fileDownloadName)
  //如果是返回动态生成的图片(比如验证码),则不用设置fileDownloadName;如果是“导出学生名单”、“下载文档”等操作则要设定fileDownloadName。
  注意:如果在Controller中要使用System.IO下的File类,因为和File方法重名了,所以要用命名空间来引用了。
  
5,return HttpNotFound();

6,return JavaScript(string script);
    返回JavaScript代码字符串,和return Content(“alert(‘Hello World’);”,“application/x-javascript”);效果一样。
    因为违反三层原则,尽量不要使用

7,Json
    JsonResult Json(object data) 把data对象序列化为json字符串返回客户端,并且设置contentType为"application/json"

Json方法默认是禁止Get请求的(主要为了防止CSRF攻击,举例:在A网站中嵌入一个请求银行网站给其他账号转账的Url的img),只能Post请求。所以如果以Get方式访问是会报错的。
    如果确实需要以Get方式方式,需要调用return Json(data, JsonRequestBehavior.AllowGet)
    ASP.NET MVC 默认的Json方法实现有如下的缺点:
      1,日期类型的属性格式化成字符串是“/Date(1487305054403)/"这样的格式,在客户端要用js代码格式化处理,很麻烦。
      2,json字符串中属性的名字和C#中的大小写一样,不符合js中“小写开头、驼峰命名”的习惯。在js中也要用大写去处理。
      3,无法处理循环引用的问题(尽管应该避免循环引用),会报错“序列化类型为***的对象时检测到循环引用”
      
8,重定向
    1,Redirect(string url)
    2,RedirectToAction(string actionName,string controllerName);//其实就是帮助拼接生成url,最终还是调用Redirect(),
    3,两者的区别:
      RedirectToAction是让客户端重定向,是一个新的Http请求,所以无法读取ViewBag中的内容;
      return View()是一次服务器一次处理转移
      Redirect和return View 的区别:
        1、 Redirect是让浏览器重定向到新的地址;return View是让服务器把指定的cshtml的内容运行渲染后给到浏览器;
        2、 Redirect浏览器和服务器之间发生了两次交互;return View浏览器和服务器之间发生了1次交互
        3、 Redirect由于是两次请求,所以第一次设置的ViewBag等这些信息,在第二次是取不到;而View则是在同一个请求中,所以ViewBag信息可以取到。
        4、 如果用Redirect,则由于是新的对Controller/Action的请求,所以对应的Action会被执行到。如果用View,则是直接拿某个View去显示,对应的Action是不执行的。

什么情况用View?服务器端产生数据,想让一个View去显示的;
什么情况用Redirect?让浏览器去访问另外一个页面的时候。

TempData

在SendRedirect客户端重定向或者验证码等场景下,由于要跨请求的存取数据,是不能放到ViewBag、Model等中,需要“暂时存到Session中,用完了删除”的需求:实现起来也比较简单:存入:

Session["verifyCode"] = new Random().Next().ToString();

读取:

String code = (string) Session["verifyCode"];
Session["verifyCode"] = null;
if(code==model.Code)
{
	//...
}

ASP.Net MVC中提供了一个TempData让这一切更简单。在一个Action存入TempData,在后续的Action一旦被读取一次,数据自动销毁。
TempData默认就是依赖于Session实现的,所以Session过期以后,即使没有读取也会销毁。
应用场景:验证码;

View公共引用

Views的web.config中的system.web.webpages.razor的pages/namespaces节点下配置add命名空间,这样cshtml中就不用using了 示例代码:

<system.web.webPages.razor>
	<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
	<pages pageBaseType="System.Web.Mvc.WebViewPage">
		<namespaces>
			<add namespace="System.Web.Mvc" />
			<add namespace="System.Web.Mvc.Ajax" />
			<add namespace="System.Web.Mvc.Html" />
			<add namespace="System.Web.Routing" />
			<add namespace="Test1" />
		</namespaces>
	</pages>
</system.web.webPages.razor>

Layout布局文件

@RenderBody()渲染正文部分;cshtml的Layout属性设定Layout页面地址;
@RenderSection(“Footer”)用于渲染具体页面中用@section Footer{}包裹的内容,如果Footer是可选的,那么使用@RenderSection(“Footer”,false),可以用IsSectionDefined(“Footer”)实现“如果没定义则显示***”的效果。
可以在Views文件夹下建一个_ViewStart.cshtml文件,在这个文件中定义Layout,这样不用每个页面中都设定Layout,当然具体页面也可以通过设定Layout属性来覆盖默认的实现;

@Html.DropDownList

如果在页面中输出一个下拉列表或者列表框,就要自己写foreach拼接html,还要写if判断哪项应该处于选中状态

<select>
	@foreach(var p in (IEnumerable<Person>)ViewBag.list)
	{
		<option selected="@(p.Id==3)">@p.Name</option>
	}
</select>

asp.net mvc中提供了一些“Html辅助方法”(其实就是Controller的Html属性中的若干方法,其实是扩展方法)用来简化html代码的生成。DropDownList是生成下拉列表的。

DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable selectList)
string name参数用来设定 标签的name属性的值,id属性的值默认和name一致。
下拉列表中的项()以SelectListItem集合的形式提供,SelectListItem的属性:
bool Selected:是否选中状态,也就是是否生成selected="selected"属性;
string Text:显示的值,也就是的innerText部分;
string Value:生成的value属性,注意是string类型;

示例代码:

List<Person> list = new List<Person>();
list.Add(new Person { Id=1,Name="lily",IsMale=false});
list.Add(new Person { Id = 12, Name = "tom", IsMale = true });
List<SelectListItem>sliList = new List<SelectListItem>();
foreach (var p in list)
{
    SelectListItem listItem = new SelectListItem();
    listItem.Selected = (p.Id==2);
    listItem.Text = p.Name;
    listItem.Value = p.Id.ToString();
    sliList.Add(listItem);
}
return View(sliList);
@model IEnumerable<SelectListItem>
<!DOCTYPE html>
<html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>DDL</title>
    </head>
    <body>
        <div>
            @Html.DropDownList("pid", Model);
        </div>
    </body>
</html>

DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable selectList, object htmlAttributes) htmlAttributes属性用来生成select标签的其他属性,通常以匿名类对象的形式提供,比如new { onchange = “javascript:alert(‘ok’)”, style = “color:red”, aaa = “rupeng”, id = “yzk”,@class=“warn error” } 生成的html源码为:

<select aaa="rupeng" class="warn error" id="yzk" name="pid" onchange="javascript:alert(&#39;ok&#39;)" style="color:red">

支持自定义属性,给你原样输出,具体什么含义自己定;
由于class是关键字,所以不能直接用class=“”,要加上一个@前缀,这其实是C#中给变量名取名为关键字的一种语法;
注意:id默认和name一致,如果设定了id则覆盖默认的实现。

构造一个特殊的集合类SelectList,他会自动帮着做集合的遍历

public ActionResult DDL2()
{
    List<Person>list = new List<Person>();
    list.Add(new Person { Id=666,Name="zhangsan",IsMale=false});
    list.Add(new Person { Id = 222, Name = "tom", IsMale = true });
    SelectList selectList = new SelectList(list, "Id", "Name");
    return View(selectList);
}
@Html.DropDownList("name", (SelectList)Model);

IEnumerable items参数用来显示的原始对象数据,string dataValueField为“对象的哪个属性用做生成value属性”,string dataTextField为“对象的哪个属性用作生成显示的文本属性”。
用SelectList的好处是简单,但是如果说要同时显示多个属性的时候,就只能用非SelectList的方式了。
SelectList还可以设定第四个参数:
哪个值被选中:SelectList selectList = new SelectList(list,“Id”,“Name”,222);
一个坑:
不能让cshtml中的DropDownList的第一个name参数和ViewBag中任何一个属性重名
建议不要通过ViewBag传递,都通过Model传递

@Html.ListBox()和@Html.DropDownList()类似

为什么不再推荐使用“Html辅助方法”

坏处:因为不符合复杂项目的开发流程(前端程序员可能看不懂),

好处:可以把表单验证、绑定等充分利用起来,开效率高,但是在互联网项目中开发效率并不是唯一关注因素。在asp.net mvc6中已经不再推荐使用html辅助方法的表单了

Request.IsAjaxRequest()

判断是来自于Ajax请求,这样可以让ajax请求和非ajax请求响应不同的内容
原理:
Ajax请求的报文头中有x-requested-with: XMLHttpRequest。
如果使用System.Web.HttpContext,那么是没有这个方法的,那么自己就从报文头中取数据判断。
示例代码:

public ActionResult Ajax1()
{
    return View();
}
public ActionResult Ajax2()
{
    Person p = new Person();
    p.Name = "rupeng";
    if (Request.IsAjaxRequest())
    {
        return Json(p);
    }
    else
    {
        return Content(p.Name);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sufengmarket

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值