关于工厂、单体、适配器、策略、观察者没啥好说的, 代码中有说明
//DesignPattern.cs
View Code
using System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
namespace
DesignPattern
{
//
################################单体模式########################################
//
单体模式思路: 禁止外接任意调用 --> 1. 构造函数做成私有的, 且本类禁止继承(密封类)
//
本类又需要创建实例, 且只能有一份 --> 2. 类的静态成员(静态变量), 因此需要静态构造函数并在其中创建实例
//
需要对外界提供调用方法 --> 3. 静态属性或者静态方法为外界提供调用
public
sealed
class
Singleton
//
用sealed封闭类, 防止用其子类创建实例
{
private
DateTime _createtime;
private
Singleton()
//
私有构造函数, 禁止外接调用
{
this
._createtime
=
DateTime.Now;
}
private
static
readonly
Singleton inner;
//
静态只读变量, 只能创建唯一的实例
static
Singleton()
//
通过静态构造函数, 返回本类的实例
{
inner =
new
Singleton();
}
public
static
Singleton GetSingleton
//
提供静态属性供外接调用
{
get
{
return
inner;
}
}
public
static
Singleton CreateSingleton()
//
也可以提供静态方法供外接调用
{
return
inner;
}
public
override
string
ToString()
//
重写ToString()方法, 返回
{
return
"
该自定义对象的HashCode为: <
"
+
inner.GetHashCode().ToString()
+
"
> , 创建时间为: <
"
+
this
._createtime.ToString()
+
"
> , 当前时间为: <
"
+
DateTime.Now.ToString()
+
"
> !
"
;
}
}
//
################################工厂模式########################################
//
工厂模式的核心思想: 运行时绑定, 在运行时才创建对象. 工厂模式3大组成: 工厂、产品、抽象产品.
//
工厂模式思路: 通过工厂类创建不同类的实例 --> 1. 嵌套类, 且不同类需要有"共有的基类"或"实现相同接口"
//
工厂类通常做成单独的程序集 --> 2. 这里做成嵌套类了, 被嵌套类为internal
//
需要对外界提供可返回实例的方法 --> 3. 根据静态方法的参数(switch), 返回不同的实例
public
class
Factory
{
internal
sealed
class
Laptop : Computer,IFunction
{
public
Laptop(
string
type,
string
manufacturer,
double
price)
: base
(
"
笔记本
"
, type,manufacturer,price)
{
}
public
override
string
ListFunction()
{
return
"
我是笔记本, 价格贵, 携带方便!
"
;
}
}
internal
class
Desktop : Computer,IFunction
{
public
Desktop(
string
type,
string
manufacturer,
double
price)
: base
(
"
台式机
"
, type, manufacturer, price)
{
}
public
override
string
ListFunction()
{
return
"
我是台式机, 性能强悍, 易升级!
"
;
}
}
internal
sealed
class
NetBook : Computer,IFunction
{
public
NetBook(
string
type,
string
manufacturer,
double
price)
: base
(
"
上网本
"
, type, manufacturer, price)
{
}
public
override
string
ListFunction()
{
return
"
我是上网本, 容易携带, 节能环保!
"
;
}
}
//
静态方法为外界提供实例(抽象类做容器)
public
static
Computer getComputer(
string
name)
{
Computer result =
null
;
switch
(name)
{
case
"
台式机
"
:
result =
new
Desktop(
"
随想T250
"
,
"
联想
"
,
5888.88
);
break
;
case
"
笔记本
"
:
result =
new
Laptop(
"
ThinkPad-T500
"
,
"
IBM
"
,
18888.0
);
break
;
case
"
上网本
"
:
result =
new
NetBook(
"
mini 9
"
,
"
Dell
"
,
3000.00
);
break
;
default
:
//
nothing to do here
break
;
}
return
result;
}
//
静态方法为外界提供实例(接口做容器)
public
static
IFunction getFunction(
string
name)
{
IFunction result =
null
;
switch
(name)
{
case
"
台式机
"
:
result =
(IFunction)
new
Desktop(
"
随想T250
"
,
"
联想
"
,
5888.88
);
break
;
case
"
笔记本
"
:
result =
(IFunction)
new
Laptop(
"
ThinkPad-T500
"
,
"
IBM
"
,
18888.0
);
break
;
case
"
上网本
"
:
result =
(IFunction)
new
NetBook(
"
mini 9
"
,
"
Dell
"
,
3000.00
);
break
;
default
:
//
nothing to do here!
break
;
}
return
result;
}
//
静态方法通过反射提供实例(需要配置文件), 由于是嵌套类, 反射有点问题, 如果是程序集肯定没问题
public
static
Computer getComputerByConfig()
{
string
typestr
=
System.Configuration.ConfigurationManager.AppSettings[
"
FactoryStrategy
"
];
if
(typestr
==
string
.Empty)
{
throw
new
TypeLoadException(
"
配置文件加载错误!
"
);
}
System.Type type =
System.Type.GetType(typestr);
if
(type
==
null
)
{
throw
new
TypeLoadException(
"
未知类型!
"
);
}
return
System.Activator.CreateInstance(type)
as
Computer;
}
}
public
abstract
class
Computer
//
抽象类做容器
{
//
字段
private
string
_name;
private
string
_type;
private
string
_manufacturer;
private
double
_price;
//
构造函数
public
Computer(
string
name,
string
type,
string
manufacturer,
double
price)
{
this
._name
=
name;
this
._type
=
type;
this
._manufacturer
=
manufacturer;
this
._price
=
price;
}
//
属性
public
string
Name
{
get
{
return
this
._name;
}
}
public
string
Type
{
get
{
return
this
._type;
}
}
public
string
Manufacturer
{
get
{
return
this
._manufacturer;
}
}
public
double
Price
{
get
{
return
this
._price;
}
}
public
override
string
ToString()
{
return
"
我是: <
"
+
this
.Name
+
"
> , 型号为: <
"
+
this
.Type
+
"
> , 制造商是: <
"
+
this
.Manufacturer
+
"
> , 价格是: <
"
+
this
.Price.ToString()
+
"
> !
"
;
}
public
abstract
string
ListFunction();
}
public
interface
IFunction
//
接口做容器
{
string
ListFunction();
}
//
################################适配器模式#######################################
//
适配器模式思路: 通过接口的不同实现影响程序的执行效果(程序代码基本不做变化) --> 1. 定义接口(适配器模式注重的是功能), 及若干实现类.
public
interface
ICallAdapter
{
string
MakeACall();
}
internal
class
Beeper : ICallAdapter
{
public
string
MakeACall()
{
return
"
通过传呼台将信息< 新婚快乐, 百年好合! > 送给了他
"
;
}
}
internal
class
TelPhone : ICallAdapter
{
public
string
MakeACall()
{
return
"
通过电话祝福他 < 新婚快乐, 百年好合! >
"
;
}
}
internal
class
CellPhone : ICallAdapter
{
public
string
MakeACall()
{
return
"
通过手机将亲手制作的视频-- < 新婚快乐, 百年好合! > 发送给了他
"
;
}
}
//
适配器模式的惯用法:
//
简单适配器(如上): 在业务逻辑比较简单且详细设计规范的情况下, 可以使用上边的方式, 在需要更换实现时直接修改源代码.
//
惯用适配器: 当我们在项目中需要更换某个功能模块的实现时, 新模块的方法名、参数名(方法签名)等均与旧模块不同, 此时可以通过引入专门的适配器来解决.
//
惯用适配器处理方式: 1. 新建类库项目并定义接口, 接口中规定需要实现的功能.
//
2. 创建新的适配器类, 该类继承自新模块中的实现类, 并实现定义的接口. 在新类的方法中, 通过base.方法名()调用新模块中的功能.
//
这样, 程序编码时使用IInterface ii = new NewClass();语句, 并调用接口ii上的方法即可. 当再发生改变时, 我们只需要在适配器中继承新模块的实现类, 并修改base后的方法即可. 之后把编译后的.dll文件拷贝到项目中去, 就可使用,源程序不做任何修改.
internal
class
MakeCall : Beeper, ICallAdapter
//
CellPhone
{
#region
ICallAdapter Members
string
ICallAdapter.MakeACall()
{
return
base
.MakeACall();
}
#endregion
}
//
################################策略模式#######################################
//
策略模式思路: 获得某个抽象类或接口的实现, 通过策略类(工具类)直接返回处理完成的结果.
//
与通过反射获得对象实例的工厂模式的区别: 工厂返回对象实例, 而策略强调完成任务、显示结果
//
1. 创建抽象基类或接口, 并创建若干实现类.
//
2. 创建策略类(工具类): 策略类利用反射从配置文件中获取对象实例后, 再调用对象上的方法, 返回结果
public
abstract
class
Vehicle
{
public
abstract
string
GetVehicleName();
}
internal
class
BoardingCar : Vehicle
{
public
override
string
GetVehicleName()
{
return
"
我是小轿车!
"
;
}
}
internal
class
MotorBicycle : Vehicle
{
public
override
string
GetVehicleName()
{
return
"
我是摩托车!
"
;
}
}
internal
class
Bike : Vehicle
{
public
override
string
GetVehicleName()
{
return
"
我是自行车!
"
;
}
}
//
策略类(工具类), 用于返回处理结果, 用户不会看到连接字符串、new等操作
public
class
VehicleProvider
{
public
static
string
OutputName()
{
string
typestr
=
System.Configuration.ConfigurationManager.AppSettings[
"
Strategy
"
];
if
(typestr
==
string
.Empty)
{
throw
new
TypeLoadException(
"
配置文件错误!
"
);
}
System.Type type =
System.Type.GetType(typestr);
if
(type
==
null
)
{
throw
new
TypeLoadException(
"
获取类型失败!
"
);
}
//
这里和通过反射获得对象的工厂的区别就是: 一个返回实例, 一个返回处理完成的结果
Vehicle v
=
System.Activator.CreateInstance(type)
as
Vehicle;
return
v.GetVehicleName();
}
}
//
策略类(工具类)的另一种写法(适合项目文件多、业务逻辑较复杂的情况)
public
class
VehicleStrategy
{
private
Vehicle _strategy;
public
void
SetStrategy(Vehicle strategy)
//
设置策略
{
this
._strategy
=
strategy;
}
public
string
ExecuteStrategy()
//
执行策略
{
return
this
._strategy.GetVehicleName();
}
}
//
################################观察者模式#######################################
//
观察者模式思路: 观察者(被动方)根据被观察着(主动方)的行为, 做出不同的响应, 已实现联动效果.
//
1. 抽象出观察者的共有行为, 即接收被观察者发送的消息; 抽象出被观察着的行为, 即提添加观察者和发送信息给观察者(对行为的抽象, 适合接口)
//
2. 定义若干观察者的类, 实现观察者接口, 定义被观察者类, 实现被观察接口
//
3. 通过被观察者行为的变化影响所有的观察者
public
interface
IObserver
//
观察者(被动方), 接收信息
{
void
ReceiveInfo(
object
obj);
}
public
interface
IActive
//
被观察着(主动方), 添加观察者和发送信息给观察者
{
void
SendInfo(
object
obj);
//
添加观察者
void
RegObserver(IObserver io);
//
发送信息
}
public
class
Car : IObserver
{
public
void
ReceiveInfo(
object
obj)
{
if
(obj.ToString()
==
"
红灯
"
)
{
Console.WriteLine( "
红灯停, 轿车踩刹车!
"
);
}
else
if
(obj.ToString()
==
"
绿灯
"
)
{
Console.WriteLine( "
绿灯行, 轿车踩油门!
"
);
}
else
{
Console.WriteLine( "
黄灯将变灯, 轿车减速!
"
);
}
}
}
public
class
Bicycle : IObserver
{
public
void
ReceiveInfo(
object
obj)
{
if
(obj.ToString()
==
"
红灯
"
)
{
Console.WriteLine( "
红灯停, 自行车下车!
"
);
}
else
if
(obj.ToString()
==
"
绿灯
"
)
{
Console.WriteLine( "
绿灯行, 自行车上车!
"
);
}
else
{
Console.WriteLine( "
黄灯将变灯, 自行车减速!
"
);
}
}
}
public
class
People : IObserver
{
public
void
ReceiveInfo(
object
obj)
{
if
(obj.ToString()
==
"
红灯
"
)
{
Console.WriteLine( "
红灯停, 人站住!
"
);
}
else
if
(obj.ToString()
==
"
绿灯
"
)
{
Console.WriteLine( "
绿灯行, 人行走!
"
);
}
else
{
Console.WriteLine( "
黄灯将变灯, 人观察!
"
);
}
}
}
public
class
TrafficLight : IActive
{
//
内部需要有个集合记录所有观察者
List
<
IObserver
>
list
=
new
List
<
IObserver
>
();
public
void
SendInfo(
object
obj)
{
foreach
(IObserver io
in
list)
{
io.ReceiveInfo(obj);
}
}
public
void
RegObserver(IObserver io)
{
list.Add(io);
}
}
//
观察者模式2(抽象类实现):猫大叫, 主人醒, 老鼠跑
public
abstract
class
Passive
//
观察者
{
public
abstract
void
Act();
}
public
abstract
class
Active
//
被观察者
{
public
abstract
void
AddList(Passive pa);
public
abstract
void
Shout();
}
public
class
Cat : Active
{
//
通知列表
List
<
Passive
>
list
=
new
List
<
Passive
>
();
public
override
void
AddList(Passive pa)
{
list.Add(pa);
}
public
override
void
Shout()
{
Console.WriteLine( "
猫大叫!
"
);
foreach
(Passive p
in
list)
{
p.Act();
}
}
}
public
class
Mouse : Passive
{
public
Mouse(
string
name)
{
this
._name
=
name;
}
private
string
_name;
public
string
Name
{
get
{
return
this
._name;
}
set
{
this
._name
=
value;
}
}
public
override
void
Act()
{
Console.WriteLine( string
.Format(
"
老鼠 < {0} > 四下逃窜!
"
,
this
.Name));
}
}
public
class
Man : Passive
{
public
override
void
Act()
{
Console.WriteLine( string
.Format(
"
主人惊醒!
"
));
}
}
}
//Progarm.cs
View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace DesignPattern
{
class Program
{
static System.Timers.Timer timer;
static
string
lightcolor
=
"
红灯
"
;
static TrafficLight tl;
static
void
Main(
string
[] args)
{
Console.WriteLine( " ------------单体模式(Singleton)-------------
"
);
// Singleton s1 = new Singleton();
//
无法直接创建Singleton的实例
Singleton s2 =
Singleton.GetSingleton;
Console.WriteLine(s2.ToString());
Thread.Sleep( 3000 );
Singleton s3 = Singleton.GetSingleton;
Console.WriteLine(s3.ToString());
Thread.Sleep( 3000 );
Singleton s4 = Singleton.CreateSingleton();
Console.WriteLine(s4.ToString());
Console.WriteLine( " \n------------工厂模式(Factory)-------------
"
);
// 基类容器
Computer c1 =
Factory.getComputer(
"
笔记本
"
);
Console.WriteLine(c1.ToString());
Computer c2 = Factory.getComputer(
"
上网本
"
);
Console.WriteLine(c2.ToString());
// 配置文件获取对象实例
// Computer c3 = Factory.getComputerByConfig();
// Console.WriteLine(c3.ToString());
// 使用接口容器
IFunction i1 =
Factory.getFunction(
"
台式机
"
);
Console.WriteLine(i1.ListFunction());
IFunction i2 = Factory.getFunction(
"
上网本
"
);
Console.WriteLine(i2.ListFunction());
Console.WriteLine( " \n------------适配器模式(Adapter)-------------
"
);
ICallAdapter ica =
null
;
//
使用接口盛放不同实现
ica =
new
TelPhone();
Console.WriteLine(NoticeInfo( " 同事结婚
"
,
"
家里
"
, ica));
ica =
new
CellPhone();
Console.WriteLine(NoticeInfo( " 好朋友结婚
"
,
"
厕所
"
, ica));
ica =
new
Beeper();
Console.WriteLine(NoticeInfo( " 爷爷再婚
"
,
"
办公室
"
, ica));
Console.WriteLine( " \n------------惯用的适配器模式-------------
"
);
ICallAdapter ica2 =
new
MakeCall();
Console.WriteLine(NoticeInfo( " 同事结婚
"
,
"
家里
"
, ica2));
Console.WriteLine( " \n----------抽象类实现观察者模式1(Observer)-----------
"
);
Cat cat =
new
Cat();
Mouse m1 =
new
Mouse(
"
Jerry
"
);
Mouse m2 =
new
Mouse(
"
MickeyMouse
"
);
Man man =
new
Man();
cat.AddList(m1);
cat.AddList(m2);
cat.AddList(man);
cat.Shout();
Console.WriteLine( " \n------------接口观察者模式2(Observer)-------------
"
);
tl =
new
TrafficLight();
Car car1 =
new
Car();
Bicycle bike1 =
new
Bicycle();
People people1 =
new
People();
tl.RegObserver(car1);
tl.RegObserver(bike1);
tl.RegObserver(people1);
// tl.SendInfo("红灯");
//
测试
// tl.SendInfo("绿灯");
//
测试
timer =
new
System.Timers.Timer();
timer.Interval =
1000
*
10
;
//
推荐写法
timer.Elapsed +=
new
System.Timers.ElapsedEventHandler(timer_Elapsed);
timer.Start();
Console.WriteLine( " \n------------策略模式(Strategy)-------------
"
);
Console.WriteLine(DesignPattern.VehicleProvider.OutputName()); // 通过反射从配置文件获得对象信息
Console.WriteLine( "
\n------------策略模式另一种写法-------------
"
);
//
添加新策略时, 可以不修改源代码
System.Reflection.Assembly asm =
System.Reflection.Assembly.LoadFrom(System.Configuration.ConfigurationManager.AppSettings[
"
AssemblyPath
"
]);
Vehicle vehicle = asm.CreateInstance(System.Configuration.ConfigurationManager.AppSettings[
"
ClassName
"
])
as
Vehicle;
//
Vehicle为抽象类
VehicleStrategy vs =
new
VehicleStrategy();
//
策略管类类
vs.SetStrategy(vehicle); //
设置策略
Console.WriteLine(vs.ExecuteStrategy()); //
执行策略, 添加新策略时只要配置好app文件中程序集位置和类名即可
Console.ReadLine(); // 挂起程序
}
static
void
timer_Elapsed(
object
sender, System.Timers.ElapsedEventArgs e)
{
timer.Stop();
Console.WriteLine( " \n-----------观察者模式2的回调结果--------------\n
"
);
if (lightcolor
==
"
红灯
"
)
{
lightcolor =
"
绿灯
"
;
}
else
if
(lightcolor
==
"
绿灯
"
)
{
lightcolor =
"
红灯
"
;
}
tl.SendInfo(lightcolor);
Console.Write(Environment.NewLine);
timer.Start();
}
static
string
NoticeInfo(
string
content,
string
place, ICallAdapter mode)
//
适配器模式中的主要代码部分
{
return
"
<
"
+
content
+
"
> , 小明正在 <
"
+
place
+
"
> , 于是用 <
"
+
mode.MakeACall()
+
"
> !
"
;
}
}
}
//App.config
<? xml version="1.0" encoding="utf-8" ?>
< configuration
>
< appSettings
>
<!-- <add key="FactoryStrategy" value="DesignPattern.Factory.Desktop,DesignPattern"/>
-->
< add
key
="Strategy"
value
="DesignPattern.Bike,DesignPattern"
/>
<!-- 可选MoterBicycle,car
-->
<!-- 策略模式配置文件
-->
< add
key
="ClassName"
value
="DesignPattern.MotorBicycle"
/>
< add
key
="AssemblyPath"
value
="D:\重要未完成\DesignPattern\DesignPattern\bin\Debug\DesignPattern.exe"
/>
</ appSettings
>
</ configuration
>
关于MVC设计模式的控制台Demo
//Model/Model.cs
View Code
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
namespace MVCModel
{
// MVC模式的思想: 将界面设计和功能设计分开, 且同时进行设计, 最后通过Controller综合工作成果. 程序运行时, 按View-Controller-Model的流程执行
// 功能开发人员可以向Controller提交dll文件, 也可以将dll注册到本机的全局程序集缓存(GAC)中(c:\windows\assembly).
// 添加到GAC中的方法:
// 1. 添加完整的文档注释, 类型及成员均需添加且不可遗漏(类: 描述... ; 方法: 根据...; 属性: 获取或设置... ; 参数: System.xx类型, 表示...)
//
// 2. 添加完整程序集信息(通过创建空类库项目, 获得AssemblyInfo文件并修改)
// 主版本号: 软件版本重大变化, 如: 单机版到网络版
// 次要版本号: 软件功能变化, 如: 添加辅助挂机功能
// 内部版本号: 如: beta,final, 或同时做出几个不同方案, 最终选一个
// 修订号: 修改bug的次数
//
// 3. 通过类库中的强名称工具获得签名密钥(需在环境变量的Path中, 添加VS2008的SDK目录c:\program files\Microsoft SDKs\Windows\v6.0A\bin)
// cmd中生成强名称(注意大小写): sn -k strongname.snk 查看强名称: sn -T xxx.dll
// 备注: VS2005的SDK目录为c:\program files\Microsoft Visual Studio 8\SDK\v2.0\Bin
//
// 4. 将有完整文档注释的cs文件、AssemblyInfo文件及强名称文件编译成一个dll文件和XML文档
// cmd中键入命令: csc /target:library /doc:xxx.xml /keyfile:strongname.snk /out:xxx.dll AssemblyInfo.cs aaa.cs bbb.cs
//
// 5. 将xxx.dll和xxx.xml拷贝到稳定的目录(如框架类库目录: c:\windows\Microsoft.Net\Framework\v3.5\)下
// cmd中使用命令gacutil /i xxx.dll注册到GAC中 使用gacutil /u xxx.dll可以反注册; 若不需要xxx.xml, 可以简单的讲xxx.dll拖到c:\windows\Assemly文件夹中
/// <summary>
/// 描述定时关机操作及其相关信息
/// </summary>
public
class
Model
{
/// <summary>
/// 根据参数选择执行的操作及延时
/// </summary>
/// <param name="action">
System.String类型, 表示操作的类型, "r"代表重启, "s"代表关机
</param>
/// <param name="seconds">
System.Int32类型, 以整数表示的操作延时, 单位为秒
</param>
public
void
RunCommand(
string
action,
int
seconds)
{
string param =
"
-
"
+
action
+
"
-t
"
+
seconds;
Process.Start( " shutdown "
, param);
}
/// <summary>
/// 根据参数返回执行命令的字符串表示
/// </summary>
/// <param name="action">
System.String类型, 表示操作额类型, "r"代表重启, "s"代表关机
</param>
/// <param name="seconds">
System.Int32类型, 以整数表示的操作延迟, 单位为秒
</param>
/// <returns>
System.String类型, 执行命令的字符串表示, 默认返回空字符串""
</returns>
public
string
GetCommand(
string
action,
int
seconds)
{
string result =
""
;
result = "
shutdown -
"
+
action
+
"
-t
"
+
seconds;
return result;
}
}
}
//Model/AssemblyInfo.cs
View Code
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle( " PowerOffComponent "
)]
[assembly: AssemblyDescription( " 全局程序集, 完成计算机定时关机操作 " )]
[assembly: AssemblyConfiguration( "" )]
[assembly: AssemblyCompany( " China America IT Technology Inc. " )]
[assembly: AssemblyProduct( " CaitProduct-PowerOff " )]
[assembly: AssemblyCopyright( " Copyright © China America IT Technology Inc. 2010 " )]
[assembly: AssemblyTrademark( " CAIT " )]
[assembly: AssemblyCulture( "" )]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible( false )]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid( " 43c452bd-72d8-421c-b2ec-4e8a9b749418 "
)]
// Version information for an assembly consists of the following four values:
//
// Major Version: 主版本号, 软件版本重大变化, 如: 单机版到网络版
// Minor Version: 次要版本号, 软件功能变化, 如: 添加辅助挂机功能
// Build Number: 内部版本号, 如: beta,final, 或同时做出几个不同方案, 最终选一个
// Revision: 修订号: 修改bug的次数
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion( " 1.0.1.5 "
)]
[assembly: AssemblyFileVersion( " 1.0.1.5 " )]
//Controller/Controller.cs
View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MVCController
{
public class Controller
{
public static string
KillPower(
string
choise,
string
time)
{
string result = null
;
string param = (choise ==
"
1
"
)
?
"
s
"
:
"
r
"
;
int inttime = Convert.ToInt32(time);
MVCModel.Model m = new MVCModel.Model();
result = m.GetCommand(param, inttime);
// 这里可以采用异步通信, 开辟子线程执行RunCommand命令
m.RunCommand(param, inttime); // 两种异步通信: 1. Async方法+事件 2.委托实例+回调函数(callback)
return result;
}
}
}
//View/View.cs
View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MVCView
{
class View
{
static void Main( string [] args)
{
Console.WriteLine( " ************************************** " );
Console.WriteLine( " * * " );
Console.WriteLine( " * MVC模式练习---关机重启小程序 * " );
Console.WriteLine( " * * " );
Console.WriteLine( " ************************************** " );
string input = "" ;
string time = " 5
"
;
string result = null ;
while ( true )
{
Console.WriteLine( " 请选择操作: \t1.关机 \t2.重启 " );
Console.WriteLine( " \t\t0.退出 " );
input = Console.ReadLine();
if (input != " 0
"
)
{
if ((input == " 1
"
)
!=
(input
==
"
2
"
))
{
Console.Write( " 请输入延迟时间(含0): " );
time = Console.ReadLine();
// 执行方法
result = MVCController.Controller.KillPower(input,time);
if (result != null )
{
Console.WriteLine( " \n操作已执行, 执行的完整命令为: " + result
+
"
\n
"
);
}
else
{
Console.WriteLine( " \n程序执行异常, 请通知管理员! \n " );
}
}
else
{
Console.WriteLine( " 输入了不合适的选项! " );
}
}
else
{
Console.WriteLine( " 感谢使用, 再见! " );
break ;
}
}
}
}
}
ASP.NET-MVC
最早是在王老师的课上听到MVC这个东西, 当时是讲设计模式. MVC设计模式从本质上讲就是种分工的方式, 人为的把一个项目分成Model(模型)、View(试图)、Controller(控制器). 这样呢, 首先由Controller来协调View和Model之间的衔接, 按王老师的话讲就是”和稀泥的家伙”, 在Controller中预先规定好需要提供给View开发人员的方法及方法名, 这样, View开发人员在开发时, 便可以忽略具体的实现, 只要根据需要调用Controller中的方法并显示结果即可; 那么Model开发人员关注的则是具体的业务对象, 针对每个业务对象制作不同的类以及与该业务对象相关的各种方法; 最后Controller通常有较有经验的工程师担当, 他负责调用Model中业务对象的各种方法来完成相关的业务逻辑. 如此, 一个项目就被分成了3个阶段, View和Controller、Controller和Model之间可以通过接口来现隔离(术语叫解耦合), 最终3个部分可以并行开发, 大大提高了开发效率.
之后在郝老师的课上, 又一次听到MVC, 这里的MVC是指ASP.NET的MVC开发方式(说开发模式容易混淆). 反正当时我是弄混了.
MVC设计模式: 何谓设计模式? 设计模式是一种设计思想, 是高于开发的一种抽象层面的想法. 而MVC开发模式或者说开发方式, 就是在你实际开发过程中, 采取的一种手段或某种流程. 前面也提过, MVC设计模式的思想就是分工, 各层用接口隔离; MVC开发模式是微软在ASP.NET技术中提出的一种开发手段, 就如同我们熟悉的WebForm开发, ASP.NET MVC也是一种开发手段与WebForm是平行的, 它代表.NET Web开发领域中, 除WebForm外的另一种开发方向. 你可以理解为ASP.NET MVC就是将MVC设计模式的思想用到了Web网站开发中的UI层, 所有ASP.NET MVC的工作都是针对UI层的, 底下的业务逻辑、数据库访问、实体等层依然和WebForm开发是一样的.
那么微软大费周章的搞出个ASP.NET MVC有什么好处呢? ----最大的好处就是可测试.
在传统的Web开发中, 如果想测试开发的网站, 你需要的启动网站, 用非正常用户的角度去尝试各种边界值和以外情况, 而在ASP.NET MVC中, 页面View中显示的内容都是从Model中来的, 而Model又是在Controller中由Action返回的, 这里先不用管Action是什么, 你可以把它当作是个Controller中的处理请求的方法. 此时, 整个Controller看起来就是类而已, 而实际上它就是个类, 这时候关于网站的测试工作的关键就看这个类了, 这时候你想到了什么? NUnitTest, 对啊, 我们只要写测试用例, 用事先写好的测试用例来测试不就好了, 开发过程中, 我们可以随时跑下测试用例, 就知道当前有没有错误. 因此, 可测试是ASP.NET MVC的最大优点.
ASP.NET MVC 请求过程:
说了一大堆, 其实就是两点: 1. ASP.NET MVC开发模式(方式)是MVC设计模式(思想)在UI层的体现. 2. ASP.NET MVC最大的优点是便于测试. Okey, 接下来开始ASP.NET MVC, 以下无特殊说明, MVC均指ASP.NET MVC. 看下图, ASP.NET MVC的请求回应过程.
客户端浏览器首先发送GET或POST请求, 当请求到达IIS后, 由aspnet_iisapi.dll转交asp.net组件, 然后由w3wp创建应用程序域, 再应用程序域中创建HttpRuntime执行环境, 并在环境中创建HttpContext对象(该对象包含HttpRequest、HttpResponse、Cache、Server等对象)和HttpApplication应用程序管道, 在HttpApplication应用程序管道中会根据请求的URL形式将会进行一个称为Routing的过程(可以参见Global.asax.cs中的代码). 什么是Routing(路由)呢? 在计算机网络中, 路由定义为: 在不同的网段间转发数据的过程. 而在此处的Routing可以理解为一个转发数据的过程, 它把GET请求头或POST请求体中的数据转发给了Controller. 上图中有个请求地址的示例, Routing的工作实际上就是通过正则表达式把Controller、Action和Parameter分别取出来. 这样, 便得到了Controller的名称、Action的名称、以及参数, 这时asp.net mvc将会到网站根目录下的Controllers文件夹中找到相应名称的Controller类, 并在Controller类中找到Action. 在Controller类中可以看到, 一个Action其实就是返回值为ActionResult的方法. 之后, 在Action方法中完成调用业务逻辑层、数据库访问层等完成工作之后, 将取到的结果封装到一个Model类中, 在返回给前台的View. 在View中通过该Model类的对象获得值并显示在View中, 最后在把View发送给客户端浏览器.
以上就是ASP.NET MVC的整个请求相应过程, 值得注意的, Model是用来封装返回结果的, 也可以在Model中添加用于验证(配合jQuery)的标注属性. 当然我们也可以不用Model, 而直接使用ViewData字典或者自定义实体类都可以返回结果. 不论是Model、ViewData还是实体类都需要在View的页面指令的Inherits属性中声明一下, 声明格式如下: Inherits =” System.Web.Mvc.ViewPage<mvc_1.Models.VenderModel>”, 其中mvc_1.Models.VenderModel就是用来封装结果的Model类.
如此说来, 我们有三种方式从Controller中传递数据岛View中: ViewData、自定义实体类、Model(常用).
开发ASP.NET MVC网站的开发工具需要是VS2008 + SP1以上, 并且需要安装ASP.NET MVC2_VS2008. 在写View的时候, 会用到Lambda表达式(Parameter => Method)和嵌入程序块(<%...%>)及嵌入表达式(<%= %>). 详见示例:
1. 为简便, 这里不再分BLL、DAL及实体层, 我们通过一个接口和一个实现类来完成对xml中数据的操作、通过Manufacturer实体类表示制造商信息.
注意: 在返回集合数据时, 可以用IEnumerable<T>泛型接口作返回类型.
Model类似于实体类, 但Model真的不是实体类:
实体类是与数据库中某张或某几张表相关的类型, 该类型可以使程序员在程序中方便的表示和使用表中的数据, 是O/R Mapping(Object-Relation Mapping, 对象关系映射)思想的体现. 实体类中几乎涉及数据表中的每个字段, 是用来在整个项目中表示数据对象的. 而Model中虽然也是一大堆封装字段的属性, 而且可以添加用于验证(配合jQuery)的标签属性, 但是Model的重点在于Controller和View之间. Model提供了一种介于Controller和View之间传递的数据的强类型表示, Model中的数据可能只是与View中需要显示的那部分数据相关. 一句话说, 实体类是数据库中的表 和程序中的数据表示 之间的一层映射, 而Model是UI层的Controller和View之间传递的数据或参数的映射. 例如: 你可能在数据中有表(包含: 序号、姓名、密码、生日、家庭住址), 那么你的实体类中往往是对表中所有字段的封装. 但是在UI中, 你的更改密码的页面(View)传递给Controller的参数往往是个Model类(包含: 旧密码、新密码)的对象, 这时区别很容易看出来. Model就是一种对传递的数据的强类型的封装, 而实体类是对数据库中表中字段进行的封装, 是用来在程序中表示表中的数据的. 根据具体的情况, Model类中字段的内容可能和实体类字段的内容相差很大, 更多的时候Model类中的字段就是View中用来接收用户输入的字段.
2. 由上图可知, 客户端请求的第一站是Controller中. 为实现低耦合, 我们在Controller中调用接口上的方法, 因为我们可以先定义接口类型的属性, 然后重写Controller的Initialize()方法, 在Initialize()方法中进行接口的赋值工作.
注意: 我们通常将业务逻辑处理完的结果用Model封装后返回给View, 但是当返回的是集合类型的元素时, 我们必须通过ViewData字典返回.
3. 接下来, 我们继续看Controller中的每个方法即Action, 每个Action应该对应一个View, 而Controller中往往有多个Action, 所以我们在View文件夹中创建Manufacturer文件夹, 并且针对每个Action都创建一个View页面, 如: Index、Detail、Delete等.
注意: 我们也可以自定义Action, 其实就是写个方法. 例如: public JsonResult CheckName(){…}, 其中JsonResult用来返回Json对象, 通过JsonResult对象的JsonRequestBehavior属性设置允许的请求类型, 通过JsonResult对象的Data属性返回结果.
在MVC中, 针对同一个View页面的两次请求会由于缓存看不到结果, 这是需要用页面指令关闭缓存. 如:<@OutputCache Duration=”1” VaryByParam=”*”%>
4. 最后, 在View中呈现我们的结果, 如果是集合数据, 我们可以采用嵌入代码块的方式(<%......%>)拼程序块, 而用<%=……%>来绑定结果中的字段; 如果返回的只是单个Model, 可以通过lambda表达式绑定结果数据, 只是不要忘了需要在页面指令的Inherits属性中, 申明Model.
以上便是Asp.Net MVC的一次请求过程, 开发网站的UI时, 只要按照Controller ---> Action ---> BLL(业务处理逻辑) ---> View的次序迭代即可.
关于MVC中的验证:
Model类中的标注属性实际上就是用来完成验证工作的, 因为Model类中的字段均是View页面中需要用户输入的字段, 凡是涉及到用户输入的地方, 肯定补课缺少的就是验证.
在MVC有两种验证方式: 服务器端的验证方式 和 客户端的验证方式.
1. 服务器端验证: 包含Model中的标注属性、View中的Html.ValidationMessageFor()、Controller中的Action方法中的ModelState.IsValid属性. MVC中的服务器端验证和jQuery的Validate配合工作的. 使用时, 只要在Model中添加验证标签(引用System.ComponentModel和System.ComponentModel.DataAnnotations命名空间), 在Controller的Action方法中用ModelState.IsValid判断下, 最后再View中添加验证信息的显示位置即可. 具体事例, 参见View文件夹中的Create.aspx.
2. 客户端验证: 客户端验证才是我们开发中常用的验证手段, 同样MVC的客户端的验证手段仍然是通过jQuery的Validate实现的. 客户端的验证, 我们不需要该Model、也不需要改Controller, 所有的验证工作都是在View中的Javascript脚本中完成的. 我们把jQuery和jQuery.Validate引用到View页面中, 并且我们可以通过Html.TextBoxFor()的重载方法, 为TextBox元素添加ID等属性(通过匿名对象new {}进行). 具体事例见Edit.aspx
注意: 我们可以通过<%= Url.Action(“ActionName”) %>计算出这个Action的全路径. 并且因为IE浏览器会对同一个请求做缓存处理, 所以这里应该用<%= Url.Action(“ActionName”) + “?” + DateTime.ToLongTimeString() %>做地址.
关于input中的name属性, 例如: <input type=”hidden” name=”abc” value=”123”>的标签, 只有添加了name属性, 在表达提交时才会将input的值发送到服务器. 发送时, 会在get请求后变成?abc=123,在post请求体中变成是…&abc=123, …表示装他的内容.
关于缓存, 我们有5中关闭缓存的方式:
1. 更改Url: 在Url后边人为添加不会重复的内容.
2. 在*.ashx, *.cs文件中用context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
3. 在*.aspx或*.ascx文件中, 用页面指令<%@Outputcache Duration=”1” VaryByParam=”*”%>
4. jQuery的Ajax中, 使用$.ajax({cache: false}); 关闭ajax时的缓存
5. 在*.html中的head标签中, 添加如下内容:
<META HTTP-EQUIV="pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache, must-revalidate">
<META HTTP-EQUIV="expires" CONTENT="Wed, 26 Feb 1997 08:21:57 GMT">
//实例代码如下:
//数据文件, App_Data/ManufacturerData.xml
View Code
<? xml versinotallow="1.0" encoding="utf-8" ?>
< Data >
< Manufacturer >
< ManufacturerID > fa33da90-d145-4122-85a9-b3f99f99ebfd </ ManufacturerID >
< ManufacturerName > Mercedes.Benz </ ManufacturerName >
< MandarinName > 梅赛德斯.奔驰 </ MandarinName >
< CreateTime > 2011-01-12 18:53:20 </ CreateTime >
</ Manufacturer >
< Manufacturer >
< ManufacturerID > 8f7f6a78-b991-493e-bbe7-4ba5af00fa63 </ ManufacturerID >
< ManufacturerName > Bayerische Motoren-Werke AG </ ManufacturerName >
< MandarinName > 宝马 </ MandarinName >
< CreateTime > 2011-03-02 08:33:00 </ CreateTime >
</ Manufacturer >
< Manufacturer >
< ManufacturerID > c3aa600a-26df-4a27-be06-4b4329f2998a </ ManufacturerID >
< ManufacturerName > Ferrari </ ManufacturerName >
< MandarinName > 法拉利 </ MandarinName >
< CreateTime > 2010-06-07 23:13:15 </ CreateTime >
</ Manufacturer >
< Manufacturer >
< ManufacturerID > 45d73ca9-96ad-4884-b56b-2b6b673d9843 </ ManufacturerID >
< ManufacturerName > cbg </ ManufacturerName >
< MandarinName > Test1 </ MandarinName >
< CreateTime > 2011-2-18 0:40:30 </ CreateTime >
</ Manufacturer >
< Manufacturer >
< ManufacturerID > 4c35a974-ecb4-489d-878b-0008f1735ba3 </ ManufacturerID >
< ManufacturerName > abc </ ManufacturerName >
< MandarinName > vvvb </ MandarinName >
< CreateTime > 2011-2-18 1:45:06 </ CreateTime >
</ Manufacturer >
</ Data >
//IManufacturerManager.cs
View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MvcApplicationDemo
{
public interface IManufacturerManager
{
// 当返回集合数据时, 可以用IEnumerable<T>泛型接口作返回类型
IEnumerable < Manufacturer > GetAllManufacturers();
Manufacturer GetManufacturerByID(Guid id);
void CreateManufacturer(Manufacturer manufacturer);
void DeleteManufacturer(Guid id);
bool CheckManufacturerName( string manufacturername);
void UpdateManufacturer(Manufacturer manufacturer);
}
}
//ManufacturerManager.cs
View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplicationDemo
{
public class ManufacturerManager : IManufacturerManager
{
string DataPath = AppDomain.CurrentDomain.BaseDirectory + " App_Data/ManufacturerData.xml "
;
#region IManufacturerManager Members
public IEnumerable < Manufacturer > GetAllManufacturers()
{
// 一次性全部读取, 适合采用XML流, 但XML流不支持结构化查询
List < Manufacturer > manufacturers = new List
<
Manufacturer
>
();
//
用于返回数据
System.IO.StreamReader sw = new System.IO.StreamReader(DataPath, System.Text.Encoding.UTF8);
using (System.Xml.XmlReader xmlrd = System.Xml.XmlReader.Create(sw))
{
Manufacturer manufacturer;
while (xmlrd.Read())
{
if (xmlrd.NodeType == System.Xml.XmlNodeType.Element)
{
if (xmlrd.Name == " Manufacturer " )
{
manufacturer = new Manufacturer();
if (xmlrd.ReadToFollowing( " ManufacturerID " ))
{
manufacturer.Uid = new Guid(xmlrd.ReadElementString( " ManufacturerID " ));
}
if (xmlrd.ReadToFollowing( " ManufacturerName " ))
{
manufacturer.ManufacturerName = xmlrd.ReadElementString( " ManufacturerName " );
}
if (xmlrd.ReadToFollowing( " MandarinName " ))
{
manufacturer.MandarinName = xmlrd.ReadElementString( " MandarinName " );
}
if (xmlrd.ReadToFollowing( " CreateTime " ))
{
manufacturer.CreateTime = DateTime.Parse(xmlrd.ReadElementString( " CreateTime " ));
}
manufacturers.Add(manufacturer);
}
}
}
}
sw.Close();
return manufacturers;
}
public Manufacturer GetManufacturerByID(Guid id)
{
Manufacturer manufacturer = null ;
// 只是查询, 适合XPathDocument, 优化过的XPath, 优点: 结构化查询、速度快; 缺点: 只能读不能写
System.Xml.XPath.XPathDocument xpdoc = new System.Xml.XPath.XPathDocument(DataPath); // 创建XPathDocument
System.Xml.XPath.XPathNavigator xpnav = xpdoc.CreateNavigator(); // 创建查找用的导航器
// 定制XPathExpression表达式
string xpathstr = " Data/Manufacturer " ;
System.Xml.XPath.XPathExpression xpath = System.Xml.XPath.XPathExpression.Compile(xpathstr);
// 使用导航器获得结果, 单个结果用XPathNavigator导航器, 多个结果用XPathNodeIterator迭代器
System.Xml.XPath.XPathNavigator resultnav = xpnav.SelectSingleNode(xpathstr);
while (resultnav.HasChildren)
{
resultnav.MoveToFirstChild();
if (resultnav.Value == id.ToString())
{
manufacturer = new Manufacturer();
manufacturer.Uid = id;
if (resultnav.MoveToNext() && resultnav.Name == " ManufacturerName "
)
{
manufacturer.ManufacturerName = resultnav.Value;
}
if (resultnav.MoveToNext() && resultnav.Name == " MandarinName "
)
{
manufacturer.MandarinName = resultnav.Value;
}
if (resultnav.MoveToNext() && resultnav.Name == " CreateTime "
&&
!
string
.IsNullOrEmpty(resultnav.Value))
{
manufacturer.CreateTime = DateTime.Parse(resultnav.Value);
}
break ;
}
else
{
resultnav.MoveToParent(); ; // 移动父节点
resultnav.MoveToNext(); // 父节点的兄弟
}
}
return manufacturer;
}
public void CreateManufacturer(Manufacturer manufacturer)
{
// 修改操作, 适合采用XPath进行操作
System.Xml.XmlDocument xdoc = new System.Xml.XmlDocument();
xdoc.Load(DataPath);
string xpath = " /Data " ;
System.Xml.XmlNode nodes = xdoc.SelectSingleNode(xpath);
System.Xml.XmlNode newnode = xdoc.CreateNode(System.Xml.XmlNodeType.Element, " Manufacturer " , string .Empty);
System.Xml.XmlElement elemid = xdoc.CreateElement( " ManufacturerID " );
System.Xml.XmlText textid = xdoc.CreateTextNode(manufacturer.Uid.ToString());
elemid.AppendChild(textid);
newnode.AppendChild(elemid);
System.Xml.XmlElement elemname = xdoc.CreateElement( " ManufacturerName " );
System.Xml.XmlText textname = xdoc.CreateTextNode(manufacturer.ManufacturerName);
elemname.AppendChild(textname);
newnode.AppendChild(elemname);
System.Xml.XmlElement elemcnname = xdoc.CreateElement( " MandarinName " );
System.Xml.XmlText textcnname = xdoc.CreateTextNode(manufacturer.MandarinName);
elemcnname.AppendChild(textcnname);
newnode.AppendChild(elemcnname);
System.Xml.XmlElement elemtime = xdoc.CreateElement( " CreateTime " );
System.Xml.XmlText texttime = xdoc.CreateTextNode(manufacturer.CreateTime.ToString());
elemtime.AppendChild(texttime);
newnode.AppendChild(elemtime);
nodes.AppendChild(newnode);
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(DataPath, false , System.Text.Encoding.UTF8))
{
xdoc.Save(sw);
}
}
public void DeleteManufacturer(Guid id)
{
// 修改操作, 适合采用XPath进行操作
System.Xml.XmlDocument xdoc = new System.Xml.XmlDocument();
xdoc.Load(DataPath);
string xpath = " /Data/Manufacturer/ManufacturerID [text()=\" " + id.ToString()
+
"
\"]
"
;
System.Xml.XmlNode node = xdoc.SelectSingleNode(xpath);
if (node != null )
{
node.ParentNode.ParentNode.RemoveChild(node.ParentNode);
}
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(DataPath, false , System.Text.Encoding.UTF8))
{
xdoc.Save(sw);
}
}
public void UpdateManufacturer(Manufacturer manufacturer)
{
// 修改操作, 适合采用XPath进行操作
System.Xml.XmlDocument xdoc = new System.Xml.XmlDocument();
xdoc.Load(DataPath);
string xpath = " /Data/Manufacturer/ManufacturerID [text()=\" " +
manufacturer.Uid.ToString()
+
"
\"]
"
;
System.Xml.XmlNode node = xdoc.SelectSingleNode(xpath);
if (node != null )
{
node.NextSibling.FirstChild.Value = manufacturer.ManufacturerName;
node.NextSibling.NextSibling.FirstChild.Value = manufacturer.MandarinName;
}
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(DataPath, false , System.Text.Encoding.UTF8))
{
xdoc.Save(sw);
}
}
public bool CheckManufacturerName( string manufacturername)
{
// 仅查找, 适合XPathDocument
System.Xml.XPath.XPathDocument xpd = new System.Xml.XPath.XPathDocument(DataPath);
System.Xml.XPath.XPathNavigator xnav = xpd.CreateNavigator();
// 定义XPath
string xpathstr = " /Data/Manufacturer/ManufacturerName [text()=\" "
+
manufacturername
+
"
\"]
"
;
System.Xml.XPath.XPathExpression xpath = System.Xml.XPath.XPathExpression.Compile(xpathstr);
System.Xml.XPath.XPathNavigator result = xnav.SelectSingleNode(xpath);
if (result == null )
{
return true ;
}
else
{
return false ;
}
}
#endregion
}
}
//实体类, Manufacturer.cs
View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcApplicationDemo
{
public class Manufacturer
{
public Guid Uid { get ; set ; }
public string ManufacturerName { get ; set ; }
public string MandarinName { get ; set ; }
public DateTime CreateTime { get ; set ; }
public Manufacturer()
{ }
public Manufacturer(Guid id, string manufacturername, string mandarinname, DateTime createtime)
{
this .Uid = id;
this .ManufacturerName = manufacturername;
this .MandarinName = mandarinname;
this .CreateTime = createtime;
}
public Manufacturer(Guid id, string manufacturername, DateTime createtime)
{
this .Uid = id;
this .ManufacturerName = manufacturername;
this .MandarinName = string .Empty;
this .CreateTime = createtime;
}
}
}
//Controllers/ManufacturerController.cs
View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplicationDemo.Controllers
{
public class ManufacturerController : Controller
{
// 通过接口来调用方法, 在初始化方法中用接口承载实现类
public IManufacturerManager ManufacturerService { get ; set ; }
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
if ( this .ManufacturerService == null )
{
this .ManufacturerService = new ManufacturerManager();
}
base .Initialize(requestContext);
}
//
// GET: /Manufacturer/
public ActionResult Index()
{
IEnumerable < Manufacturer > manufacturers = this .ManufacturerService.GetAllManufacturers();
// 由于ManufacturerModel无法传递集合, 这里用ViewData传递集合数据
ViewData[ " manufacturers " ] = manufacturers;
return View();
}
//
// GET: /Manufacturer/Details/5
public ActionResult Details(Guid id) // 修改int类型为GUID
{
Manufacturer manufacturer = this .ManufacturerService.GetManufacturerByID(id);
return View(manufacturer); // 显示全部信息, 这里用实体类返回数据给View, 注意在View中注册Manufacturer类型
}
//
// GET: /Manufacturer/Create
public ActionResult Create() // Get方式
{
return View();
}
//
// POST: /Manufacturer/Create
[HttpPost]
public ActionResult Create(MvcApplicationDemo.Models.ManufacturerModel model) // 使用Model传递数据
{
if (ModelState.IsValid) // Model是否通过验证, 验证工作通过Model类的标注属性完成(服务器端验证)
{
try
{
// TODO: Add insert logic here
Manufacturer manufacturer = new Manufacturer(Guid.NewGuid(), model.ManufacturerName, model.MandarinName, DateTime.Now);
this .ManufacturerService.CreateManufacturer(manufacturer);
return RedirectToAction( " Index " );
}
catch
{
return View();
}
}
return View(model);
}
//
// GET: /Manufacturer/Edit/5
public ActionResult Edit(Guid id)
{
if (id != Guid.Empty)
{
Manufacturer manufacturer = this .ManufacturerService.GetManufacturerByID(id);
MvcApplicationDemo.Models.ManufacturerModel model = new MvcApplicationDemo.Models.ManufacturerModel();
model.ManufacturerName = manufacturer.ManufacturerName;
model.MandarinName = manufacturer.MandarinName;
return View(model); // 用Model返回数据
}
else
{
return View();
}
}
//
// POST: /Manufacturer/Edit/5
[HttpPost]
public ActionResult Edit(Guid id, MvcApplicationDemo.Models.ManufacturerModel model)
{
try
{
// TODO: Add update logic here
Manufacturer manufacturer = new Manufacturer();
manufacturer.Uid = id;
manufacturer.ManufacturerName = model.ManufacturerName;
manufacturer.MandarinName = model.MandarinName;
this .ManufacturerService.UpdateManufacturer(manufacturer);
return RedirectToAction( " Index " );
}
catch
{
return View();
}
}
//
// GET: /Manufacturer/Delete/5
public ActionResult Delete(Guid id)
{
if (id != Guid.Empty)
{
this .ManufacturerService.DeleteManufacturer(id);
}
return RedirectToAction( " Index " );
}
//
// POST: /Manufacturer/Delete/5
// [HttpPost] // 删除不需要Post方式
// public ActionResult Delete(Guid id, FormCollection collection)
// {
// try
// {
// // TODO: Add delete logic here
// if (id != null)
// {
// this.ManufacturerService.DeleteManufacturer(id);
// }
// return RedirectToAction("Index");
// }
// catch
// {
// return View();
// }
// }
// 添加自定义的Action
public ActionResult CheckManufacturerName( string manufacturername)
{
if ( ! string .IsNullOrEmpty(manufacturername))
{
// JsonResult专门用来返回Json对象
JsonResult jresult = new JsonResult();
jresult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
jresult.Data = this .ManufacturerService.CheckManufacturerName(manufacturername);
return jresult;
}
return View();
}
}
}
//Models/ManufacturerModel.cs
View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcApplicationDemo.Models
{
public class ManufacturerModel
{
[System.ComponentModel.DataAnnotations.Required]
[System.ComponentModel.DisplayName( " 制造商名称 " )] // 文本框前的文本信息, 需要配合LabelFor()
public string ManufacturerName { get ; set ; }
[System.ComponentModel.DataAnnotations.Required]
[System.ComponentModel.DisplayName( " 中文名称 " )]
public string MandarinName { get ; set ; }
}
}
//Views/Shared/Site.Master
View Code
<% @ Master Language = " C# " Inherits = " System.Web.Mvc.ViewMasterPage " %>
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" >
< html xmlns ="http://www.w3.org/1999/xhtml" >
< head runat ="server" >
< title >< asp:ContentPlaceHolder ID ="TitleContent" runat ="server" /></ title >
< link href ="" rel ="stylesheet" type ="text/css" />
</ head >
< body >
< div class ="page" >
< div id ="header" >
< div id ="title" >
< h1 > My MVC Application </ h1 >
</ div >
< div id ="logindisplay" >
<% Html.RenderPartial( " LogOnUserControl " ); %>
</ div >
< div id ="menucontainer" >
< ul id ="menu" >
< li > <% = Html.ActionLink( " Home " , " Index "
,
"
Home
"
)
%>
</
li
>
< li > <% = Html.ActionLink( " About " , " About "
,
"
Home
"
)
%>
</
li
>
< li > <% = Html.ActionLink( " Manufacturer " , " Index "
,
"
Manufacturer
"
)
%>
</
li
>
</ ul >
</ div >
</ div >
< div id ="main" >
< asp:ContentPlaceHolder ID ="MainContent" runat ="server" />
< div id ="footer" >
</ div >
</ div >
</ div >
</ body >
</ html >
//Views/Manufacturer/Index.aspx
View Code
<% @ Page Title = "" Language = " C# " MasterPageFile = " ~/Views/Shared/Site.Master " Inherits
=
"
System.Web.Mvc.ViewPage
"
%>
<% @OutputCache Duration = " 1 " VaryByParam = " * " %>
< asp:Content ID ="Content1" ContentPlaceHolderID ="TitleContent" runat ="server" >
制造商
</ asp:Content >
< asp:Content ID ="Content2" ContentPlaceHolderID ="MainContent" runat ="server" >
< h2 > 制造商 </ h2 >
<% = Html.ActionLink( " 添加 " , " Create " ) %>
< hr />
<% var manufacturers = ViewData[ " manufacturers " ] as IEnumerable < MvcApplicationDemo.Manufacturer > ;
%>
< table >
< tr >
< td > 制造商ID </ td >
< td > 制造商名称 </ td >
</ tr >
<%
foreach (var m in manufacturers)
{
%>
< tr >
< td > <% = Html.Encode(m.Uid) %> </ td > <% -- Encode用来防止用户直接输入Html元素 --
%>
< td > <% = Html.Encode(m.ManufacturerName) %> </ td >
< td > <% = Html.ActionLink( " 详细 " , " Details " ,
new
{ id
=
m.Uid } )
%>
</
td
>
< td > <% = Html.ActionLink( " 修改 " , " Edit " ,
new
{ id
=
m.Uid } )
%>
</
td
>
< td > <% = Html.ActionLink( " 删除 " , " Delete " ,
new
{ id
=
m.Uid } )
%>
</
td
>
</ tr >
<% } %>
</ table >
</ asp:Content >
//Views/Manufacturer/Details.aspx
View Code
<% @ Page Title = "" Language = " C# " MasterPageFile = " ~/Views/Shared/Site.Master " Inherits =
"
System.Web.Mvc.ViewPage<MvcApplicationDemo.Manufacturer>
"
%>
<% @OutputCache Duration = " 1 " VaryByParam = " * " %>
< asp:Content ID ="Content1" ContentPlaceHolderID ="TitleContent" runat ="server" >
制造商详情
</ asp:Content >
< asp:Content ID ="Content2" ContentPlaceHolderID ="MainContent" runat ="server" >
< h2 > 制造商详情 </ h2 >
<% = Html.ActionLink( " 修改 " , " Edit " , new { id = ViewData.Model.Uid} )
%>
<% = Html.ActionLink( " 返回 " , " Index " ) %>
< hr />
< ul >
< li > <% = Html.Encode(ViewData.Model.Uid) %> </ li >
< li > <% = Html.Encode(ViewData.Model.ManufacturerName) %> </ li >
< li > <% = Html.Encode(ViewData.Model.MandarinName) %> </ li >
< li > <% = Html.Encode(ViewData.Model.CreateTime) %> </ li >
<% --< li >< % = Html.Encode(ViewData.Eval( " CreateTime " )) %> </ li >
--%>
</ ul >
</ asp:Content >
//Views/Manufacturer/Create.aspx
View Code
<% @ Page Title = "" Language = " C# " MasterPageFile = " ~/Views/Shared/Site.Master " Inherits = "
System.Web.Mvc.ViewPage<MvcApplicationDemo.Models.ManufacturerModel>
"
%>
< asp:Content ID ="Content1" ContentPlaceHolderID ="TitleContent" runat ="server" >
添加制造商
</ asp:Content >
< asp:Content ID ="Content2" ContentPlaceHolderID ="MainContent" runat ="server" >
< h2 > 添加制造商 </ h2 >
<% Html.BeginForm(); %>
< fieldset >
< legend > 制造商信息 </ legend >
制造商名称: <% = Html.TextBoxFor(m => m.ManufacturerName) %>
<% = Html.ValidationMessageFor(m => m.ManufacturerName) %> < br />
中文名称: <% = Html.TextBoxFor(m => m.MandarinName) %>
<% = Html.ValidationMessageFor(m => m.MandarinName) %> < br />
< br />
< input type ="submit" value ="保存" />
</ fieldset >
<% Html.EndForm(); %>
</ asp:Content >
//Views/Manufacturer/Edit.aspx
View Code
<% @ Page Title = "" Language = " C# " MasterPageFile = " ~/Views/Shared/Site.Master " Inherits = " System.Web.Mvc.ViewPage<MvcApplicationDemo.Models.ManufacturerModel>
"
%>
<% @ OutputCache Duration = " 1 " VaryByParam = " * " %>
< asp:Content ID ="Content1" ContentPlaceHolderID ="TitleContent" runat ="server" >
Edit
</ asp:Content >
< asp:Content ID ="Content2" ContentPlaceHolderID ="MainContent" runat ="server" >
< h2 >
修改制造商信息 </ h2 >
<% = Html.ActionLink( " 返回 " , " Index " ) %>
<% Html.BeginForm(); %>
< fieldset >
< legend > 制造商信息 </ legend > 制造商名称:
<% = Html.TextBoxFor(m => m.ManufacturerName, new { id = " ManuName " }) %>
< span ></ span >
< br />
中文名称:
<% = Html.TextBoxFor(m => m.MandarinName) %>
< span ></ span >
< br />
< input type ="submit" value ="保存" />
</ fieldset >
<% Html.EndForm(); %>
< script src ="" type ="text/javascript" ></ script >
< script src ="" type ="text/javascript" ></ script >
< script type ="text/javascript" >
// 关闭缓存的做法: 1.修改Url 2.设置Ajax关闭缓存 3.<OutputCache> 4.<META HTTP-EQUIV="Pragma" CONTENT="no-cache"><META HTTP-EQUIV="Expires" CONTENT="-1">
// $.ajax({
// cache: false
// });
$( function () {
// alert("hello");
$( " form " ).validate(
// 通过一个参数对象描述验证信息
{
rules: {
ManufacturerName: {
required: true ,
minlength: 2 ,
remote: ' <%=Url.Action("CheckManufacturerName") + "?" + DateTime.Now.ToLongTimeString() %> '
},
MandarinName: {
minlength: 2
}
},
messages: {
ManufacturerName: {
required: " 必须输入供应商名称 " ,
minlength: jQuery.format( " 供应商名称至少包含 {0} 个字符 " ),
remote: " 供应商已经存在,请检查名称。 "
},
MandarinName: {
minlength: jQuery.format( " 中文名称至少包含 {0} 个字符 " )
}
},
errorPlacement: function (error, element) {
error.appendTo(element.next( " span " ));
},
success: function (label) {
// set as text for IE
label.html( " " ).addClass( " checked " );
}
});
})
</ script >
</ asp:Content >
//Global.asax.cs
View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace MvcApplicationDemo
{
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit http://go.microsoft.com/?LinkId=9394801
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute( " {resource}.axd/{*pathInfo} " );
// 最常见的路由设置
routes.MapRoute(
" Default " , // Route name
" {controller}/{action}/{id} " , // URL with parameters
new { controller = " Home " , action = " Index " , id = UrlParameter.Optional }
//
Parameter defaults
);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
// 注册路由
RegisterRoutes(RouteTable.Routes);
}
}
}