美高梅4688官方网站这是由于没有添加相应的引用造成的,业务逻辑层的架构和基本功能

ASP.NET 或 VC# 中,using 了名称空间,但仍然不提示该名称空间下的类。

嘴上不说 心里却想MD 这家伙在博客园装了这么久的高手 竟然连这都不会 ,我去噢。

上次业务逻辑和展示层的架构都写了,可以开始进行具体功能的实现,这次先实现管理员的登录、验证和注销功能。

这是由于没有添加相应的引用造成的。

程序集签名

.net 下 “程序集” 什么东东 ,反正就是听着挺牛x的,其实就是指“一堆程序”从我们传统的C++封装的dll 认知 就是一个dll文件名 然后一个lib文件里面有对应的函数列表,把lib文件添加进去就OK了。

呐 现在我们来新建一个空白Asp.net网站
打开web.config 里面就有一些默认引用的程序集

1 <assemblies>
2         <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>            
3     <add assembly="System.Xml.Linq, Version=3.5.0.0,Culture=neutral,PublicKeyToken=B77A5C561934E089"/>
4 </assemblies>

看见那些唧唧歪歪的属性没有 System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089 这都是些啥 ,这就是程序集信息 .net下对程序集的定义已经超出我们原来对dll文件认知的那种范畴了,程序集信息指代“一堆可用程序功能”经过签名的唯一电子标签信息。

系统目录的程序集称之为GAC ,global assembly cache,就是我们平常用的console.write()啊 messageBox.show()啊啥的 。他放在C:WINDOWSassembly 进入那个目录下后发现资源管理器的视图变得很特殊。发现只可查看属性 而不能拷走里面的文件。要拷走也可以 在dos命令行下就可以了 他是以命名空间为目录树存放的。

我们自己的程序集也可放到GAC里 需要这样做:
放到GAC下的程序集必须使用一个私钥进行签名(附加强名称)方式如下:

  1. 在vs命令行 sn -k d:/key.snk
  2. 写好代码 编译 csc /keyfile:d:/test.snk /target:library function.cs
  3. 会有个function.dll文件产生 使用命令gacutil /i function.dll安装
  4. 在上面空白的asp.net网站里我们平常都是右键->添加引用 然后选中dll文件。 代码中using 命名空间 然后就按常规的方式使用。现在我们不用了 只需要在web.config 的<assemblies>里添加一行就可以了,像这样:
    <addassembly="Function,Version=0.0.0.0,Culture=neutral,PublicKeyToken=6ac36eab110b624e"/>
    前几个值都知道 但是这个PublicKeyToken怎么看呢 直接在C:WINDOWSassembly就可看到:
     美高梅4688官方网站 1
    其他各种方式都可以 比如sn -t 文件名。然后代码中using 命名空间 然后就按常规的方式使用。

普通程序集在不破坏pe文件结构的情况修改后是可以运行的。而经过强名称签名的则不可以,有效的保证了程序完整性.。
注意在.net3.5或以上版本不论在编译时选什么版本加了强名称都还是可以更改的。因为.net认为你的程序运行在一个"受信任的环境" 所以强名称验证是被pass的。但是加到GAC应该是加不进去的 加到GAC必定会进行强名称验证。要想进行强名称验证不被pass在app.config 里添加这样的配置:

1 <configuration>
2    <runtime>
3       <bypassTrustedAppStrongNames enabled="false"/>
4    </runtime>
5 </configuration>

附:
使用gacutil /i function.dll卸载
也可在C:WINDOWSassembly目录 选中程序集点右键 卸载。
csc命令的各种使用方式:
生成dll的签名文件:
D:>sn -k keyfor_function.snk
附加签名编译为dll:
D:>csc /keyfile:keyfor_function.snk /t:library function.cs
附加dll编译主调程序源码:
D:>csc /reference:function.dll kit.cs

 

 

目录

奔跑吧,代码小哥!

MVC5网站开发之一 总体概述

MVC5 网站开发之二 创建项目

MVC5 网站开发之三 数据存储层功能实现

MVC5 网站开发之四 业务逻辑层的架构和基本功能

MVC5 网站开发之五 展示层架构

MVC5 网站开发之六 管理员 1、登录、验证和注销

MVC5 网站开发之六 管理员 2、添加、删除、重置密码、修改密码、列表浏览

MVC5 网站开发之七 用户功能 1、角色的后台管理

 

 

举个例子,ConfigurationManager 类位于 System.Configuration 中,但我们可能还需要考虑其程序集,其程序集在 system.configuration.dll,如果无法使用请添加程序集引用。

msil

.net运行时东西大部分的人是不会去刻意学他的,啥CLR 啊 JIT  啊 我也不懂 不能装高手 更不能拿出来吹。 入门的还是得给自己普及下。.net的exe是中间语言代码 这不得不说ilasm 跟ildasm,一个是编译 一个是反编译。先来演示一下怎样简单“破解”一个小程序。顺便我们也来玩玩ildsam

新建一个控制台程序
写几句代码:

 1 using System;
 2 namespace test
 3 {
 4     class Program
 5     {
 6         static void Main(string[] args)
 7         {
 8             //验证不通过程序立即退出
 9             if (licence() == false)
10             {
11                 Console.WriteLine("invalid license");
12                 Console.ReadKey();
13                 return;
14             }
15             else//验证成功 程序继续运行
16             {
17                 Console.WriteLine("licence is ok");
18                 Console.ReadKey();
19             }
20         }
21         static bool licence()
22         {
23             //假设这里是一个硬件ID授权认证
24             //共享软件的注册验证 根据硬盘串号通过指定加密算法得到密文 即注册码
25             //硬盘串号加密得到的密文跟注册码进行匹配
26             //如果不一样则认为软件已被拷到未被授权的电脑上使用 return false
27             return false;
28         }
29     }
30 }

在项目属性上->右键->属性
添加程序签名:
美高梅4688官方网站 2
项目上->右键->添加->新建项->应用程序配置文件
项目下多了app.config
编辑它

1 <?xml version="1.0"?>
2 <configuration>
3   <runtime>
4     <bypassTrustedAppStrongNames enabled="false"/>
5   </runtime>
6 </configuration>

现在编译并运行

运行输出 invalid licence
美高梅4688官方网站 3

很明显验证不通过

呐现在我们就来对他进行破解 让他验证通过

然后打开il dasm 工具
如果不知道在哪里打开 就在vs命令行里输入ildasm
然后打开我们在debug目录编译后的exe文件
美高梅4688官方网站 4
美高梅4688官方网站 5代表test命名空间
美高梅4688官方网站 6代表program类
美高梅4688官方网站 7咦这啥东东 咱在代码里没写这个方法啊

咱在书上学过如果没有写构造方法 则编译时提供默认的构造方法
看 这里就是这个意思 ctor可能全称是 constructor

打开main函数 代码如下:

 1 .method private hidebysig static void  Main(string[] args) cil managed
 2 {
 3   .entrypoint
 4   // 代码大小       50 (0x32)
 5   .maxstack  1
 6   .locals init ([0] bool CS$4$0000)
 7   IL_0000:  nop
 8   IL_0001:  call       bool test.Program::licence()
 9   IL_0006:  stloc.0
10   IL_0007:  ldloc.0
11   IL_0008:  brtrue.s   IL_001e
12   IL_000a:  nop
13   IL_000b:  ldstr      "invalid license"
14   IL_0010:  call       void [mscorlib]System.Console::WriteLine(string)
15   IL_0015:  nop
16   IL_0016:  call       valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
17   IL_001b:  pop
18   IL_001c:  br.s       IL_0031
19   IL_001e:  nop
20   IL_001f:  ldstr      "licence is ok"
21   IL_0024:  call       void [mscorlib]System.Console::WriteLine(string)
22   IL_0029:  nop
23   IL_002a:  call       valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
24   IL_002f:  pop
25   IL_0030:  nop
26   IL_0031:  ret
27 } // end of method Program::Main

打开licence函数 代码如下:

 1 .method private hidebysig static bool  licence() cil managed
 2 {
 3   // 代码大小       7 (0x7)
 4   .maxstack  1
 5   .locals init ([0] bool CS$1$0000)
 6   IL_0000:  nop
 7   IL_0001:  ldc.i4.0
 8   IL_0002:  stloc.0
 9   IL_0003:  br.s       IL_0005
10   IL_0005:  ldloc.0
11   IL_0006:  ret
12 } // end of method Program::licence

然后单击文件菜单->转储
保存为il 文件
我们只需要在main函数中更改条件判断 让他验证通过就可以了
用记事本打开保存的il文件
找到这一行 看到没有
IL_0008:  brtrue.s   IL_001e

如果改成这样呢
IL_0008:  brfalse.s   IL_001e
试下吧

改完后在vs命令行使用ilasm test.il 把il文件重新编译成exe文件

这时我们再次运行test.exe
咦怎么回事 不成功

1 未处理的异常:  System.IO.FileLoadException: 未能加载文件或程序集“test, Version=
2 1.0.0.0, Culture=neutral, PublicKeyToken=e49d145887009c3e”或它的某一个依赖项。
3 强名称验证失败。 (异常来自 HRESULT:0x8013141A)
4 文件名:“test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e49d145887009c3e
5 ” ---> System.Security.SecurityException: 强名称验证失败。 (异常来自 HRESULT:0x
6 8013141A)
7 失败的程序集的区域是:
8 MyComputer

因为有程序签名,所以我们还得把强名称去掉。
再次打开il文件
看到有这样3处开始的地方:
.publickeytoken
.publickey
.hash

把他们删除
然后再用ilasm编译 并运行发现验证成功
美高梅4688官方网站 8

注意:
如果程序集加了强名称 改了pe文件的任何内容后都是无法启动的 就像有绑定的MD5校验一样。为了保护程序 都会使用混淆器进行处理 ,而混淆器正好又会更改文件内容。

另外:
说俗点高级语言也无非就
int var1=123
if(){
}
else{}

for(){}
这些之类的
看了下网上il的代码解析 以及以前看过一些对汇编的理解 虽然不用汇编做开发。
汇编是基于堆栈的 流水线 似的操作 ,事先初始化的变量在编译时都是确定好的 入栈出栈操作 ,每次都进行一个指令 对寄存器赋值 或者进行运算 地址跳转 等。

仔细想想有了这些基础特征就够了 高级语言的那些语法基本上都可以实现只不过要麻烦些

int var1=123
这个不说了

if(){
}
else{}
在汇编里估计是通过条件 地址跳转啥的来实现

for(){}
其实也很简单
看了一点il的代码 发现也就是一个连续if的过程 条件达不到跳转到前面的地址继续n++
像这样
int n=1;
loop:
n++;
console.writeline("hi");
if(n<50)
goto loop;

其实我不懂汇编语言的 有些乱说的见谅 勿喷。

一、业务逻辑层

在解决方案中,网站是直接在网站上右键->Add Reference,项目是在其“引用”上右键->添加。

1、实现256散列加密方法。

Ninesky.Core【右键】-> 添加->文件夹,输入文件夹名General。

General文件夹【右键】->添加->类,输入类名Security。

引用System.Security.Cryptography命名空间(1),并实现SHA256静态加密方法。

美高梅4688官方网站 9

美高梅4688官方网站 10

2、Administrator模型类

美高梅4688官方网站 11

Ninesky.Core【右键】-> 添加->,输入类名Administrator。

添加引用System.ComponentModel.DataAnnotations; 完成的类代码

using System;
using System.ComponentModel.DataAnnotations;

namespace Ninesky.Core
{
    /// <summary>
    /// 管理员模型
    /// </summary>
    public class Administrator
    {
        [Key]
        public int AdministratorID { get; set; }

        /// <summary>
        /// 帐号
        /// </summary>
        [Required(ErrorMessage = "必须输入{0}")]
        [StringLength(30, MinimumLength = 4, ErrorMessage ="{0}长度为{2}-{1}个字符")]
        [Display(Name ="帐号")]
        public string Accounts { get; set; }

        /// <summary>
        /// 密码
        /// </summary>

        [DataType(DataType.Password)]
        [Required(ErrorMessage = "必须输入{0}")]
        [StringLength(256,ErrorMessage = "{0}长度少于{1}个字符")]
        [Display(Name = "密码")]
        public string Password { get; set; }

        /// <summary>
        /// 登录IP
        /// </summary>
        [Display(Name = "登录IP")]
        public string LoginIP { get; set; }

        /// <summary>
        /// 登录时间
        /// </summary>
        [Display(Name = "登录时间")]
        public Nullable<DateTime> LoginTime { get; set; }

        /// <summary>
        /// 创建时间
        /// </summary>
        [Display(Name = "创建时间")]
        public DateTime CreateTime { get; set; }
    }
}

3、数据上下文

打开Ninesky.Core->NineskyContext.cs 添加Administrators属性

美高梅4688官方网站 12

红框内为添加内容。

4、AdministratorManager管理类

美高梅4688官方网站 13

 

Ninesky.Core【右键】-> 添加->,输入类名AdministratorManager。

类继承自BaseManager<Administrator>。

为类添加Ninesky.Core.Types引用。

using Ninesky.Core.Types;
using System;

namespace Ninesky.Core
{
    public class AdministratorManager : BaseManager<Administrator>
    {
        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="admin">管理员实体</param>
        /// <returns></returns>
        public override Response Add(Administrator admin)
        {
            Response _resp = new Response();
            if (HasAccounts(admin.Accounts))
            {
                _resp.Code = 0;
                _resp.Message = "帐号已存在";
            }
            else _resp = base.Add(admin);
            return _resp;
        }

        /// <summary>
        /// 修改密码
        /// </summary>
        /// <param name="administratorID">主键</param>
        /// <param name="password">新密码【密文】</param>
        /// <returns></returns>
        public Response ChangePassword(int administratorID, string password)
        {
            Response _resp = new Response();
            var _admin = Find(administratorID);
            if (_admin == null)
            {
                _resp.Code = 0;
                _resp.Message = "该主键的管理员不存在";
            }
            else
            {
                _admin.Password = password;
                _resp = Update(_admin);
            }
            return _resp;
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="administratorID">主键</param>
        /// <returns></returns>
        public override Response Delete(int administratorID)
        {
            Response _resp = new Response();
            if (Count() == 1)
            {
                _resp.Code = 0;
                _resp.Message = "不能删除唯一的管理员帐号";
            }
            else _resp = base.Delete(administratorID);
            return _resp;
        }

        /// <summary>
        /// 查找
        /// </summary>
        /// <param name="accounts">帐号</param>
        /// <returns></returns>
        public Administrator Find(string accounts)
        {
            return base.Repository.Find(a => a.Accounts == accounts);
        }

        /// <summary>
        /// 帐号是否存在
        /// </summary>
        /// <param name="accounts">帐号</param>
        /// <returns></returns>
        public bool HasAccounts(string accounts)
        {
            return base.Repository.IsContains(a => a.Accounts.ToUpper() == accounts.ToUpper());
        }

        /// <summary>
        /// 更新登录信息
        /// </summary>
        /// <param name="administratorID">主键</param>
        /// <param name="ip">IP地址</param>
        /// <param name="time">时间</param>
        /// <returns></returns>
        public Response UpadateLoginInfo(int administratorID, string ip, DateTime time)
        {
            Response _resp = new Response();
            var _admin = Find(administratorID);
            if (_admin == null)
            {
                _resp.Code = 0;
                _resp.Message = "该主键的管理员不存在";
            }
            else
            {
                _admin.LoginIP = ip;
                _admin.LoginTime = time;
                _resp = Update(_admin);
            }
            return _resp;
        }

        /// <summary>
        /// 验证
        /// </summary>
        /// <param name="accounts">帐号</param>
        /// <param name="password">密码【密文】</param>
        /// <returns>Code:1-成功;2-帐号不存在;3-密码错误</returns>
        public Response Verify(string accounts, string password)
        {
            Response _resp = new Response();
            var _admin = base.Repository.Find(a => a.Accounts == accounts);
            if (_admin == null)
            {
                _resp.Code = 2;
                _resp.Message = "帐号为:【" + accounts + "】的管理员不存在";
            }
            else if (_admin.Password == password)
            {
                _resp.Code = 1;
                _resp.Message = "验证通过";
            }
            else
            {
                _resp.Code = 3;
                _resp.Message = "帐号密码错误";
            }
            return _resp;
        }
    }
}

二、展示层实现

首先,添加css。

Ninesky.Web->Content【右键】->添加->试样表,输入名称StyleControl。

打开Ninesky.Web->App_Start->BundleConfig.cs。

美高梅4688官方网站 14

添加红框内代码。StyleControl.css具体内容这里省略了。

其次,添加对Ninesky.Core的引用。

Ninesky.Web->引用【右键】->添加引用.。在引用管理器中选择 项目->解决方案->Ninesky.Core.

处理完这两项内容就继续具体内容了:

1、管理员身份验证类AdminAuthorizeAttribute

AdminAuthorizeAttribute继承自AuthorizeAttribute,重写AuthorizeCore方法,通过Session["AdminID"]来判断管理员是否已经登录,重写HandleUnauthorizedRequest方法来处理未登录时的页面跳转。

using System.Web;
using System.Web.Mvc;

namespace Ninesky.Web.Areas.Control
{
    /// <summary>
    /// 管理员身份验证类
    /// </summary>
    public class AdminAuthorizeAttribute : AuthorizeAttribute
    {
        /// <summary>
        /// 重写自定义授权检查
        /// </summary>
        /// <returns></returns>
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (httpContext.Session["AdminID"] == null) return false;
            else return true;
        }
        /// <summary>
        /// 重写未授权的 HTTP 请求处理
        /// </summary>
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            filterContext.Result = new RedirectResult("~/Control/Admin/Login");
        }
    }
}

Ninesky.Web->Areas->Control【右键】->添加->,输入控制器名称HomeController。

HomeController添加[AdminAuthorize]

美高梅4688官方网站 15

2、管理员控制器

Ninesky.Web->Areas->Control->Controllers【右键】->添加->控制器。选择 MVC5 控制器 – 空, 输入控制器名称Admin。

在控制器中引用Ninesky.Core、Ninesky.Core.GeneralNinesky.Web.Areas.Control.Models命名空间。

添加私有变量private AdministratorManager adminManager = new AdministratorManager();

为AdminController添加[AdminAuthorize]

3.1 管理员登录

3.1.1 登录视图模型

Ninesky.Web->Areas->Control->Models【右键】->添加->类,输入类名LoginViewModel。

namespace Ninesky.Web.Areas.Control.Models
{
    /// <summary>
    /// 登录模型
    /// </summary>
    public class LoginViewModel
    {
        /// <summary>
        /// 帐号
        /// </summary>
        [Required(ErrorMessage = "必须输入{0}")]
        [StringLength(30, MinimumLength = 4, ErrorMessage = "{0}长度为{2}-{1}个字符")]
        [Display(Name = "帐号")]
        public string Accounts { get; set; }


///

/// 密码 /// [DataType(DataType.Password)] [Required(ErrorMessage = "必须输入{0}")] [StringLength(20,MinimumLength =6, ErrorMessage = "{0}长度{2}-{1}个字符")] [Display(Name = "密码")] public string Password { get; set; } } }

3.1.2 登录方法

在AdminController中添加Login()方法

/// <summary>
        /// 登录
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        public ActionResult Login()
        {
            return View();
        }

3.1.3 登录视图

Login()方法上点【右键】->添加视图

美高梅4688官方网站 16

模板选Create,模型类选LoginViewModel ,选项选中引用脚本库。完成后代码

@model Ninesky.Web.Areas.Control.Models.LoginViewModel

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>登录</title>
    @Styles.Render("~/Content/controlcss")
    @Scripts.Render("~/bundles/modernizr")
</head>
<body>
    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/jqueryval")

    <div class="loginform">


        <div class="form-horizontal">
            <h2 class="text-primary">登录</h2>
            @using (Html.BeginForm())
            {
                @Html.AntiForgeryToken()
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group form-group-lg">
                    @Html.EditorFor(model => model.Accounts, new { htmlAttributes = new { @class = "form-control", placeholder = "帐号" } })
                    @Html.ValidationMessageFor(model => model.Accounts, "", new { @class = "text-danger" })
                </div>
                <div class="form-group form-group-lg">
                    @Html.EditorFor(model => model.Password, new { htmlAttributes = new { @class = "form-control", placeholder = "密码" } })
                    @Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-danger" })
                </div>
                <div class="form-group form-group-lg">
                    <input type="submit" value="登录" class="btn btn-default pull-right" />
                </div>
            }
        </div>

    </div>
</body>
</html>

在AdminController中添加登录的处理方法public ActionResult Login(LoginViewModel loginViewModel)

[AllowAnonymous]
        [ValidateAntiForgeryToken]
        [HttpPost]
        public ActionResult Login(LoginViewModel loginViewModel)
        {
            if(ModelState.IsValid)
            {
                string _passowrd = Security.SHA256(loginViewModel.Password);
                var _response = adminManager.Verify(loginViewModel.Accounts, _passowrd);
                if (_response.Code == 1)
                {
                    var _admin = adminManager.Find(loginViewModel.Accounts);
                    Session.Add("AdminID", _admin.AdministratorID);
                    Session.Add("Accounts", _admin.Accounts);
                    _admin.LoginTime = DateTime.Now;
                    _admin.LoginIP = Request.UserHostAddress;
                    adminManager.Update(_admin);
                    return RedirectToAction("Index", "Home");
                }
                else if (_response.Code == 2) ModelState.AddModelError("Accounts", _response.Message);
                else if (_response.Code == 3) ModelState.AddModelError("Password", _response.Message);
                else ModelState.AddModelError("",_response.Message);
            }
            return View(loginViewModel);
        }

4、注销

在AdminController中添加注销的处理方法public ActionResult Logout()

/// <summary>
        /// 注销
        /// </summary>
        /// <returns></returns>
        public ActionResult Logout()
        {
            Session.Clear();
            return RedirectToAction("Login");
        }

完工可以按F5测试了。

 

美高梅4688官方网站 17

登录界面,输入帐号mzwhj 密码123456,登录成功。

美高梅4688官方网站 18

登录成功界面。

 

=====================================================

代码见:

代码下载:https://ninesky.codeplex.com 点击SOURCE CODE 点击Download下载源文件。

本文由美高梅4688官方网站发布于美高梅4688官方网站,转载请注明出处:美高梅4688官方网站这是由于没有添加相应的引用造成的,业务逻辑层的架构和基本功能

您可能还会对下面的文章感兴趣: