1. 首页
  2. 程序生涯
  3. .NET

用.NET MVC写一个短网址服务

最近公司在C端功能上出现了比较多的二维码分享功能,由于是基于微信,所以二维码需要编码的内容很长,导致二维码很密比较难识别。所以我写了一个比较简单的短网址服务,今天来分享一下。

虽然说短网址比较简单,但是在做的过程中还是有比较多需要考虑的关键点。按照网上各大服务商提供的短网址服务,基本是大小写字母和数字,所以算法基本类似,我没过多研究,在网上找了一个,如下:

/// <summary>
/// 转换链接为短码
/// </summary>
/// <param name="url">链接</param>
/// <returns>4个短码集合长度</returns>
public static string[] ShortUrl(string url)
{
    // 可以自定义生成 MD5 加密字符传前的混合 KEY  
    string key = "fangsi";
    // 要使用生成 URL 的字符  
    string[] chars = new string[] { "a" , "b" , "c" , "d" , "e" , "f" , "g" , "h" ,
        "i" , "j" , "k" , "l" , "m" , "n" , "o" , "p" , "q" , "r" , "s" , "t" ,
        "u" , "v" , "w" , "x" , "y" , "z" , "0" , "1" , "2" , "3" , "4" , "5" ,
        "6" , "7" , "8" , "9" , "A" , "B" , "C" , "D" , "E" , "F" , "G" , "H" ,
        "I" , "J" , "K" , "L" , "M" , "N" , "O" , "P" , "Q" , "R" , "S" , "T" ,
        "U" , "V" , "W" , "X" , "Y" , "Z" };

    // 对传入网址进行 MD5 加密  
    string sMD5EncryptResult = Tools.MD5(key + url);
    string hex = sMD5EncryptResult;

    string[] resUrl = new string[4];
    for (int i = 0; i < 4; i++)
    {
        // 这里需要使用 long 型来转换,因为 Inteper .parseInt() 只能处理 31 位 , 首位为符号位 , 如果不用 long ,则会越界  
        int hexint = 0x3FFFFFFF & Convert.ToInt32("0x" + hex.Substring(i * 8, 8), 16);
        string outChars = string.Empty;
        for (int j = 0; j < 6; j++) { // 把得到的值与 0x0000003D 进行位与运算,取得字符数组 chars 索引 long index = 0x0000003D & hexint; // 把取得的字符相加 outChars += chars[index]; // 每次循环按位右移 5 位 hexint = hexint >> 5;
        }
        // 把字符串存入对应索引的输出数组  
        resUrl[i] = outChars;
    }
    return resUrl;
}

通过以上的方法就能将网址编码为短码,再进行存储,那么在生成前需要注意什么吗? 当然是可以去考虑一下网址的真实性的,所以就有了验证网址是否正常可访问的代码:

/// <summary>
/// 网址有效性检查
/// </summary>
/// <param name="url">需要检查的url,ip地址也可以</param>
/// <returns>是否可用</returns>
public static bool UrlIsOK(string url)
{
    try
    {
        if (!url.Contains("http"))
        {
            return false;
        }
        HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(url);
        myRequest.Method = "HEAD";
        myRequest.Timeout = 5000;  //超时时间5秒
        HttpWebResponse res = (HttpWebResponse)myRequest.GetResponse();
        return ((int)res.StatusCode < 400);
    }
    catch
    {
        try
        {
            HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(url);
            myRequest.Method = "GET";
            myRequest.Timeout = 5000;  //超时时间5秒
            HttpWebResponse res = (HttpWebResponse)myRequest.GetResponse();
            return ((int)res.StatusCode < 400);
        }
        catch
        {
            return false;
        }
    }
}

这里利用HEAD进行请求,消耗资源比较小,但是在使用的时候发现HEAD对于有些服务并不能正常的响应。所以就增加了一个GET请求,确保网址能被正确的验证。 验证完网址,并生成短码后,存储到数据库时新的问题来了,如何在MVC中能做到像其它服务一样进行域名后跟短码“http://t.cn/Rz6ka2d”这中形式的链接呢? 其实很简单,加入我们进行跳转的控制器名为“Url”,action的名称为“Jump”,那么我们只需在路由中新增规则:

routes.MapRoute(
    name: "ShortUrl",
    url: "{key}",
    defaults: new { controller = "Url", action = "Jump", id = UrlParameter.Optional }
);

这样就可以实现域名后跟短码进行访问,并且不会影响到其它的控制器。到这里已经可以实现将网址验证后生成短码,并实现了短码接收。但是我做的时候是通过SQLServer数据库进行短码存储的,因为SQLServer默认查询where条件是不区分大小写的,所以还需要在查询的SQL后带上:“COLLATE Chinese_PRC_CS_AS” 即可。

原创文章,作者:锋哥,如若转载,请注明出处:https://www.fangsi.net/1360.html

发表评论

登录后才能评论

联系我们

在线咨询:点击这里给我发消息

邮件:service@fangsi.net

工作时间:周一至周五,9:30-18:30,节假日休息