<Pro ASP.NET MVC 5> - Note02

50 篇文章 0 订阅
17 篇文章 0 订阅

CHAPTER 3: The MVC Pattern


Building Loosely Coupled Components


  1. Implement an interface that defines all of the public functions required.
  2. By introducing interface, I ensure that there is no direct dependency between the function user and its implementation.


Using Dependency Injection


Breaking and Declaring Dependencies

public class PasswordResetHelper {
	private IEmailSender emailSender;
	public PasswordResetHelper(IEmailSender emailSenderParam) {
		emailSender = emailSenderParam;
	}
	public void ResetPassword() {
		// ...call interface methods to configure e-mail details...
		emailSender.SendEmail();
	}
}


Injecting Dependencies



Using a Dependency Injection Container

  1. I register the set of interfaces or abstract types that my application uses with the DI container, and specify which implementation classes should be instantiated to satisfy dependencies.
  2. The DI container puts information together, creates the MyEmailSender object and then uses it as an argument to create a PasswordResetHelper object, which I am then able to use in the application.
  3. It is important to note that I no longer create the objects in my application myself using the new keyword. Instead, I go to the DI container and request the objects I need.
  4. Ninject, you can get details at www.ninject.org.


Getting Started with Automated Testing


Understanding Unit Testing


Understanding Integration Testing

Selenium RC (http://seleniumhq.org/), which consists of a Java "server" application that can send automation commands to Internet Explorer, Firefox, Safari, or Opera, plus clients for .NET, Python, Ruby, and multiple others so that you can write test scripts in the language of your choice. Selenium is powerful and mature; its only drawback is that you have to run its Java server.



CHAPTER 6: Essential Tools for MVC


Using Ninject

The idea is to decouple the components in an MVC application, with a combination of interfaces and DI container that creates instances of objects by creating implementations of the interfaces they depend on and injecting them into the constructor.


CHAPTER 21: 辅助方法

这一章讲的辅助方法是HTML的辅助方法。


定制辅助方法


内联方法

直接见下面的示例代码好了:

@model string
@{
  Layout = null;
}
@helper ListArrayItems(string[] items) {
  foreach(string str in items) {
    <b>@str</b>
  }
}
<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width" />
    <title>Index
    </title>
  </head>
  <body>
    <div>
      Here are the fruits: @ListArrayItems(ViewBag.Fruits)
    </div>
    <div>
      Here are the cities: @ListArrayItems(ViewBag.Cities)
    </div>
    <div>
      Here is the message:
      <p>@Model</p>
    </div>
  </body>
</html>

这个做法的好处就是,不用在HTML里一直重复foreach代码块,这其实应该说是所有辅助方法的用意吧。


外部方法

这个就复杂点,先要定义一个静态C#类,里面定义一个静态方法:

using System.Web.Mvc;
namespace HelperMethods.Infrastructure {
 public static class CustomHelpers {
  public static MvcHtmlString ListArrayItems(this HtmlHelper html, string[] list) {
   TagBuilder tag = new TagBuilder("ul");
   foreach(string str in list) {
    TagBuilder itemTag = new TagBuilder("li");
    itemTag.SetInnerText(str);
    tag.InnerHtml += itemTag.ToString();
   }
   return new MvcHtmlString(tag.ToString());
  }
 }
}


这类方法是定义在HtmlHelper上的扩展方法,所以第一个参数是以this修饰的HtmlHelper对象,HtmlHelper上面其实定义了很多有用的属性,用来访问一些上下文或者全局信息,如下:

  • RouteCollection
  • ViewBag
  • ViewContext

ViewBag就是Controller用来给view传数据的那个东西。ViewContext则非常有用,它提供了大多数时候我们需要访问的信息,包括:

  • Controller
  • HttpContext
  • IsChildAction
  • RouteData
  • View


HTML辅助方法的主要任务就是根据接收的参数生成相应的HTML片段,所以它的返回类型是MvcHtmlString。


TagBuilder类就是用来帮助程序员方便控制生成的HTML片段的。它有两个属性很常用:

  • InnerHtml
  • Attributes

还有几个方法:

  • SetInnerText(string)
  • AddCssClass(string)
  • MergeAttribute(string, string, bool)


最后,通常的做法是利用TagBuilder的ToString()方法和MvcHtmlString的构造函数来生成一个MvcHtmlString对象并将它返回,其实另外也可以用MvcHtmlString.Create()来生成返回值。


好了,现在来看看如何使用上面定义的外部辅助函数:

@model string
@using HelperMethods.Infrastructure
@{
  Layout = null;
}
<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
  </head>
  <body>
    <div>
      Here are the fruits: @Html.ListArrayItems((string[])ViewBag.Fruits)
    </div>
    <div>
      Here are the cities: @Html.ListArrayItems((string[])ViewBag.Cities)
    </div>
    <div>
      Here is the message:
      <p>@Model</p>
    </div>
  </body>
</html>


辅助方法里字符串的编码问题(略)


使用內建的表单辅助方法

多数的内容都可以略去。只是有一点有必要强调下,就是表单控件的辅助方法有两种,一种就是简单的,如下:

@Html.TextBox("myTextbox", "val");

另外一种被称为强类型辅助方法:

@Html.TextBoxFor(x => x.FirstName);


后者只能用于强类型的view。这个地方值得进一步讨论,对于强类型的view,你依然可以选择使用简单的辅助方法,所以,究竟使用强类型辅助方法的优点在哪里?而这个问题的答案决定了在自定义辅助方法的时候应该采用那个。


参考资料:

Html.Textbox VS Html.TextboxFor

difference between Html.TextBox and Html.TextBoxFor


CHAPTER 22: 模板化的辅助方法


除了针对单独的属性生成HTML的辅助方法外,还有针对整个model类的辅助方法,如下:

  • DisplayForModel()
  • EditorForModel()
  • LabelForModel()

但是看起来用处不大。


使用模型元数据

这一节其实讲的是使用属性标签来影响辅助方法在生成属性的HTML时的行为,作者的示例代码里用到的有:

  • [HiddenInput(DisplayValue=false)]
  • [ScaffoldColumn(false)]
  • [DataType(DataType.Date)]
  • [UIHint("MultilineText")]


其中UIHint支持的参数除了Multiline Text以外还有:

  • Boolean
  • Collection
  • Decimal
  • DateTime
  • Date
  • EmailAddress
  • HiddenInput
  • Html
  • Number
  • Object
  • Password
  • String
  • Text
  • Tel
  • Time
  • Url


Buddy Class

如果你想用属性标签直接修饰用EF生成的模型类,就需要给它定义一个“好友类”,在好友类里给你想修饰的属性加上属性标签,比如:

namespace HelperMethods.Models {
	[DisplayName("New Person")]
	public partial class PersonMetaData {
		[HiddenInput(DisplayValue=false)]
		public int PersonId { get; set; }
		[Display(Name="First")]
		public string FirstName { get; set; }
		[Display(Name = "Last")]
		public string LastName { get; set; }
		[Display(Name = "Birth Date")]
		[DataType(DataType.Date)]
		public DateTime BirthDate { get; set; }
		[Display(Name="Approved")]
		public bool IsApproved { get; set; }
	}
}


EF生成的类是这样的:

namespace HelperMethods.Models {
	[MetadataType(typeof(PersonMetaData))]
	public partial class Person {
		public int PersonId { get; set; }
		public string FirstName { get; set; }
		public string LastName { get; set; }
		public DateTime BirthDate { get; set; }
		public Address HomeAddress { get; set; }
		public bool IsApproved { get; set; }
		public Role Role { get; set; }
	}
	// ...other types omitted from listing for brevity...
}


但是有一个问题,EF生成的类里还是需要一个标签,但是这个文件是自动生成的,如何保证这个标签不在再次生成时被重载。


定制模板



















评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值