1.MVC身份验证.

有两种方式.一个是传统的所有控制器继承自定义Control,然后再里面用MVC的过滤器拦截.所以每次网站的后台被访问时.就会先走入拦截器.进行前端和后端的验证

一个是利用(MVC4及以上版本)自动生成的Global.asax.cs中的 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters),这个file会加载所有的过滤器.第一种方式适用目前任何版本,第二种支持MVC4以及以上,下面对两种方式一一细讲

1.

public class CountController : BaseController
            CountController是自定义Controller,BaseController是需要继承的Control
Base里两行是精华.其他自定义
public class BaseController : Controller

protected override void OnActionExecuting(ActionExecutingContext filterContext)

第一行是Control原本继承的父类.所以目前的控制器多继承了一个父类.第二行代码就是要多继承一次的原因.OnActionExecuting是每个Action被调用前.不论是Actionresult还是Jsonresult.都会被拦截.然后我们可以拿到Request.Cookie和相关的请求地址.

就像这杨 url = $"/{filterContext.ActionDescriptor.ControllerDescriptor.ControllerName}/{filterContext.ActionDescriptor.ActionName}"; 还有这杨cookieName = Request.Cookies["userName"].Value.ToString();

一般cookie中会包含请求人信息.然后我们根据数据库就能检测出此人是否能访问这个前端页面或者后端接口.如果通过Return true ,反之

   Response.RedirectToRoute(new { controller = "Error", action = "NotFound", Content = "权限不足,请联系管理员" });
return;

这杨就会跳到异常页面了.

如果通过了身份验证.就可以设定一个全局通用身份.HttpContext.Current.User.Identity.Name.方便后面接口使用.但这个属性是只读的.所以要往上重写IPrincipal

public class MyPrincipal : System.Security.Principal.IPrincipal
{
public MyPrincipal(string userID)
{
Identity = new MyIdentity(userID);
} public System.Security.Principal.IIdentity Identity { get; set; } public bool IsInRole(string role)
{
return true;
}
} public class MyIdentity : System.Security.Principal.IIdentity
{
public MyIdentity(string currentUserID)
{
Name = currentUserID;
} public bool IsAuthenticated
{
get
{
return true;
}
} public string Name { get; } public string AuthenticationType
{
get
{
return null;
}
}
}
最后赋值的方式:
MyPrincipal principal = new MyPrincipal(userName);
HttpContext.User = principal;

     2.(MVC4及以上版本)自动生成的Global.asax.cs中的 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters),提供三种拦截器.Action,Result,Exption,分别是方法拦截.结果拦截.异常拦截,

在fileconfig中添加三个过滤器

public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//filters.Add(new HandleErrorAttribute());
filters.Add(new ActionFillters());
filters.Add(new ExceptionFillters());
filters.Add(new ResultFillters()); }
}

为了方便我将三个过滤器写在一个类中

namespace MvcApplication2.App_Start
{
public class ActionFillters : FilterAttribute, IActionFilter
{
public void OnActionExecuted(ActionExecutedContext filterContext)
{
//执行action后执行这个方法 比如做操作日志
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
//执行action前执行这个方法,比如做身份验证
}
}
public class ExceptionFillters : FilterAttribute, IExceptionFilter
{
//发生异常时会执行这段代码
public void OnException(ExceptionContext filterContext)
{
//在这里你可以记录发生异常时你要干什么,比例写日志 //这一行告诉系统,这个异常已经处理了,不用再处理
filterContext.ExceptionHandled = true;
}
}
public class ResultFillters : FilterAttribute, IResultFilter
{
public void OnResultExecuted(ResultExecutedContext filterContext)
{
//执行完action后跳转后执行
} public void OnResultExecuting(ResultExecutingContext filterContext)
{
//执行完action后跳转前执行
}
} }

           3.接下来介绍MVC6新关键字.Task,Async(异步)

对线程进行了封装.变成了属性.简单举个例子

using System;
using System.Threading;
using System.Threading.Tasks; namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
new Task(StartCode, ).Start();
Console.WriteLine("主线程运行到此");
Thread.Sleep(); Task<Int32> t = new Task<Int32>(n => Sum((Int32)n), );
t.Start();
t.Wait();
Console.WriteLine("The Sum is:" + t.Result); }
private static void StartCode(object i)
{
Console.WriteLine("开始执行子线程...{0}", i);
Thread.Sleep();//模拟代码操作
}
private static Int32 Sum(Int32 i)
{
Int32 sum = i; return sum-;
}
}
}

在这段代码中.Task是单独启动了一个子线程运行方法.和主线程互不干涉.但是有一点Task接受到的返回值要加上Result.不然返回的是整个线程属性

    接下来讲下Task和MVC6的结合
 public async Task<JsonResult> Test()
{
var jsonresult = await DATA();
return Json(jsonresult); }
private Task<string> DATA()
{
return Task.FromResult("HELLO");
}

根据约定Async 和await 永远是成双成对

Async代表异步 Task代表线程

接受时 用await

返回值用 Task.FromResult封装

好吧。真的很简单的新属性

前端模拟表单验证.

大家都用过MVC的表单吧.大致是view模型绑定.from 中submit 提交. controll同名同参方法接受

但是在实际运用中略限僵硬.如果一个实体类要多次提交呢?MVC默认以实体类的名字作为控件ID,一个页面出现两个同名控件只会拿到第一个的值.所以需要自定义部分表单提交.那么从头讲起吧

引入以下文件

<link rel="stylesheet" href="~/Scripts/bootstrapValidator.css" />
<script src="~/Scripts/bootstrapValidator.js"></script>

HTML表单 <form id="formEditAPP" method="post" action=""> HTML控件在表单中实际取的NAME <input class="form-control" id="EditAPPSysId" type="text" name="EditAPPSysId" readonly="readonly">

在JQUERY中

   $("#formEditAPP").bootstrapValidator({
live: 'enabled',//验证时机,enabled是内容有变化就验证(默认),disabled和submitted是提交再验证
message: '通用的验证失败消息',
feedbackIcons: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
},
fields: {
EditappAccount: {
validators: {
notEmpty: {
message: '通道账号必填'
}
}
},
EditappPassword: {
validators: {
notEmpty: {
message: '通道密码必填'
}
}
}, }
});

当没有通过验证的时候

  

    模拟表单的提交

   $("#EditAPPSubmit").click(function () {
$("#formEditAPP").bootstrapValidator('validate');//提交验证
if ($("#formEditAPP").data('bootstrapValidator').isValid()) {//获取验证结果,如果成功,执行下面代码
$("#formEditAPP").data('bootstrapValidator').resetForm();
var array = new Object();
array.sysId = $("#EditAPPSysId").val();
array.account = $("#EditappAccount").val();
array.password = $("#EditappPassword").val();
array.appEnable = $("#EditappEnable option:selected").val();
array.appChannel = $("#EditAppChannel option:selected").val();

数组的值和服务端实体类对应,ajax 设置参数如下

     $.ajax({
url: '/Business/UpdateSystemSms',
type: "post",
data: JSON.stringify(array),
contentType: "application/json; charset=utf-8",

服务端设置参数如下

UpdateSystemSms([System.Web.Http.FromBody]MsgSysAppConfigEntity sysConfig)

         自定义匿名集合

很多时候我们不想写实体类.如何偷懒呢

    var trackList = new[]{ new  {
ID = string.Empty,
ChannelKey=string.Empty,
ToMobilStatus=,
CreateTime = string.Empty,
Type=string.Empty
}}.ToList();
trackList.Clear();

这杨数组中NEW匿名集合.类型是List<a> {string xxx,,string xx1.....}

如果是非对应数据库实体.用这个方式.快感略强烈

   Edge导出到Excel 
在WIN10中推出了Edge替换IE,但是Edge的内核信息和IE完全不一致.所以需要更新Edge导出EXCEL的功能.至于IE,Google等其他浏览器利用TABLE导出excel可以参考之前的博客
 function EdgeToExcel(obj) {
var oHtml = document.getElementsByClassName(obj)[].outerHTML;
var excelHtml = `
<html>
<head>
<meta charset='utf-8' />
</head>
<body>
${oHtml}
</body>
</html>
`; var excelBlob = new Blob([excelHtml], { type: 'application/vnd.ms-excel' })
// 创建一个a标签
var oA = document.createElement('a');
// 利用URL.createObjectURL()方法为a元素生成blob URL
oA.href = URL.createObjectURL(excelBlob);
// 给文件命名
oA.download = '下载.xls';
// 模拟点击
oA.click();
// 移除
oA.remove();
}
     如何区分Edge呢
      function getExplorer() {
var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串
var isIE = userAgent.indexOf("compatible") > - && userAgent.indexOf("MSIE") > -; //判断是否IE<11浏览器
var isEdge = userAgent.indexOf("Edge") > - && !isIE; //判断是否IE的Edge浏览器
if (isEdge) {
return 'Edge';
}
else if (userAgent.indexOf("Chrome") >= ) {
return 'Chrome';
}
}

大家要注意WIN7 的IE 9,10,11

和WIN10 IE 9,10,11内核信息完全不一致

edge和IE的内核信息也不一致.所以在做兼容性的时候要多考虑一下

       BootstrapTree树状菜单的全选和反选.

如果没有这两个功能.一个一个点也是非常反人类的

 var nodeCheckedSilent = false;
function nodeChecked(event, node) {
if (nodeCheckedSilent) {
return;
}
nodeCheckedSilent = true;
checkAllParent(node);
checkAllSon(node);
nodeCheckedSilent = false;
} var nodeUncheckedSilent = false;
function nodeUnchecked(event, node) {
if (nodeUncheckedSilent)
return;
nodeUncheckedSilent = true;
uncheckAllParent(node);
uncheckAllSon(node);
nodeUncheckedSilent = false;
} //选中全部父节点
function checkAllParent(node) {
$('#tree').treeview('checkNode', node.nodeId, { silent: true });
var parentNode = $('#tree').treeview('getParent', node.nodeId);
if (!("nodeId" in parentNode)) {
return;
} else {
checkAllParent(parentNode);
}
} //取消全部父节点
function uncheckAllParent(node) {
$('#tree').treeview('uncheckNode', node.nodeId, { silent: true });
var siblings = $('#tree').treeview('getSiblings', node.nodeId);
var parentNode = $('#tree').treeview('getParent', node.nodeId);
if (!("nodeId" in parentNode)) {
return;
}
var isAllUnchecked = true; //是否全部没选中
for (var i in siblings) {
if (siblings[i].state.checked) {
isAllUnchecked = false;
break;
}
}
if (isAllUnchecked) {
uncheckAllParent(parentNode);
} } //级联选中所有子节点
function checkAllSon(node) {
$('#tree').treeview('checkNode', node.nodeId, { silent: true });
if (node.nodes != null && node.nodes.length > ) {
for (var i in node.nodes) {
checkAllSon(node.nodes[i]);
}
}
} //级联取消所有子节点
function uncheckAllSon(node) {
$('#tree').treeview('uncheckNode', node.nodeId, { silent: true });
if (node.nodes != null && node.nodes.length > ) {
for (var i in node.nodes) {
uncheckAllSon(node.nodes[i]);
}
}
}

       如何使用呢

   $('#tree').treeview({
data: data,
showCheckbox: true,
onNodeChecked: nodeChecked,
onNodeUnchecked: nodeUnchecked
});

已经集成的相当好啦.用的时候注意一下控件ID

       今天刚折腾了一个BOOTSTRAP可搜索下拉框.就顺带讲一下吧
    <script src="~/Scripts/Bootstrap/bootstrap-select.js" defer></script>
<link rel="stylesheet" href="~/Content/Bootstrap/bootstrap-select.css">

  <select class="form-control selectpicker show-tick" data-live-search="true" id="FromSys" name="FromSys" data-live-search="true" multiple data-actions-box="true">

                                <option value="@item.Value">@item.Text</option>

                    </select>
selectpicker show-tick 样式是可搜索下拉框必备的样式
data-live-search="true" 允许搜索 
 
multiple 下拉框允许多选
data-actions-box="true" 下拉框允许全选



MVC身份验证.MVC过滤器.MVC6关键字Task,Async.前端模拟表单验证,提交.自定义匿名集合.Edge导出到Excel.BootstrapTree树状菜单的全选和反选.bootstrap可搜索可多选可全选下拉框的更多相关文章

  1. 4.前端注册表单验证 && 表单回填

    表单验证 前端表单验证就是在 jsp 页面中添加验证逻辑,使得注册表单在传入后台之前先进行一次表单验证 在jsp文件里的 head 块里面添加 jQuery 代码 <script type=&q ...

  2. 夺命雷公狗—angularjs—2—模拟表单验证

    这里我们就来借助妹子ui来搭建下模版,废话不多说,代码如下图所示: <!doctype html> <html lang="en"> <head> ...

  3. ASP.NET MVC Jquery Validate 表单验证的多种方式

    在我们日常开发过程中,前端的表单验证很重要,如果这块处理不当,会出现很多bug .但是如果处理的好,不仅bug会很少,用户体验也会得到很大的提升.在开发过程中我们可以不借助 JS 库,自己去手写 JS ...

  4. [转]ASP.NET MVC Jquery Validate 表单验证的多种方式介绍

    在我们日常开发过程中,前端的表单验证很重要,如果这块处理不当,会出现很多bug .但是如果处理的好,不仅bug会很少,用户体验也会得到很大的提升.在开发过程中我们可以不借助 JS 库,自己去手写 JS ...

  5. ASP.NET MVC Form表单验证与Authorize特性

    一.Form表单验证 1.基本概念 表单验证是一个基于票据(ticket-based)[也称为基于令牌(token-based)]的系统.当用户登录系统以后,会得到一个包含基于用户信息的票据(tick ...

  6. webdriver--单选、复选及下拉框的定位

    单选radiobutton的操作 两种情况,一种是各个button元素的属性都有唯一定位值,可以直接用属性唯一值定位:另一种就是一组各方面属性值都一样的radiobutton,除了text,可以用组元 ...

  7. flask中单选、多选、下拉框的获取

    1.单选: source = request.form.get('source') 2.多选:   joy = request.form.getlist('joy')    或者   joy = re ...

  8. jQuery html5Validate基于HTML5表单验证插件

    更新于2016-02-25 前面提到的新版目前线上已经可以访问: http://mp.gtimg.cn/old_mp/assets/js/common/ui/Validate.js demo体验狠狠地 ...

  9. jquery 表单验证插件

    其他: <form action=""> First name: <input type="text" name="FirstNam ...

随机推荐

  1. Android手机里的垃圾文件和文件夹清理

    SD卡中各个文件夹功能的最详尽分析SD卡用久了会有好多文件夹出现,大家看看都是干什么用~ 1..android_secure  是官方app2sd的产物,删了之后装到sd卡中的软件就无法使用了.2.. ...

  2. 纯css 更改原生raiod与 checkbox的样式

    原文地址: .checkbox input[type=checkbox], .checkbox-inline input[type=checkbox], .radio input[type=radio ...

  3. HDU1423:Greatest Common Increasing Subsequence

    浅谈\(DP\):https://www.cnblogs.com/AKMer/p/10437525.html 题目传送门:http://acm.hdu.edu.cn/showproblem.php?p ...

  4. ECMAScript 2016(ES7) 知多少

    ECMAScript 2016(ES7) 知多少 1. 数组方法 Array.prototype.includes(value : any) : boolean 2. 幂运算符 x ** y 扩展阅读 ...

  5. 把ASM下的HDD VM转换成ARM下Managed Disk的SSD VM

    在ASM下,要把HDD的VM转换成SSD的VM步骤非常复杂.需要手工把Disk从普通存储账户复制到高级存储账户.再通过这个Disk创建VM. 目前在有了ASM到ARM的迁移工具,以及Managed D ...

  6. uboot - *** Warning - bad CRC, using default environment

    出现这个现象的原因 环境变量存储区没有相应的数据,产生的原因可能是: 1.首次烧写uboot启动,,出现这个提示,执行saveenv 指令保存环境变量即可: 2.nor fash芯片的 基地址出错. ...

  7. Day2-Python基础2---字符编码与转码

    详细内容http://www.cnblogs.com/yuanchenqi/articles/5956943.html 一.编码介绍: 1.基本概念: 在python 2中默认编码是 ASCII,而在 ...

  8. 浅析TCP /UDP/ IP协议

    互连网早期的时候,主机间的互连使用的是NCP协议.这种协议本身有很多缺陷,如:不能互连不同的主机,不能互连不同的操作系统,没有纠错功能.为了改善这种缺点,大牛弄出了TCP/IP协议.现在几乎所有的操作 ...

  9. HDU 2544 最短路(邻接表+优先队列+dijstra优化模版)

    最短路 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  10. Set,Sorted Set相关命令操作,批量插入及管道,事务

    Set SADD key member [member ...] 向key指定的set集合添加成员,次集合是排重的,从2.4版本后才支持添加多个如果key不存在则创建key以及set集合返回当前操作成 ...