欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-07-09 17:16:13
...

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

AspDotNet写法

前台请求
Asp.Net的ashx模式转.NetCore初探索

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

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了,可以用脚本批量处理
Asp.Net的ashx模式转.NetCore初探索

第一个对应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层请求不变
Asp.Net的ashx模式转.NetCore初探索

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

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

相关标签: DotNetCore