• 学习笔记 工厂、单体、适配器、策略、观察者、MVC设计模式及ASP.NET MVC开发模式、关闭缓存的方法


    关于工厂、单体、适配器、策略、观察者没啥好说的, 代码中有说明

    //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 version="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="http://www.cnblogs.com/Content/Site.css" 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="http://www.cnblogs.com/Scripts/jquery-1.4.1-vsdoc.js" type="text/javascript"></script>

    <script src="http://www.cnblogs.com/Scripts/jquery.validate-vsdoc.js" 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 &nbsp; as text for IE
    label.html("&nbsp;").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);
    }
    }
    }
  • 相关阅读:
    Tips_信息列表(手风琴)效果的多种实现方法
    JS_ Date对象应用实例
    JS _函数作用域及变量提升
    C_使用clock()函数获取程序执行时间
    C_输入一个整数N,输出从0~N(算法思考)
    Chrome_查看 webSocket 连接信息
    Chrome_断点调试(使用vue-resource进行数据交互)
    Tips_利用padding实现高度可控的分隔线
    CSS_圣杯布局和双飞翼布局
    Tips_一级菜单栏实现
  • 原文地址:https://www.cnblogs.com/cs_net/p/1958022.html
Copyright © 2020-2023  润新知