Bootstrap

Asp.Net的ashx模式转.NetCore初探索

由于以前开发Asp.Net网站时候才用的后台ashx配合前台ajax实现的交互。ashx起码有500个以上。js里调用地址更是不计其数。如果不按ashx模式调用的话,js修改都很大工作量。而DotNetCore里已经没有ashx了,都是用中间件。为此试着用中间件模拟了ashx效果,最大程度降低换平台工作量。

AspDotNet写法

前台请求
在这里插入图片描述

后端ashx
在这里插入图片描述

DotNetCore模拟实现

1.先定义执行请求接口

using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace WebTow
{
    /// <summary>
    /// http执行请求接口
    /// </summary>
    public interface IBaseHttpHandler
    {
        /// <summary>
        /// 执行请求
        /// </summary>
        /// <param name="context"></param>
        public void ProcessRequest(HttpContext context);
    }
}

2.实现请求基类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;

namespace WebTow
{
    /// <summary>
    /// 执行请求基类
    /// </summary>
    public class BaseHttpHandler : IBaseHttpHandler
    {
        /// <summary>
        /// 系统内嵌的超级用户
        /// dhcc账户不能被删除
        /// dhcc不能被锁定
        /// dhcc具有所有的菜单
        /// dhcc具有所有的功能
        /// dhcc密码不能被修改
        /// </summary>
        public static string DHCC = "dhcc";

        /// <summary>
        /// 所有的请求参数
        /// </summary>
        private HttpContext contex;

        /// <summary>
        /// 所有的响应参数
        /// </summary>
        private HttpResponse response;

        /// <summary>
        /// 所有的请求参数
        /// </summary>
        private HttpRequest request;

        /// <summary>
        /// 所有的请求参数
        /// </summary>
        public HttpRequest Request
        {
            get
            {
                return request;
            }
            set
            {
                request = value;
            }
        }

        /// <summary>
        /// 所有的响应参数
        /// </summary>
        public HttpResponse Response
        {
            get
            {
                return response;
            }
            set
            {
                response = value;
            }
        }

        /// <summary>
        /// 重载方法
        /// </summary>
        /// <param name="context">上下文</param>
        public void ProcessRequest(HttpContext context)
        {
            //赋值私有变量
            request = context.Request;
            response = context.Response;


            //是否是访问登录界面
            string path = Request.GetDisplayUrl();
            //判断是否访问登陆界面
            bool loginFlag = path.ToLower().IndexOf("login.ashx") > -1;


            //统一处理方法调用
            string result = string.Empty;
            try
            {
                //执行要调用的方法
                result = ProcessRequestReflect();
                //否则输出结果
                Write(result);
                return;
            }
            catch (Exception e)
            {
                Write(e.Message);
                return;
            }
        }

        /// <summary>
        /// 前台的统一输出方法
        /// </summary>
        /// <param name="message"></param>
        public void Write(string message)
        {
            this.Response.WriteAsync(message);
        }


        /// <summary>
        /// 调用需要调用的所有方法 
        /// </summary>
        /// <returns></returns>
        private string ProcessRequestReflect()
        {
            //获得前台传入的要调用的方法名称
            string method = Request.Query["Method"];
            //方法名称不为空,找到并执行方法
            if (!string.IsNullOrEmpty(method))
            {
                //根据名称获得方法信息
                MethodInfo methodInfo = this.GetType().GetMethod(method, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public);
                //没找到方法就抛出错误信息
                if (methodInfo == null)
                {
                    return "未找到后台方法“" + method + "”!";
                }
                //执行找到的方法,并返回结果
                return (string)methodInfo.Invoke(this, null);
            }
            else
            {
                return "方法名Method不能为空!";
            }
        }

    }
}

3.实现自定义中间件

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;

namespace WebTow
{
    // You may need to install the Microsoft.AspNetCore.Http.Abstractions package into your project
    public class MianMiddleware
    {
        private readonly RequestDelegate _next;

        public MianMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public Task Invoke(HttpContext httpContext)
        {
            httpContext.Response.ContentType = "text/plain;charset=utf-8";
            //string url = httpContext.Request.GetDisplayUrl();
            //string [] urlArr = url.Split('?')[0].Split('/');
            //string className = urlArr[urlArr.Length-1];
            //className = className.Split('.')[0];
            string path = httpContext.Request.Path;
            string className = path.Split('.')[0].Replace("/",".");
            if(className=="")
            {
                return null;
            }
            object objDeal = GetObjectByConfString("WebTow" + className);
            IBaseHttpHandler baseDeal = objDeal as IBaseHttpHandler;
            if(baseDeal!=null)
            {
                baseDeal.ProcessRequest(httpContext);
            }
            return null;
        }

        /// <summary>
        /// 通过配置得当对象
        /// </summary>
        /// <param name="confStr">配置</param>
        /// <returns></returns>
        private object GetObjectByConfString(string confStr)
        {
            try
            {
                string[] strArr = confStr.Replace(" ", "").Split(',');
                Assembly assembly = null;
                if (strArr.Length < 2)
                {
                    assembly = Assembly.GetExecutingAssembly();
                }
                else
                {
                    string path = AppContext.BaseDirectory + strArr[1];
                    if (!path.Contains(".dll"))
                    {
                        path = path + ".dll";
                    }
                    assembly = Assembly.LoadFile(path);
                }
                object obj = assembly.CreateInstance(strArr[0], false);
                return obj;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

    }

    // Extension method used to add the middleware to the HTTP request pipeline.
    public static class MianMiddlewareExtensions
    {
        public static IApplicationBuilder UseMianMiddleware(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<MianMiddleware>();
        }
    }
}

4.在Startup注册中间件

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace WebTow
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
        }

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

            app.UseRouting();
            //注册中间件
            app.UseMiddleware<MianMiddleware>();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Hello World!");
                });
            });
        }
    }
}

然后模拟实现两个ashx的类,这里后缀为cs了,可以用脚本批量处理
在这里插入图片描述

第一个对应ashx的实现类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace WebTow.Test.ashx
{
    public class TestAshx:BaseHttpHandler
    {
        public string GetData()
        {
            return "我是ashx里实现方法,这是我给前端返回的参数";
        }
    }
}

第二个对应ashx的实现类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace WebTow.Test.ashx
{
    public class TestTowAshx : BaseHttpHandler
    {
        public string GetData()
        {
            return "我是ashx里实现方法2,这是我给前端返回的参数";
        }
    }
}

完成以上后前台就能和以前ashx一样调用了,可以保证js层请求不变
在这里插入图片描述

在这里插入图片描述

以上就是ashx文件迁移的探索部分

;