ValidNumber.ashx 验证码

本文介绍了一个使用 ASP.NET 和 C# 编写的简单验证码生成器,该生成器能够生成包含字母和数字的随机字符串,并将其显示为带有干扰线的图片。

ValidNumber.ashx 代码:

<%@ WebHandler Language="C#" Class="ValidNumber" %>

using System;
using System.Web;
using System.Web.SessionState; //第一步:导入此命名空间
public class ValidNumber : IHttpHandler, IRequiresSessionState
{

    public void ProcessRequest(HttpContext context)
    {
        //种子
        string[] strlist = new[]
        {
            "a","b","c","d","1","2","3","4","5","6","7","8","9","0","q","w","e","r","t","y","u","i","o","p","z","x","n","v","W","Q","B","A","D","D","F","G","H","J","K","L"
        };

        //生成随机数
        string[] list = new string[4];
        Random rd = new Random(DateTime.Now.Millisecond * 100000);
        for (int i = 0; i < 4; i++)
        {
            list[i] = strlist[rd.Next(strlist.Length)];
            System.Threading.Thread.Sleep(5);
        }

        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        for (int i = 0; i < 4; i++)
        {
            sb = sb.Append(list[i]);
        }
        HttpContext.Current.Session["validNumber"] = sb;
        //创建一张图片
        System.Drawing.Bitmap image = new System.Drawing.Bitmap(list.Length * 15, 40);
        //创建画布
        System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(image);
        //清空背景色,并添充成白色
        g.Clear(System.Drawing.Color.White);

        //噪声线
        for (int i = 0; i < 20; i++)
        {
            Random rds = new Random();

            float x1 = rds.Next(image.Width - 1);
            float x2 = rds.Next(image.Width - 1);
            float y1 = rds.Next(image.Height - 1);
            float y2 = rds.Next(image.Height - 1);
            System.Threading.Thread.Sleep(5);
            g.DrawLine(new System.Drawing.Pen(System.Drawing.Color.Silver), x1, y1, x2, y2);
        }
        System.Drawing.Font f = new System.Drawing.Font("黑体", 25, System.Drawing.GraphicsUnit.Pixel);
        System.Drawing.Brush bs = new System.Drawing.SolidBrush(System.Drawing.Color.Red);

        g.DrawString(sb.ToString(), f, bs, 5, 5);
        //当前请求输出的类型
        HttpContext.Current.Response.ContentType = "image/jpeg";
        //保存到输出流
        image.Save(HttpContext.Current.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);

        g.Dispose();
        image.Dispose();

    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

}

页面调用时 <img src="ValidNumber.ashx" alt="图片验证码" /> 但是回发session值改变页面图片没变,暂无比较理想的解决办法,提交时后台用  Response.Write("<script> window.location.href=window.location.href</script>")  刷新下页面。欢迎指教,有没有好点的用法。

<think>我们注意到用户引用的内容涉及UploadHandler.ashx,这是一种基于ASP.NET的通用处理程序(ASHX)用于处理文件上传。根据引用[1][5]中的示例,UploadHandler.ashx的核心代码在ProcessRequest方法中处理上传的文件。 用户需求:在C#中实现文件上传到UploadHandler.ashx 我们将分为两部分: 1. 服务器端:实现UploadHandler.ashx处理上传的文件。 2. 客户端:使用C#(可以是控制台、WinForms等)发送文件到该处理程序。 注意:根据引用[2][3][4]的漏洞信息,我们在实现服务器端时要注意安全性,避免任意文件上传漏洞。 服务器端实现(UploadHandler.ashx): 我们将实现一个安全的文件上传处理程序,包括: - 限制文件类型(白名单) - 限制文件大小 - 使用安全的文件名(避免路径遍历) - 指定上传目录(避免用户指定任意目录) 客户端实现: 使用HttpClient发送multipart/form-data请求,包含文件数据。 具体步骤: 一、服务器端(UploadHandler.ashx)代码示例: 在ASP.NET Web应用程序中添加一个一般处理程序(UploadHandler.ashx),并修改其ProcessRequest方法如下:</think>以下是使用C#实现文件上传到`UploadHandler.ashx`的完整解决方案,包含服务端处理和客户端调用: ### 服务端实现(安全版 UploadHandler.ashx) ```csharp // UploadHandler.ashx public class UploadHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; context.Response.Charset = "utf-8"; // 安全配置 const int maxFileSize = 10 * 1024 * 1024; // 10MB string[] allowedExtensions = { ".jpg", ".png", ".gif" }; string uploadFolder = "~/Uploads/"; // 固定上传目录 try { HttpPostedFile file = context.Request.Files["Filedata"]; if (file == null || file.ContentLength == 0) { context.Response.Write("ERROR: 文件为空"); return; } // 验证文件大小 if (file.ContentLength > maxFileSize) { context.Response.Write($"ERROR: 文件超过{maxFileSize / 1024 / 1024}MB限制"); return; } // 验证文件扩展名 string fileExt = Path.GetExtension(file.FileName).ToLower(); if (!allowedExtensions.Contains(fileExt)) { context.Response.Write("ERROR: 仅支持" + string.Join(",", allowedExtensions) + "格式"); return; } // 生成安全文件名(防止路径遍历) string safeFileName = Guid.NewGuid().ToString("N") + fileExt; string physicalPath = context.Server.MapPath(Path.Combine(uploadFolder, safeFileName)); // 确保目录存在 Directory.CreateDirectory(Path.GetDirectoryName(physicalPath)); // 保存文件 file.SaveAs(physicalPath); context.Response.Write("SUCCESS:" + safeFileName); // 返回安全文件名 } catch (Exception ex) { context.Response.Write("ERROR: " + ex.Message); } } public bool IsReusable => false; } ``` ### 客户端调用(C#控制台/WinForms/WPF) ```csharp using System; using System.IO; using System.Net.Http; using System.Threading.Tasks; class FileUploader { public async Task<string> UploadFile(string filePath, string handlerUrl) { using (var httpClient = new HttpClient()) using (var formData = new MultipartFormDataContent()) { // 读取文件内容 var fileBytes = File.ReadAllBytes(filePath); var fileContent = new ByteArrayContent(fileBytes); // 设置文件字段名(需与服务端匹配) formData.Add(fileContent, "Filedata", Path.GetFileName(filePath)); // 发送POST请求 var response = await httpClient.PostAsync(handlerUrl, formData); // 处理响应 var result = await response.Content.ReadAsStringAsync(); if (result.StartsWith("SUCCESS:")) { return $"上传成功!文件名: {result.Substring(8)}"; } return $"上传失败: {result}"; } } } // 使用示例 static async Task Main(string[] args) { var uploader = new FileUploader(); var result = await uploader.UploadFile( @"C:\test\image.jpg", "http://yourserver.com/Handler/UploadHandler.ashx" ); Console.WriteLine(result); } ``` ### 关键安全措施(防止漏洞) 1. **固定上传目录** 避免使用`context.Request["folder"]`参数(引用[2][4]中的漏洞来源),直接指定安全目录: ```csharp string uploadFolder = "~/App_Data/Uploads/"; // 不可通过URL直接访问 ``` 2. **文件扩展名白名单** ```csharp string[] allowedExtensions = { ".jpg", ".png", ".gif" }; // 仅允许图片 ``` 3. **重命名上传文件** 使用GUID生成新文件名,避免原始文件名注入: ```csharp string safeFileName = Guid.NewGuid().ToString("N") + fileExt; ``` 4. **限制文件大小** ```csharp if (file.ContentLength > 10 * 1024 * 1024) // 10MB ``` 5. **禁用执行权限**(web.config配置) ```xml <system.webServer> <security> <requestFiltering> <fileExtensions> <add fileExtension=".ashx" allowed="true" /> <add fileExtension=".aspx" allowed="false" /> </fileExtensions> </requestFiltering> </security> </system.webServer> ``` ### 部署注意事项 1. **目录权限** 给`IIS_IUSRS`账户赋予上传目录的写入权限 2. **Web.config 配置** ```xml <system.web> <httpRuntime maxRequestLength="10240" /> <!-- 10MB --> </system.web> <system.webServer> <security> <requestFiltering> <requestLimits maxAllowedContentLength="10485760" /> <!-- 10MB --> </requestFiltering> </security> </system.webServer> ``` 3. **跨域支持**(若需要) 在`ProcessRequest`方法中添加: ```csharp context.Response.Headers.Add("Access-Control-Allow-Origin", "*"); ``` ### 工作流程 1. 客户端发送POST请求到`UploadHandler.ashx` 2. 服务端验证文件大小、类型和内容 3. 生成随机文件名保存到安全目录 4. 返回成功消息或错误原因 5. 客户端解析响应结果 > 通过以上实现,可有效避免引用[2][3][4]中提到的任意文件上传漏洞,同时满足常规文件上传需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值