快捷搜索:
来自 计算机编程 2019-08-24 18:07 的文章
当前位置: 67677新澳门手机版 > 计算机编程 > 正文

67677新澳门手机版Framework实现方式,使用WinApi操作

接下去是新的觉察

在探讨MSDN下边关于剪切板的API的时候,开掘了叁个函数

bool AddClipboardFormatListener(HWND hwnd);

依靠描述来说,是加上二个剪切板的监察和控制,在剪切板有任何更改的时候,通告你所内定的句柄的窗口,笔者一想,那不就是自己所急需的么,有了那样贰个API未来,其实笔者上边所显示的,使用死循环轮询剪切板的措施就变得很傻逼,並且也很轻便失误了,于是,基于这么些新意识的API,笔者重新改动了上上下下的程序逻辑,反而比原本的完毕特别简明了。

率先我们供给四个新的窗口依然控件来接过Windows音信更新后所发来的音信,只要New 贰个form就行

        public Form2()
        {
            InitializeComponent();
            AddClipboardFormatListener(this.Handle);
        }

然后我们在初叶化组件的一声令下后边,把利用加多剪切板监听的API把当下窗口的句柄发给系统,那样系统在吸纳到剪切板退换的通令后,会把音信发给当前窗口

下一场大家须要复写WndProc方法

   protected override void WndProc(ref Message m)
        {
            if (m.Msg == 0x031D && Onice)
            {var Temp = ClipboardControl.GetText(ClipboardFormat.CF_UNICODETEXT);
                    if (!string.IsNullOrEmpty(Temp))
                    {
                        ClipboardControl.SetText(Temp);
                        Onice = false;
                    }
            }
            else if (!Onice)
            {
                Onice = true;
            }
            else
            {
                base.WndProc(ref m);
            }
        }
   private bool Onice = true;

先是WndProc假诺是Form类上边三个特意用来抽出系统一发布送过来的音讯的议程

接下来关于m.Msg == 0x031D的0x031D在WinAPI定义上的含义是WM_CLIPBOA奥迪Q3DUPDATE ,也正是剪切板更新事件,那几个通过搜寻MSDN能够找到

上边未有特意意外的函数,就是有少数亟需小心,大家这里设置了剪切板数据,也等于进行了二遍立异,所以会在这一转眼重新爆发剪切板更新事件,然后又会通报那几个格局,然后就能产生死循环,作者在此间用了叁个布尔判定来经过布尔状态调节是还是不是截取剪切板,不仅独有未有越来越好的措施来贯彻

以上

 

以下是本文

想着,既然作者能用C 调用WinAPI完美兑现自个儿索要的效果,並且C#也能调用非托管的代码来进行WinAPI,那么笔者不是能够把上边C 写的代码移植到C#内部实施?说干就干

首先,C#调用WinAPI要求先表达

        [DllImport("User32")]
        internal static extern bool OpenClipboard(IntPtr hWndNewOwner);

        [DllImport("User32")]
        internal static extern bool CloseClipboard();

        [DllImport("User32")]
        internal static extern bool EmptyClipboard();

        [DllImport("User32")]
        internal static extern bool IsClipboardFormatAvailable(int format);

        [DllImport("User32")]
        internal static extern IntPtr GetClipboardData(int uFormat);

        [DllImport("User32", CharSet = CharSet.Unicode)]
        internal static extern IntPtr SetClipboardData(int uFormat, IntPtr hMem);

操作剪切板须求调用的API大致就地点那个

有了API未来,我们还索要团结手动封装方法

     internal static void SetText(string text)
        {
            if (!OpenClipboard(IntPtr.Zero))
        {
        SetText(text);
        return;
        }
            EmptyClipboard();
            SetClipboardData(13, Marshal.StringToHGlobalUni(text));
            CloseClipboard();
        }

        internal static string GetText(int format)
        {
            string value = string.Empty;
            OpenClipboard(IntPtr.Zero);
            if (IsClipboardFormatAvailable(format))
            {
                IntPtr ptr = NativeMethods.GetClipboardData(format);
                if (ptr != IntPtr.Zero)
                {
                    value = Marshal.PtrToStringUni(ptr);
                }
            }
            CloseClipboard();
            return value;
        }

我们也就用到多个点子,从剪切板获得文本和装置文本到剪切板,哦关于SetClipboardData的第一个参数13是怎么来的主题素材,其实这一个剪切板的格式参数,下边有一张表,正是自从这里来的

67677新澳门手机版 167677新澳门手机版 2

public static class ClipboardFormat
{
    /// <summary>
    /// Text format. Each line ends with a carriage return/linefeed (CR-LF) combination. A null character signals
    /// the end of the data. Use this format for ANSI text.
    /// </summary>
    public const int CF_TEXT = 1;

    /// <summary>
    /// A handle to a bitmap (<c>HBITMAP</c>).
    /// </summary>
    public const int CF_BITMAP = 2;

    /// <summary>
    /// Handle to a metafile picture format as defined by the <c>METAFILEPICT</c> structure. When passing a
    /// <c>CF_METAFILEPICT</c> handle by means of DDE, the application responsible for deleting <c>hMem</c> should
    /// also free the metafile referred to by the <c>CF_METAFILEPICT</c> handle.
    /// </summary>
    public const int CF_METAFILEPICT = 3;

    /// <summary>
    /// Microsoft Symbolic Link (SYLK) format.
    /// </summary>
    public const int CF_SYLK = 4;

    /// <summary>
    /// Software Arts' Data Interchange Format.
    /// </summary>
    public const int CF_DIF = 5;

    /// <summary>
    /// Tagged-image file format.
    /// </summary>
    public const int CF_TIFF = 6;

    /// <summary>
    /// Text format containing characters in the OEM character set. Each line ends with a carriage return/linefeed
    /// (CR-LF) combination. A null character signals the end of the data.
    /// </summary>
    public const int CF_OEMTEXT = 7;

    /// <summary>
    /// A memory object containing a <c>BITMAPINFO</c> structure followed by the bitmap bits.
    /// </summary>
    public const int CF_DIB = 8;

    /// <summary>
    /// Handle to a color palette. Whenever an application places data in the clipboard that depends on or assumes
    /// a color palette, it should place the palette on the clipboard as well. If the clipboard contains data in
    /// the <see cref="CF_PALETTE"/> (logical color palette) format, the application should use the
    /// <c>SelectPalette</c> and <c>RealizePalette</c> functions to realize (compare) any other data in the
    /// clipboard against that logical palette. When displaying clipboard data, the clipboard always uses as its
    /// current palette any object on the clipboard that is in the <c>CF_PALETTE</c> format.
    /// </summary>
    public const int CF_PALETTE = 9;

    /// <summary>
    /// Data for the pen extensions to the Microsoft Windows for Pen Computing.
    /// </summary>
    public const int CF_PENDATA = 10;

    /// <summary>
    /// Represents audio data more complex than can be represented in a CF_WAVE standard wave format.
    /// </summary>
    public const int CF_RIFF = 11;

    /// <summary>
    /// Represents audio data in one of the standard wave formats, such as 11 kHz or 22 kHz PCM.
    /// </summary>
    public const int CF_WAVE = 12;

    /// <summary>
    /// Unicode text format. Each line ends with a carriage return/linefeed (CR-LF) combination. A null character
    /// signals the end of the data.
    /// </summary>
    public const int CF_UNICODETEXT = 13;

    /// <summary>
    /// A handle to an enhanced metafile (<c>HENHMETAFILE</c>).
    /// </summary>
    public const int CF_ENHMETAFILE = 14;

    /// <summary>
    /// A handle to type <c>HDROP</c> that identifies a list of files. An application can retrieve information
    /// about the files by passing the handle to the <c>DragQueryFile</c> function.
    /// </summary>
    public const int CF_HDROP = 15;

    /// <summary>
    /// The data is a handle to the locale identifier associated with text in the clipboard. When you close the
    /// clipboard, if it contains <c>CF_TEXT</c> data but no <c>CF_LOCALE</c> data, the system automatically sets
    /// the <c>CF_LOCALE</c> format to the current input language. You can use the <c>CF_LOCALE</c> format to
    /// associate a different locale with the clipboard text.
    /// An application that pastes text from the clipboard can retrieve this format to determine which character
    /// set was used to generate the text.
    /// Note that the clipboard does not support plain text in multiple character sets. To achieve this, use a
    /// formatted text data type such as RTF instead. 
    /// The system uses the code page associated with <c>CF_LOCALE</c> to implicitly convert from
    /// <see cref="CF_TEXT"/> to <see cref="CF_UNICODETEXT"/>. Therefore, the correct code page table is used for
    /// the conversion.
    /// </summary>
    public const int CF_LOCALE = 16;

    /// <summary>
    /// A memory object containing a <c>BITMAPV5HEADER</c> structure followed by the bitmap color space
    /// information and the bitmap bits.
    /// </summary>
    public const int CF_DIBV5 = 17;

    /// <summary>
    /// Owner-display format. The clipboard owner must display and update the clipboard viewer window, and receive
    /// the <see cref="ClipboardMessages.WM_ASKCBFORMATNAME"/>, <see cref="ClipboardMessages.WM_HSCROLLCLIPBOARD"/>,
    /// <see cref="ClipboardMessages.WM_PAINTCLIPBOARD"/>, <see cref="ClipboardMessages.WM_SIZECLIPBOARD"/>, and
    /// <see cref="ClipboardMessages.WM_VSCROLLCLIPBOARD"/> messages. The <c>hMem</c> parameter must be <c>null</c>.
    /// </summary>
    public const int CF_OWNERDISPLAY = 0x0080;

    /// <summary>
    /// Text display format associated with a private format. The <c>hMem</c> parameter must be a handle to data
    /// that can be displayed in text format in lieu of the privately formatted data.
    /// </summary>
    public const int CF_DSPTEXT = 0x0081;

    /// <summary>
    /// Bitmap display format associated with a private format. The <c>hMem</c> parameter must be a handle to
    /// data that can be displayed in bitmap format in lieu of the privately formatted data.
    /// </summary>
    public const int CF_DSPBITMAP = 0x0082;

    /// <summary>
    /// Metafile-picture display format associated with a private format. The <c>hMem</c> parameter must be a
    /// handle to data that can be displayed in metafile-picture format in lieu of the privately formatted data.
    /// </summary>
    public const int CF_DSPMETAFILEPICT = 0x0083;

    /// <summary>
    /// Enhanced metafile display format associated with a private format. The <c>hMem</c> parameter must be a
    /// handle to data that can be displayed in enhanced metafile format in lieu of the privately formatted data.
    /// </summary>
    public const int CF_DSPENHMETAFILE = 0x008E;

    /// <summary>
    /// Start of a range of integer values for application-defined GDI object clipboard formats. The end of the
    /// range is <see cref="CF_GDIOBJLAST"/>. Handles associated with clipboard formats in this range are not
    /// automatically deleted using the <c>GlobalFree</c> function when the clipboard is emptied. Also, when using
    /// values in this range, the <c>hMem</c> parameter is not a handle to a GDI object, but is a handle allocated
    /// by the <c>GlobalAlloc</c> function with the <c>GMEM_MOVEABLE</c> flag.
    /// </summary>
    public const int CF_GDIOBJFIRST = 0x0300;

    /// <summary>
    /// See <see cref="CF_GDIOBJFIRST"/>.
    /// </summary>
    public const int CF_GDIOBJLAST = 0x03FF;

    /// <summary>
    /// Start of a range of integer values for private clipboard formats. The range ends with
    /// <see cref="CF_PRIVATELAST"/>. Handles associated with private clipboard formats are not freed
    /// automatically; the clipboard owner must free such handles, typically in response to the
    /// <see cref="ClipboardMessages.WM_DESTROYCLIPBOARD"/> message.
    /// </summary>
    public const int CF_PRIVATEFIRST = 0x0200;

    /// <summary>
    /// See <see cref="CF_PRIVATEFIRST"/>.
    /// </summary>
    public const int CF_PRIVATELAST = 0x02FF;
}

View Code

在C 里面是绝不钦赐数字的,只必要用CF_UNICODETEXT就行,然而.Net里面应该未有对号入座的索引表,所以只可以手动输入(作者那边是为了证实用才专门用数字,本人代码那是索引的枚举类)

上面多个专业做完之后,就能够兑现效果与利益了,作用代码如下

                   var LastS = string.Empty;
                   while (!CancelInfoClipboard.IsCancellationRequested)
                   {
                       var Temp = ClipboardControl.GetText(ClipboardFormat.CF_UNICODETEXT);
                       if (!string.IsNullOrEmpty(Temp) && Temp != LastS)
                       {
                           ClipboardControl.SetText(Temp);
                           LastS = Temp;
                       }
                       Thread.Sleep(50);
                   }

是还是不是和最先始呈现的调用.Net框架的方法一致(笑),不过使用底层API达成的法力,就从未有过那么多杂乱无章的Bug了,自身也很明亮到底达成了吗作用,同有的时候间也获得了成都百货上千新知识(主倘使非托管代码调用的时候的注意事项什么的,还会有,向非托管代码传递数据的时候,最广大用马尔斯hal类里面包车型地铁章程,不然大概会出错,究竟那个类正是专程为非托管代码而设立的)

下一场大家用浏览器查看下cookie有何样变化~

前言:

近年来刚刚写三个程序,必要操作剪切板

功用很轻松,只需求从剪切板内读取字符串,然后清空剪切板,然后再把字符串导入剪切板

我想当然的采取自身最拿手的C#来成功那项工作,原因无他,因为.Net框架封装了能促成这种效果的秘技

接下来就有了如下代码

67677新澳门手机版 367677新澳门手机版 4

 1             string Temp = "";
 2             while (true)
 3             {
 4                 string Tex = Clipboard.GetText().ToString();
 5                 if (!string.IsNullOrWhiteSpace(Tex) && Temp != Tex)
 6                 {
 7                     Clipboard.Clear();
 8                     Clipboard.SetDataObject(Tex, false);
 9                     Temp = Tex;
10                 }
11                 Thread.Sleep(1);
12             }

View Code

这段代码,也是网页上普及流传的,使用.Net框架操作系统剪切板的方法,当然那个格局在有些境况下很得力

可是在自个儿那确爆发了点难题,首要的难题有两点

第一,小编对剪切板的操作要求有实时性,也正是,操作职员复制的一刹这就应该截取到剪切板的数量,管理完后再放入剪切板

结果

 Clipboard.SetDataObject(Tex, false);

没悟出上边那条设置剪切板的吩咐竟然会卡核心窗口的线程,举个例子说,笔者在A软件施行了一遍复制操作,假若应用了上述代码,那么A软件强制线程堵塞大约几百飞秒的楷模,反正很影响体验,小编想见是因为该命令会锁定内部存储器导致的

那如何是好,本着死马当活马医的姿态,笔者特意为该指令启用了八个线程

       Task.Factory.StartNew(()=> 
                    {
                        Clipboard.Clear();
                        Clipboard.SetDataObject(Text, false);
                    });

运用了线程以往,因为操作滞后(线程运维会延迟一会儿,并不实时)了,所以上述难点就好像减轻了,不过没悟出现身了新的主题素材

 string Tex = Clipboard.GetText().ToString();

上述从剪切板获得字符串的吩咐,在默写情形下,会卡滞住,然后程序在一分钟过后,因为超时而被系统注销

emmmmm,在经过几番努力以往,笔者好不轻松开采到,即使.Net封装了多数操作系统API的法子,使得部分IO操作变轻便十分多,可是带来的标题也是一致大的,在遇见不能缓慢解决的主题素材的时候,会有个别力不能及

于是乎无语,作者只可以抛弃选拔过C#成功该项效用,想着辛亏功效简单,并且操作WinAPI其实最棒的要么采用C 来写,于是我用C 复现了上述意义

67677新澳门手机版 567677新澳门手机版 6

 1 #include "stdafx.h"
 2 #include <windows.h>
 3 #include <iostream>
 4 using namespace std;
 5 #pragma comment(linker,"/subsystem:windows /entry:mainCRTStartup")
 6 
 7 int main(int argc, _TCHAR* argv[])
 8 {
 9     HANDLE THandle = GlobalAlloc(GMEM_FIXED, 1000);//分配内存
10     char* Temp = (char*)THandle;//锁定内存,返回申请内存的首地址
11     while (true)
12     {
13         HWND hWnd = NULL;
14         OpenClipboard(hWnd);//打开剪切板
15         if (IsClipboardFormatAvailable(CF_TEXT))
16         {
17             HANDLE h = GetClipboardData(CF_TEXT);//获取剪切板数据
18             char* p = (char*)GlobalLock(h);
19             GlobalUnlock(h);
20             if (strcmp(Temp, p))
21             {
22                 EmptyClipboard();//清空剪切板
23                 HANDLE hHandle = GlobalAlloc(GMEM_FIXED, 1000);//分配内存
24                 char* pData = (char*)GlobalLock(hHandle);//锁定内存,返回申请内存的首地址
25                 strcpy(pData, p);
26                 strcpy(Temp, p);
27                 SetClipboardData(CF_TEXT, hHandle);//设置剪切板数据
28                 GlobalUnlock(hHandle);//解除锁定
29             }
30         }
31         CloseClipboard();//关闭剪切板
32         Sleep(500);
33     }
34     return 0;
35 }

View Code

名符其实是C ,使用上述代码后,完美兑现自身急需的效果与利益,何况不管是主程序,照旧自个儿写的这些程序,都不会产出卡滞只怕不干活的情形了,真是可喜可贺。

那么本学科就到此甘休。

 

 

 

View Code

 

好啊,整个Identity认证不重视EF已经达成了,多少个核心点正是急需贯彻IUser接口以及各样Store。。然后将达成各类Store的类注入到UserManager构造函数里

第三部、建模

Microsoft.AspNet.Identity.Core      MSDN评释:包涵与处理 ASP.NET Identity 的客商和剧中人物相关的类和接口。

 1         [AllowAnonymous]
 2         public ActionResult Login()
 3         {
 4             return View();
 5         }
 6 
 7 
 8         [HttpPost]
 9         [AllowAnonymous]
10         public async Task<ActionResult> Login(BASE_USER user)
11         {
12             if (string.IsNullOrEmpty(user.UserName)) { return View(); }
13             if (string.IsNullOrEmpty(user.PWD)) { return View(); }
14             //Context
15             Microsoft.Owin.IOwinContext OwinContext = HttpContext.GetOwinContext();
16             //实例化UserStore对象
17             HsUserStore userStore = new HsUserStore();
18             //UserManager
19             HsUserManager userManager = new HsUserManager(userStore);
20             //授权对象
21             IAuthenticationManager autherticationManager = OwinContext.Authentication;
22             //登录管理对象
23             HsSignInManager signManager = new HsSignInManager(userManager, autherticationManager);
24 
25             //登录
26             Microsoft.AspNet.Identity.Owin.SignInStatus SignInStatus = Microsoft.AspNet.Identity.Owin.SignInStatus.Failure;
27             try
28             {
29                 SignInStatus = await signManager.PasswordSignInAsync(user.UserName,
30                                                                      user.PWD,
31                                                                      true,
32                                                                      shouldLockout: false);
33              
34             }catch(Exception ea)
35             {
36                  
37             }
38             //登录状态
39             switch (SignInStatus)
40             {
41                 //成功 同一个Control里跳转直接使用RecirectToAction(ActionName) 
42                 case Microsoft.AspNet.Identity.Owin.SignInStatus.Success:                
43                     //不同控制器使用RedirectToAction
44                     return RedirectToAction("Index", "Home"); //可以直接跳到别的Controller.                
45                 //锁定
46                 case Microsoft.AspNet.Identity.Owin.SignInStatus.LockedOut:
47                     Response.Write("账户被锁定啦~~~!");
48                     break;
49                 //失败
50                 case Microsoft.AspNet.Identity.Owin.SignInStatus.Failure:
51                     Response.Write("登录失败啦~~~!");
52                     break;
53                 //要求验证
54                 case Microsoft.AspNet.Identity.Owin.SignInStatus.RequiresVerification:
55                     Response.Write("需要验证!");
56                     break;
57 
58             }
59             return View();
60         }

 

Asp.Net.Identity为啥物请自行检索,也可转化此文章

第五步承袭UserManager类

 

  

 

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 using IdeintityDemo.Models;
 6 using Microsoft.AspNet.Identity;
 7 using Microsoft.AspNet.Identity.Owin;
 8 using Microsoft.Owin;
 9 using System.Threading.Tasks;
10 using Microsoft.Owin.Security;
11 
12 namespace IdeintityDemo.Identity
13 {
14     /// <summary>
15     /// 登录管理,此处用到了UserManager
16     /// </summary>
17     public class HsSignInManager : SignInManager<BASE_USER, Guid>
18     {
19 
20         /// <summary>
21         /// 构造函数
22         /// </summary>
23         /// <param name="UserManager"></param>
24         /// <param name="AuthenticationManager"></param>
25         public HsSignInManager(Microsoft.AspNet.Identity.UserManager<BASE_USER, Guid> UserManager, Microsoft.Owin.Security.IAuthenticationManager AuthenticationManager)
26             : base(UserManager, AuthenticationManager)
27         {
28 
29         }
30 
31         /// <summary>
32         /// 根据用户名密码,验证用户登录
33         /// </summary>
34         /// <param name="userName"></param>
35         /// <param name="password"></param>
36         /// <param name="isPersistent"></param>
37         /// <param name="shouldLockout"></param>
38         /// <returns></returns>
39         public override System.Threading.Tasks.Task<Microsoft.AspNet.Identity.Owin.SignInStatus> PasswordSignInAsync(string userName,
40                                                                                                                      string password,
41                                                                                                                      bool isPersistent,
42                                                                                                                      bool shouldLockout)
43         {
44             /*这里可以直接通过PasswordSignInAsync来校验,也可以重写~ */
45             //这里用Find方法会返回空的user。。。搞不懂。。
46             var user = base.UserManager.FindByName<BASE_USER, Guid>(userName);
47             if (user == null || user.Id == Guid.Empty)
48                 return Task.FromResult<SignInStatus>(SignInStatus.Failure);
49             else if (user.PWD != password)
50                 return Task.FromResult<SignInStatus>(SignInStatus.Failure);
51             else
52             {
53                 /*这个时候如果不写入到cooks里,在Home控制器的Index action里会被系统的
54                     Authorize刷选器拦截*/
55                 // 利用ASP.NET Identity获取identity 对象
56                 var identity = base.UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
57                 // 将上面拿到的identity对象登录
58                 base.AuthenticationManager.SignIn(new AuthenticationProperties()
59                 { IsPersistent = true }, identity.Result);
60                 return Task.FromResult<SignInStatus>(SignInStatus.Success);
61             }
62             /*这里如果你想直接使用微软的登入方法也可以,直接base.就ok啦*/
63             //return base.PasswordSignInAsync(userName,
64             //                                password,
65             //                                isPersistent,
66             //                                shouldLockout);
67         }
68 
69 
70     }
71 }

 

等一时光再落到实处下Identity命名空间下的剧中人物处理这一块啊。。。不得不说微软的接口真是封装的好啊~

 

 F5运作试下

可以说大家封装的行事早已成功了,封装了七个类

 

 

 

 

 现在我们看Controller里的代码是怎么写的吗~

67677新澳门手机版 7

 

View Code

 

Microsoft.Owin.Security.OAuth      MSDN评释:包括与 OAuth 提供程序相关的花色。(详细消息参谋 )

我们在工程站点的Models文件夹里新建一个BASE_USECRUISER类,让它继续Microsoft.AspNet.Identity.IUser<GUID>,这里我们加贰个数据表不设有的NICKNAME别称字段,到末端看看会有何样效果~

 1  /// <summary>
 2         /// 注册
 3         /// </summary>
 4         /// <returns></returns>
 5         [HttpPost]
 6         [AllowAnonymous]
 7         public async Task<ActionResult> Register(BASE_USER user)
 8         { 
 9             Microsoft.Owin.IOwinContext OwinContext = HttpContext.GetOwinContext();
10             //用户储存
11             HsUserStore userStore = new HsUserStore();
12             //UserManager
13             HsUserManager UserManager = new HsUserManager(userStore);
14             IdentityResult result = await UserManager.CreateAsync(user);
15             if (result.Succeeded)
16             {
17                 Response.Write("注册成功!");
18                 return RedirectToAction("index", "home");
19             }
20             return View();
21         }
22 
23         [AllowAnonymous]
24         public ActionResult Register()
25         {
26             return View();
27         }

 

 

地点最重视的办法便是PasswordSignInAsync,那个措施就是登录方法。

第二部、Nuget上安装Microsoft.AspNet.Identity、Microsoft.AspNet.Identity.Owin

 

从MSDN的笺注能够看出来Microsoft.AspNet.Identity.Owin里其实便是将网址的登陆、注册业务场景所需的API实行了包装;

 

  1 using Microsoft.AspNet.Identity;
  2 using System;
  3 using System.Collections.Generic;
  4 using System.Data;
  5 using System.Data.SqlClient;
  6 using System.Linq;
  7 using System.Threading.Tasks;
  8 using System.Web;
  9 using System.Security.Claims;
 10 using IdeintityDemo.Models;
 11 using IdeintityDemo.Common;
 12 
 13 namespace IdeintityDemo.Identity
 14 {
 15 
 16     /// <summary>
 17     /// 用户持久化存储对象
 18     /// 必须实现Microsoft.AspNet.Identity相应接口,否则在SignInManager类进行登录校验过程中
 19     /// 会弹出未实现相关接口的异常!   
 20     /// IUserStore:检测是否存在账户
 21     /// IUserPasswordStore:校验密码
 22     /// IUserLockoutStore:锁定账户相关操作
 23     /// IUserClaimStore:存储用户特定的声明
 24     /// IUserEmailStore:邮箱关联、验证等相关操作
 25     /// IUserPhoneNumberStore:手机关联、验证相关操作
 26     /// IUserTwoFactorStore:获取或设置用户双重身份验证的方法。
 27     /// </summary>
 28     public class HsUserStore : Microsoft.AspNet.Identity.IUserStore<BASE_USER, Guid>,
 29                                Microsoft.AspNet.Identity.IUserPasswordStore<BASE_USER, Guid>,
 30                                Microsoft.AspNet.Identity.IUserLockoutStore<BASE_USER, Guid>,
 31                                Microsoft.AspNet.Identity.IUserClaimStore<BASE_USER, Guid>,
 32                                Microsoft.AspNet.Identity.IUserEmailStore<BASE_USER, Guid>,
 33                                Microsoft.AspNet.Identity.IUserPhoneNumberStore<BASE_USER, Guid>,
 34                                Microsoft.AspNet.Identity.IUserTwoFactorStore<BASE_USER, Guid>
 35     {
 36 
 37         /// <summary>
 38         /// 声明
 39         /// </summary>
 40         public IList<System.Security.Claims.Claim> Claims = null;
 41         /// <summary>
 42         /// 用户
 43         /// </summary>
 44         public BASE_USER UserIdentity = null;
 45 
 46         /// <summary>
 47         /// 实例化
 48         /// </summary>
 49         public HsUserStore()
 50         {
 51             //声明
 52             Claims = new List<System.Security.Claims.Claim>();
 53         }
 54         /// <summary>
 55         /// 创建用户
 56         /// </summary>
 57         /// <param name="user"></param>
 58         /// <returns></returns>
 59         public Task CreateAsync(BASE_USER user)
 60         {
 61             return Task.Run(() => {
 62                 string sql = @"INSERT INTO [dbo].[BASE_USER]([ID],[NAME],[PWD])
 63                         VALUES(@UserID,@name,@pwd)";
 64                 SqlParameter[] parameters = {
 65                      new SqlParameter("@UserID", Guid.NewGuid()),
 66                      new SqlParameter("@name", user.UserName),
 67                      new SqlParameter("@pwd", user.PWD)
 68                 };
 69                 int iResult = DbHelperSQL.ExecuteSql(sql, parameters);
 70             });
 71         }
 72         /// <summary>
 73         /// 删除用户
 74         /// </summary>
 75         /// <param name="user"></param>
 76         /// <returns></returns>
 77         public Task DeleteAsync(BASE_USER user)
 78         {
 79             return Task.Run(() => {
 80                 string sql = @"DELETE FROM [dbo].[BASE_USER] WHERE ID=@ID";
 81                 SqlParameter[] parameters = {
 82                      new SqlParameter("@UserID", user.Id)};
 83                 int iResult = DbHelperSQL.ExecuteSql(sql, parameters);
 84             });
 85         }
 86         /// <summary>
 87         /// 根据用户id获取用户
 88         /// </summary>
 89         /// <param name="userId"></param>
 90         /// <returns></returns>
 91         public Task<BASE_USER> FindByIdAsync(Guid userId)
 92         {
 93             return Task<BASE_USER>.Run(() =>
 94              {
 95                  BASE_USER result = new BASE_USER();
 96                  string sql = @"SELECT * FROM [dbo].[BASE_USER] WHERE ID=@ID";
 97                  SqlParameter[] parameters = {
 98                      new SqlParameter("@ID", userId)};
 99                  DataSet ds = DbHelperSQL.Query(sql, parameters);
100                  if (ds == null || ds.Tables == null || ds.Tables[0].Rows.Count <= 0)
101                      return result;
102                  //model
103                  DataRow dr = ds.Tables[0].Rows[0];
104                  result.Id = Guid.Parse(dr["ID"].ToString());
105                  result.UserName = dr["NAME"].ToString();
106                  result.PWD = dr["PWD"].ToString();
107                  return result;
108              });
109         }
110         /// <summary>
111         /// 根据名称获取用户信息
112         /// </summary>
113         /// <param name="userName"></param>
114         /// <returns></returns>
115         public Task<BASE_USER> FindByNameAsync(string userName)
116         {
117             return Task<BASE_USER>.Run(() =>
118             {
119                 BASE_USER result = new BASE_USER();
120                 string sql = @"SELECT * FROM [dbo].[BASE_USER] WHERE NAME=@NAME";
121                 SqlParameter[] parameters = {
122                      new SqlParameter("@NAME", userName)};
123                 DataSet ds = DbHelperSQL.Query(sql, parameters);
124                 if (ds == null || ds.Tables == null || ds.Tables[0].Rows.Count <= 0)
125                     return result;
126                 //model
127                 DataRow dr = ds.Tables[0].Rows[0];
128                 result.Id = Guid.Parse(dr["ID"].ToString());
129                 result.UserName = dr["NAME"].ToString();
130                 result.PWD = dr["PWD"].ToString();
131 
132                 return result;
133             });
134         }
135         /// <summary>
136         /// 更新用户
137         /// </summary>
138         /// <param name="user"></param>
139         /// <returns></returns>
140         public Task UpdateAsync(BASE_USER user)
141         {
142             return Task.Run(() =>
143             {
144                 //省略...
145             });
146         }
147         /// <summary>
148         /// 异步返回当前失败的访问尝试次数。当密码被验证或帐户被锁定时,这个数字通常会被重置。
149         /// (这里因为我数据库里没有去做这一块的记录保存,所以先写死返回1)
150         /// </summary>
151         /// <param name="user">用户</param>
152         /// <returns></returns>
153         public Task<int> GetAccessFailedCountAsync(BASE_USER user)
154         {
155             return Task.FromResult<int>(1);
156         }
157         /// <summary>
158         /// 获取锁定状态
159         /// </summary>
160         /// <param name="user"></param>
161         /// <returns></returns>
162         public Task<bool> GetLockoutEnabledAsync(BASE_USER user)
163         {
164             return Task.FromResult<bool>(false);
165         }
166         /// <summary>
167         /// 获取锁定结束时间
168         /// </summary>
169         /// <param name="user"></param>
170         /// <returns></returns>
171         public Task<DateTimeOffset> GetLockoutEndDateAsync(BASE_USER user)
172         {
173             throw new NotImplementedException();
174         }
175         /// <summary>
176         /// 记录试图访问用户失败的记录。
177         /// </summary>
178         /// <param name="user"></param>
179         /// <returns></returns>
180         public Task<int> IncrementAccessFailedCountAsync(BASE_USER user)
181         {
182             return Task.FromResult<int>(1);
183         }
184         /// <summary>
185         /// 重置访问失败计数,通常在帐户成功访问之后
186         /// </summary>
187         /// <param name="user"></param>
188         /// <returns></returns>
189         public Task ResetAccessFailedCountAsync(BASE_USER user)
190         {
191             return Task.FromResult(false);
192         }
193         /// <summary>
194         /// 异步设置是否可以锁定用户。
195         /// </summary>
196         /// <param name="user"></param>
197         /// <param name="enabled"></param>
198         /// <returns></returns>
199         public Task SetLockoutEnabledAsync(BASE_USER user, bool enabled)
200         {
201             return Task.Run(() => { });
202         }
203         /// <summary>
204         /// 异步锁定用户直到指定的结束日期
205         /// </summary>
206         /// <param name="user"></param>
207         /// <param name="lockoutEnd"></param>
208         /// <returns></returns>
209         public Task SetLockoutEndDateAsync(BASE_USER user, DateTimeOffset lockoutEnd)
210         {
211             return Task.Run(() =>
212             {
213 
214             });
215         }
216         /// <summary>
217         /// 获取用户密码
218         /// </summary>
219         /// <param name="user"></param>
220         /// <returns></returns>
221         public Task<string> GetPasswordHashAsync(BASE_USER user)
222         {
223             return Task<string>.Run(() =>
224             {
225                 return user.PWD;
226             });
227         }
228         /// <summary>
229         /// 是否有密码
230         /// </summary>
231         /// <param name="user"></param>
232         /// <returns></returns>
233         public Task<bool> HasPasswordAsync(BASE_USER user)
234         {
235             return Task.FromResult<bool>(!string.IsNullOrEmpty(user.PWD));
236         }
237         /// <summary>
238         /// 密码进行加密
239         /// </summary>
240         /// <param name="user"></param>
241         /// <param name="passwordHash"></param>
242         /// <returns></returns>
243         public Task SetPasswordHashAsync(BASE_USER user, string passwordHash)
244         {
245             return Task.Run(() =>
246             {
247                 user.PWD = passwordHash;//加密后
248             });
249         }
250         /// <summary>
251         /// 添加一个声明
252         /// </summary>
253         /// <param name="user"></param>
254         /// <param name="claim"></param>
255         /// <returns></returns>
256         public Task AddClaimAsync(BASE_USER user, Claim claim)
257         {
258             return Task.Run(() => { Claims.Add(claim); });
259         }
260         /// <summary>
261         /// 获取改用户的所有声明
262         /// </summary>
263         /// <param name="user"></param>
264         /// <returns></returns>
265         public Task<IList<Claim>> GetClaimsAsync(BASE_USER user)
266         {
267             return Task.Run<IList<System.Security.Claims.Claim>>(() =>
268             {
269                 IList<System.Security.Claims.Claim> list = new List<System.Security.Claims.Claim>();
270                 return list;
271             });
272         }
273         /// <summary>
274         /// 移除申明
275         /// </summary>
276         /// <param name="user"></param>
277         /// <param name="claim"></param>
278         /// <returns></returns>
279         public Task RemoveClaimAsync(BASE_USER user, Claim claim)
280         {
281             return Task.Run(() =>
282             {
283 
284             });
285         }
286         /// <summary>
287         /// 通过邮箱获取对应的用户信息
288         /// </summary>
289         /// <param name="email"></param>
290         /// <returns></returns>
291         public Task<BASE_USER> FindByEmailAsync(string email)
292         {
293             return Task<BASE_USER>.Run(() => new BASE_USER());
294         }
295         /// <summary>
296         /// 获取邮箱
297         /// </summary>
298         /// <param name="user"></param>
299         /// <returns></returns>
300         public Task<string> GetEmailAsync(BASE_USER user)
301         {
302             return Task<string>.Run(() => string.Empty);
303         }
304         /// <summary>
305         /// 确认邮箱
306         /// </summary>
307         /// <param name="user"></param>
308         /// <returns></returns>
309         public Task<bool> GetEmailConfirmedAsync(BASE_USER user)
310         {
311             return Task.FromResult<bool>(true);
312         }
313         /// <summary>
314         /// 修改邮箱
315         /// </summary>
316         /// <param name="user"></param>
317         /// <param name="email"></param>
318         /// <returns></returns>
319         public Task SetEmailAsync(BASE_USER user, string email)
320         {
321             return Task.Run(() => { });
322         }
323         /// <summary>
324         ///设置用户是否邮箱确认 
325         /// </summary>
326         /// <param name="user"></param>
327         /// <param name="confirmed"></param>
328         /// <returns></returns>
329         public Task SetEmailConfirmedAsync(BASE_USER user, bool confirmed)
330         {
331             throw new NotImplementedException();
332         }
333         /// <summary>
334         /// 获取联系电话
335         /// </summary>
336         /// <param name="user"></param>
337         /// <returns></returns>
338         public Task<string> GetPhoneNumberAsync(BASE_USER user)
339         {
340             return Task.FromResult<string>(string.Empty);
341         }
342         /// <summary>
343         /// 获取用户电话号码是否已确认
344         /// </summary>
345         /// <param name="user"></param>
346         /// <returns></returns>
347         public Task<bool> GetPhoneNumberConfirmedAsync(BASE_USER user)
348         {
349             return Task.FromResult<bool>(true);
350         }
351         /// <summary>
352         /// 设置用户电话号码
353         /// </summary>
354         /// <param name="user"></param>
355         /// <param name="phoneNumber"></param>
356         /// <returns></returns>
357         public Task SetPhoneNumberAsync(BASE_USER user, string phoneNumber)
358         {
359             return Task.Run(() => { });
360         }
361         /// <summary>
362         /// 设置与用户关联的电话号码
363         /// </summary>
364         /// <param name="user"></param>
365         /// <param name="confirmed"></param>
366         /// <returns></returns>
367         public Task SetPhoneNumberConfirmedAsync(BASE_USER user, bool confirmed)
368         {
369             return Task.Run(() => { });
370         }
371         /// <summary>
372         /// 是否为用户启用了双重身份验证。
373         /// </summary>
374         /// <param name="user"></param>
375         /// <returns></returns>
376         public Task<bool> GetTwoFactorEnabledAsync(BASE_USER user)
377         {
378             return Task.FromResult<bool>(false);
379         }
380         /// <summary>
381         /// 设置双重身份验证
382         /// </summary>
383         /// <param name="user"></param>
384         /// <param name="enabled"></param>
385         /// <returns></returns>
386         public Task SetTwoFactorEnabledAsync(BASE_USER user, bool enabled)
387         {
388             throw new NotImplementedException();
389         }
390         /// <summary>
391         /// 释放
392         /// </summary>
393         public void Dispose()
394         {
395             throw new NotImplementedException();
396         }
397 
398     }
399 }

 SignInManager类是Microsoft.AspNet.Identity.Owin命名空间下的,集成了顾客登陆实行管理的相干API,是Asp.Net.Identity里不可缺少的管理类

67677新澳门手机版 8

View Code

 

View Code

67677新澳门手机版 9

 

 

 运转发掘浏览器直接跳转到了登入页面。。

本文由67677新澳门手机版发布于计算机编程,转载请注明出处:67677新澳门手机版Framework实现方式,使用WinApi操作

关键词: