最近公司在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” 即可。
本博客所有文章如无特别注明均为原创
如果觉得对你有帮助,可以通过下方打赏对作者表示鼓励
本文采用知识共享署名-非商业性使用-相同方式共享
如若转载,请注明出处:《用.NET MVC写一个短网址服务》https://www.fangsi.net/1360.html
评论列表(2条)
您好, 按照您说的设置路由规则后,请求返回404,还需要设置什么嘛?谢谢
@5025:需要创建名为Url的控制器,并且在控制器内实现一个名为Jump的Action哦。