写在2018年度高考

中考、高考、考研、考公务员,这应该算是中国的“四大考”了吧。“四大考”之一的高考马上就要到了,距我第一次参加高考已经过去了整整15年,我一共参加过两次高考。
2003年那年,是我第一次参加高考,而那一年也正值非典,全国上下,无论农村还是城市,对非典的防范都是非常严的。当时我住校,每个星期回家一次,正常情况下每天中午和晚上放学时间都可以出校门,而非典期间我们连续一个月都没出去过,几乎弹尽粮绝,而且一个多月没出过校门,可以想象一下是什么样的感觉,每天量2到3次体温,体温有点不正常就需要立马报告。好在高考前的大概一个月左右,趁周末,学校找来大巴车,把我们挨个送回了家住了两天,之后又把我们挨个接回来。
高考的时候,每个考生都需要量体温,红外线耳温枪,还是很快的。体温异常的单独一个考场,那个考场的监考老师全都是防护服和口罩,真替那个考场的老师和考生捏一把汗,需要强大的心理素质。
那年的高考题挺难的,可以查下当年的数学卷,非常有名,被称为“数学惨案”,大家基本上都差不多的惨不忍睹,当时还以为要与大学无缘了,但是估分下来,考个差不多的二本还是没问题的。但是因为每一次填志愿,没什么经验,而且当时我是那种从不去网吧的五好学生,也不知道可以上网上查学校的信息,志愿填的都是那些看上去不错而且上一年分数不高的学校专业,结果可想而知,自己认真填的学校没有一个愿意要我的,而最后那个保底的在同学那抄来的专科学校向我伸来了橄榄枝,问我去不去?我当然不去了,不然就没有第二次高考了。
经历过了之后,就打算复课去了。复课当然不能回原来的学校,太没面子了。就去了县城里的那个不是重点但是比普高要好一点的中不溜的不上不下的复课生都爱去的那个学校。我们复课的单独一个班,大概能有70多个学生吧,可以说是一个大班了。而在复课的这一年,我学会了上网,经常去网吧,甚至在高考的前一天晚上还上网。问我第二次高考考的怎么样?你见过几个网瘾严重的人学习好呢?不过也没想像中的那么差,比第一次高考能多个20多分吧,主要是题比第一年的要简单点。但是这次有经验了,志愿填的比第一次好,当然运气也是一部分,填的是一个离家非常远的一个二本学校,但是到学校的时候,直接就升到211了。
时间过的真快,一转眼15年过去了,再过15年,应该就是我陪孩子高考了。高考只是人生转折点之一,如果没有把握好这次机会,还有其他的机会可以选择。但是还是希望所有的考生不出意外,正常发挥就好。
最后,发几个老图来激励一下:

-598a8d9541573583.jpg
-2263447313bb7a97.jpg
798aa1dae5937a3d.jpg
39b99f4d8813267b.jpg
22c315076de31eb6.jpg
-5e5fdc61a67f11a4.jpg
-1777dcd77df601fa.jpg
610a75301ae872f.jpg
34283e97582fb86a.jpg

ASP.Net Core 2.0 在Linux下连接SQL Server数据库问题

在ASP.Net Core 2.0下,通过Dapper来使用SQL Server数据库,在Windows系统下完全正常,而部署到Linux服务器上会出现连不上数据库的情况,从日志里看,报下面的错误:

Connection Timeout Expired. The timeout period elapsed during the post-login phase. The connection could have timed out while waiting for server to complete the login process and respond; Or it could have timed out while attempting to create multiple active connections. The duration spent while attempting to connect to this server was - [Pre-Login] initialization=23; handshake=365; [Login] initialization=0; authentication=2; [Post-Login] complete=28022;

连接超时。开始的时候怀疑是防火墙的原因,检查了一下防火墙正常,而且通过telnet命令检查数据库的1433端口是通的,看来问题是出在.net core上。
通过百度和Google搜索相关的关键字,找到了一篇帖子:《Timeout Connecting to SQL Server instance from Linux》,说的是只有SQL Server 2008 及之前的版本会有这问题,SQL Server 2012及之后修复了这个问题。
检查了下自己的SQL数据库版本,是SQL Server 2008 R2 版的,正在此列。开了腾讯云的SQL Server云数据库连接测试,完全正常。

以上。

关于ASP.NET MVC中使用Forms验证的问题

表单验证(Forms验证)是一个基于票据(ticket-based)[也称为基于令牌(token-based)]的系统。这意味着当用户登录系统以后,他们得到一个包含基于用户信息的票据(ticket)。这些信息被存放在加密过的cookie里面,这些cookie和响应绑定在一起,因此每一次后续请求都会被自动提交到服务器。

当用户请求匿名用户无法访问的ASP.NET页面时,ASP.NET运行时验证这个表单验证票据是否有效。如果无效,ASP.NET自动将用户转到登录页面。这时就该由你来操作了。你必须创建这个登录页面并且验证由登录页面提交的凭证。如果用户验证成功,你只需要告诉ASP.NET架构验证成功(通过调用FormsAuthentication类的一个方法),运行库会自动设置验证cookie(实际上包含了票据)并将用户转到原先请求的页面。通过这个请求,运行库检测到验证cookie中包含一个有效票据,然后赋给用户对这个页面的访问权限。

下面,就是具体的实现。我们先写一个生成用户票据的方法:

//生成Token并保存到Cookies中
private void CreateToken(Models.User user)
{
    string json = JsonConvert.SerializeObject(user);
    FormsAuthentication.SetAuthCookie(user.UserName.Trim(), true, FormsAuthentication.FormsCookiePath);
    FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket(1, user.UserName, DateTime.Now, DateTime.Now.AddHours(12), false, json);
    Biz126.Cache.SetCookies.AddCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(Ticket));
}

其中Biz126.Cache.SetCookies.AddCookie是我自己封装的保存Cookie方法。
生成Token并保存到Cookie中的方法我们已经写好了,只要在登录成功之后直接调用这个方法就可以了。

下面是验证票据,验证票据,我们放在过滤器中进行验证。
新建AuthenticationAttribute类,继承ActionFilterAttribute,重写OnActionExecuting方法:

        /// <summary>
        /// 检查用户是否有该Action执行的操作权限
        /// </summary>
        /// <param name="actionContext"></param>
        public override void OnActionExecuting(HttpActionContext filterContext)
        {
            Models.ResultModel<object> result = new Models.ResultModel<object>();
            result.code = -401;
            result.message = "请登录后进行操作";
            result.status = false;
            //如果存在身份信息
            if (!HttpContext.Current.User.Identity.IsAuthenticated)
            {
                filterContext.Response = filterContext.Request.CreateResponse(HttpStatusCode.Unauthorized, result, "application/json");
            }
            else
            {                
                
                BLL.IManager manager = new BLL.Manage.Manager();
                result = manager.Detail();    //取当前登录的用户信息,进行其他的操作,比如判断有没有权限等,这里省略
                //。。。省略掉其他的操作
                
                if (!result.status)
                {
                    filterContext.Response = filterContext.Request.CreateResponse(HttpStatusCode.Unauthorized, result, "application/json");
                    //filterContext.Result = redirect;
                }
            }
        }

之后,在要在需要用户登录的Action上面,加上[Authentication]就可以了,也可以新加一个控制器,如BaseWebApiController,在这个控制器上加上[Authentication],其他的控制器都继承BaseWebApiController,在不需要验证的Action上加上[AllowAnonymous]就可以了。
下面是通过票据取得用户信息:

            if (HttpContext.Current.Request.IsAuthenticated)//是否通过身份验证
            {
                HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];//获取cookie
                FormsAuthenticationTicket Ticket = FormsAuthentication.Decrypt(authCookie.Value);//解密
                string json = Ticket.UserData;//反序列化
                Models.Models.User user = new Models.User();
                try
                {
                    user = JsonConvert.DeserializeObject<Models.User>(json);
                    result.data = user;
                    result.message = "success";
                    result.status = true;
                }
                catch
                {

                }

            }

还需要在web.config中增加配置:

  <system.web>
    <authentication mode="Forms">
      <forms loginUrl="~/Users/Login" timeout="2880" />
    </authentication>
  </system.web>

到这里,其本上都已经完成了,但是你会发现,在IE上,会有很多用户登录的时候验证不通过的情况,如果记录日志,会发现HttpContext.Current.Request.IsAuthenticated==false
HttpContext.Current.Request.User为空
而且这种情况只有在IE下才会出现,其他的现代浏览器比如Chrome、Firefox等都很正常。
通过网络搜索,大部分都没给出答案来。其他把配置按下面的方法修改,就可以解决这个问题:

  <system.web>
    <authentication mode="Forms">
      <forms cookieless="UseCookies" loginUrl="~/Users/Login" timeout="2880" />
    </authentication>
    <authorization>
      <allow users="*" />
    </authorization>
  </system.web>

或者是打开服务器的IIS,按下面的步骤修改:
IIS的“身份证验证”
1.打开IIS,选择自己的站点,之后双击IIS中的“身份验证”功能
设置Forms身份验证
2.选中Forms身份验证,点击右侧操作区的“编辑”菜单,如果没有启用请先点击“启用”
Forms身份验证的默认设置
3.这是Forms身份验证的默认设置,我们需要改动一下
修改之后的Forms身份验证设置
4.按这里修改一下,就可以了。

以上。

ASP.NET Core 2.0下使用log4net记录文件日志

我们知道log4net的日志功能非常强大,而使用方法也比较复杂;在ASP.NET Core 2.0下,可以通过一个第三方的扩展方法来降低我们的使用难度,具体使用方法如下:
我们先新建一个自己的静态类Log4Net,用于之后调用记录日志:

    public static class Log4Net
{
    private static readonly log4net.ILog log =
    log4net.LogManager.GetLogger(typeof(Log4Net));

    static void SetConfig()
    {
        XmlDocument log4netConfig = new XmlDocument();
        log4netConfig.Load(File.OpenRead("log4net.config"));

        var repo = log4net.LogManager.CreateRepository(
            Assembly.GetEntryAssembly(), typeof(log4net.Repository.Hierarchy.Hierarchy));

        log4net.Config.XmlConfigurator.Configure(repo, log4netConfig["log4net"]);
    }

    /// <summary>
    /// 信息
    /// </summary>
    /// <param name="Message"></param>
    public static void LogInfo(string Message)
    {
        if (!log.IsInfoEnabled)
            SetConfig();
        log.Info(Message);
    }

    /// <summary>
    /// 信息
    /// </summary>
    /// <param name="Message"></param>
    /// <param name="ex"></param>
    public static void LogInfo(string Message, Exception ex)
    {
        if (!log.IsInfoEnabled)
            SetConfig();
        log.Info(Message, ex);
    }

    /// <summary>
    /// 错误日志
    /// </summary>
    /// <param name="Message"></param>
    public static void ErrorInfo(string Message)
    {
        if (!log.IsErrorEnabled)
            SetConfig();
        log.Error(Message);
    }

    /// <summary>
    /// 错误日志
    /// </summary>
    /// <param name="Message"></param>
    /// <param name="ex"></param>
    public static void Error(Exception ex)
    {
        if (!log.IsInfoEnabled)
            SetConfig();
        log.Error("异常", ex);
    }

    /// <summary>
    /// 错误日志
    /// </summary>
    /// <param name="Message"></param>
    /// <param name="ex"></param>
    public static void ErrorInfo(string Message, Exception ex)
    {
        if (!log.IsErrorEnabled)
            SetConfig();
        log.Error(Message, ex);
    }

    /// <summary>
    /// Debug日志
    /// </summary>
    /// <param name="Message"></param>
    public static void DebugInfo(string Message)
    {
        if (!log.IsDebugEnabled)
            SetConfig();
        log.Debug(Message);
    }

    /// <summary>
    /// Debug日志
    /// </summary>
    /// <param name="Message"></param>
    /// <param name="ex"></param>
    public static void DebugInfo(string Message, Exception ex)
    {
        if (!log.IsDebugEnabled)
            SetConfig();
        log.Debug(Message, ex);
    }

    /// <summary>
    /// 警告
    /// </summary>
    /// <param name="Message"></param>
    public static void WarnInfo(string Message)
    {
        if (!log.IsWarnEnabled)
            SetConfig();
        log.Warn(Message);
    }

    /// <summary>
    /// 警告
    /// </summary>
    /// <param name="Message"></param>
    /// <param name="ex"></param>
    public static void WarnInfo(string Message,Exception ex)
    {
        if (!log.IsWarnEnabled)
            SetConfig();
        log.Warn(Message,ex);
        
    }

    /// <summary>
    /// 致命错误
    /// </summary>
    /// <param name="Message"></param>
    public static void FataInfo(string Message)
    {
        if (!log.IsFatalEnabled)
            SetConfig();
        log.Fatal(Message);
    }

    /// <summary>
    /// 致命错误
    /// </summary>
    /// <param name="Message"></param>
    /// <param name="ex"></param>
    public static void FataInfo(string Message,Exception ex)
    {
        if (!log.IsFatalEnabled)
            SetConfig();
        log.Fatal(Message, ex);
    }

该类下需要通过NuGet安装下面几个扩展:

  1. Microsoft.Extensions.Logging

  2. Microsoft.Extensions.Logging.Log4Net.AspNetCore

  3. log4net

之后log4net.config配置文件内容:

<log4net>
    <appender name="Console" type="log4net.Appender.ConsoleAppender">
        <layout type="log4net.Layout.PatternLayout">
            <!-- Pattern to output the caller's file name and line number -->
            <conversionPattern value="%5level [%thread] - STACK: %exception{stacktrace} - MESSAGE: %message%newline" />
        </layout>
    </appender>

    <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
        <!--<file value="Log4Net" />
        <appendToFile value="true" />
    <rollingStyle value="Date" />
    <datePattern value="yyyyMMdd&quot;.log&quot;" />
        <maximumFileSize value="100KB" />
        <maxSizeRollBackups value="2" />-->
    <param name="File" value="logfile/" />
    <param name="AppendToFile" value="true" />
    <param name="RollingStyle" value="Date" />
    <param name="DatePattern" value="yyyyMMdd&quot;.log&quot;" />
    <param name="StaticLogFileName" value="false" />

        <layout type="log4net.Layout.PatternLayout">
            <!--<conversionPattern value="%level %thread - STACK: %exception{stacktrace} - MESSAGE: %message%newline" />-->
      <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />
        </layout>
    </appender>

    <root>
        <level value="ALL" />
        <appender-ref ref="Console" />
        <appender-ref ref="RollingFile" />
    </root>
</log4net>

最后,修改Startup.cs文件的Configure方法,增加新参数如下:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)

在Configure方法中,添加:

loggerFactory.AddLog4Net();

完整如下:

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            loggerFactory.AddLog4Net();

            app.UseStaticFiles();

            app.UseMvc();
        }

测试:
我们写个测试的来看看,在Program类的静态方法中,添加段代码测试一下:

        public static void Main(string[] args)
        {
            Logger.Log4Net.LogInfo("test测试");

            try
            {
                int a = 5;
                int b = 1 / (a - 5);
            }
            catch (Exception e)
            {
                Logger.Log4Net.ErrorInfo("异常信息", e);
            }
            BuildWebHost(args).Run();
        }

运行之后,我们会在根目录下的logfile文件夹中,看到出现了一个日志文件:20180513.log
打开,内容如下:

2018-05-13 22:43:12,039 [1] INFO  Biz126.Logger.Log4Net - test测试
2018-05-13 22:43:12,930 [1] ERROR Biz126.Logger.Log4Net - 异常信息
System.DivideByZeroException: Attempted to divide by zero.
   at Biz126.WebAPI.Program.Main(String[] args) in D:\Items\Log测试\Biz126.WebAPI\Program.cs:line 23
2018-05-13 22:43:18,274 [5] INFO  Microsoft.AspNetCore.Hosting.Internal.WebHost - Request starting HTTP/1.1 GET http://localhost:65176/api/values  
2018-05-13 22:43:18,753 [5] INFO  Microsoft.AspNetCore.Hosting.Internal.WebHost - Request finished in 479.9045ms 404 

符合预期,以上。

ASP.NET Core 2.0 WebAPI 跨域问题

关于 asp.net core 2.0 webapi的跨域,我们这里使用CORS来实现,不使用旧的JSONP,可以这样配置:
打开 Startup.cs文件,转到ConfigureServices(IServiceCollection services) 中,增加:

services.AddCors(options =>
{
    options.AddPolicy("AnyOrigin", builder =>
    {
        builder
            .AllowAnyOrigin()
            .AllowAnyMethod();
    });
});

再转到Configure(IApplicationBuilder app, IHostingEnvironment env)中,增加:

app.UseCors("AnyOrigin");

就可以开启CORS跨域了。
关于ASP.Net Core的CORS跨域问题详细的使用方法,请参考《Enable Cross-Origin Requests (CORS) in ASP.NET Core》一文。
下面测试一下:

<html>
    <head>
        
    </head>
    <body>
        
        <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
        <script>
            $(function(){
                $.ajax({
                    url:"http://domain/api/Mall/Category/List",
                    data:{id:1},
                    dataType:"json",
                    type:"post",
                    success:function(result){
                        console.log(result);
                    }
                });
            });
        </script>
    </body>
</html>

直接双击通过浏览器打开这个页面,可以看到,已经读到远程接口的数据了:
console
network
以上。

分类

最新文章

最近回复

  • 老徐: 已经加上了,抱歉才看到
  • 青山: 某种原因,暂停友链,抱歉。
  • 搬瓦工: 朋友 交换链接吗
  • 飞刀说: 名称:飞刀说 描述:...
  • 青山: 计划搬迁到腾讯云,正...
  • 河边的飞刀: 网站名称:飞刀说 网...
  • 老徐: 具体要哪个呢?
  • 老徐: 是不是有点老?
  • 青山: 哇,林志炫
  • 老白: 哇,这改的可以,能不...

归档

标签云

C# .net core asp.net 情感 SQL mongodb sql server EasyUI 安全 激活 linux 身份验证 https typecho .net sql注入 kms MVC IIS 高并发 IE 坑爹 服务器 mysql Oracle Combobox Datagrid 口语 数据抓取

其它