建表
CREATE TABLE [dbo].[ShortUrl]( [Id] [int] IDENTITY(1,1) NOT NULL, [LongUrl] [nvarchar](500) NOT NULL, [BaseUri] [int] NOT NULL, [ShortToken] [nvarchar](50) NOT NULL, [Hits] [int] NOT NULL, [Creator] [nvarchar](50) NULL, [CreateTime] [datetime] NOT NULL, [LastUpdateTime] [datetime] NULL, [LastOperator] [nvarchar](50) NULL, [Enable] [bit] NOT NULL, [IsDelete] [bit] NOT NULL ) ON [PRIMARY] GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'长链地址' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'ShortUrl', @level2type=N'COLUMN',@level2name=N'LongUrl' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'短链域名对应数值' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'ShortUrl', @level2type=N'COLUMN',@level2name=N'BaseUri' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'短链末尾编码串' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'ShortUrl', @level2type=N'COLUMN',@level2name=N'ShortToken' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'url点击量' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'ShortUrl', @level2type=N'COLUMN',@level2name=N'Hits' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'创建人' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'ShortUrl', @level2type=N'COLUMN',@level2name=N'Creator' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'创建时间' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'ShortUrl', @level2type=N'COLUMN',@level2name=N'CreateTime' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'最近更新时间' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'ShortUrl', @level2type=N'COLUMN',@level2name=N'LastUpdateTime' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'更新操作人' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'ShortUrl', @level2type=N'COLUMN',@level2name=N'LastOperator' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'是否启用' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'ShortUrl', @level2type=N'COLUMN',@level2name=N'Enable' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'是否删除' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'ShortUrl', @level2type=N'COLUMN',@level2name=N'IsDelete' GO ALTER TABLE [dbo].[ShortUrl] ADD CONSTRAINT [DF_ShortUrl_IsDelete] DEFAULT ((0)) FOR [IsDelete] GO
CREATE TABLE [dbo].[ShortUrlStat]( [Id] [int] IDENTITY(1,1) NOT NULL, [UrlId] [int] NOT NULL, [ShortUrl] [nvarchar](500) NOT NULL, [UrlRefferer] [nvarchar](500) NOT NULL, [UserAgent] [nvarchar](500) NOT NULL, [UserHostAddress] [nvarchar](500) NOT NULL, [UserLanguage] [nvarchar](100) NOT NULL, [Browser] [nvarchar](200) NOT NULL, [MajorVersion] [int] NOT NULL, [IsMobile] [bit] NOT NULL, [CreateTime] [datetime] NOT NULL ) ON [PRIMARY] GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'状态记录所对应的长链的id' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'ShortUrlStat', @level2type=N'COLUMN',@level2name=N'UrlId' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'短链地址' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'ShortUrlStat', @level2type=N'COLUMN',@level2name=N'ShortUrl' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'获取Url链接当前客户端的主机部分' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'ShortUrlStat', @level2type=N'COLUMN',@level2name=N'UrlRefferer' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'获取客户端完整的用户代理字符串' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'ShortUrlStat', @level2type=N'COLUMN',@level2name=N'UserAgent' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'获取客户端ip的主机地址' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'ShortUrlStat', @level2type=N'COLUMN',@level2name=N'UserHostAddress' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'获取客户端语言首选项' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'ShortUrlStat', @level2type=N'COLUMN',@level2name=N'UserLanguage' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'获取浏览器请求标头中发送的浏览器字符串' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'ShortUrlStat', @level2type=N'COLUMN',@level2name=N'Browser' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'获取浏览器主版本号' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'ShortUrlStat', @level2type=N'COLUMN',@level2name=N'MajorVersion' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'获取浏览器是否已标识为移动设备' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'ShortUrlStat', @level2type=N'COLUMN',@level2name=N'IsMobile' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'创建时间' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'ShortUrlStat', @level2type=N'COLUMN',@level2name=N'CreateTime' GO
@model IEnumerable<ShortUrl.ShortUrlModels> @{ ViewBag.Title = "Index"; } <h2>Index</h2> <a href="@Url.Action("AddDetail", "ShortUrl")">新增</a> @if (Model != null && Model.Any()) { <table> <thead> <tr> <th style="text-align: center"> 序号 </th> <th style="text-align: center">短链</th> </tr> </thead> <tbody> @foreach (var item in Model) { <tr> <td>@item.Id</td> <td><a href="@Url.Action("ReirectToken", "ShortUrl", new { id =item.Id})" target="_blank">@item.BaseShortUrl</a></td> </tr> } </tbody> </table> }
@using ShortUrl @model ShortUrl.ShortUrlModels @{ ViewBag.Title = "AddShortUrl"; } <script src="@Url.Content("~/Scripts/jquery-1.8.2.min.js")"></script> <h2>AddShortUrl</h2> <table style=" 99%; margin: 5px auto;"> <tbody> <tr> <td>长链</td> <td> <input type="text" value="@Model.LongUrl" id="longurl"/> </td> </tr> <tr> <td>短网址后缀</td> <td> @Html.DropDownListFor(m => m.BaseUri, new KvSelectList(Model.ShortUrl)) </td> </tr> <tr> <td> <input type="button" value="保存" class="sBtn" id="btnSave" style="margin-left: 45%"/> </td> </tr> </tbody> </table> <script type="text/javascript"> function necessaryinput() { //if ($("#longurl").val() == '' || $("#longurl").val() == undefined || $("#longurl").val().match(/(http[s]?|ftp)://([w-]+.)+[w-]+(/[w- ./?%&=]*)?/) == null) { // alert("请输入合法的长链地址"); // return false; //} if ($("#longurl").val() == '' || $("#longurl").val() == undefined) { alert("请输入长链地址"); return false; } return true; } var model = {}; $("#btnSave").click(function () { model.LongUrl = $.trim($("#longurl").val()); model.BaseUri = $.trim($("#BaseUri").val()); if (confirm("你确定保存吗?")) { if (necessaryinput()) { $.ajax({ url: '@Url.Action("Add", "ShortUrl")', type: 'post', dataType: 'json', contentType: 'application/json', data: JSON.stringify(model), success: function (result) { if (result.DoFlag) { alert(result.DoResult); window.location.href = '@Url.Action("Index", "ShortUrl")'; } else { alert(result.DoResult); } } }); } } }) </script>
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Web; using System.Web.Mvc; using ShortUrl.Models; using ShortUrlDbEntity; using ShortUrlUtility; namespace ShortUrl.Controllers { public class ShortUrlController : Controller { // // GET: /ShortUrl/ MVCDemoEntities db = new MVCDemoEntities(); public ActionResult Index() { List<ShortUrlModels> shortUrlList = new List<ShortUrlModels>(); shortUrlList.AddRange(db.ShortUrl.OrderByDescending(x => x.Hits).ThenByDescending(x => x.LastUpdateTime).Select(t => new ShortUrlModels() { Id=t.Id, LongUrl = t.LongUrl, BaseUri = t.BaseUri, ShortToken = t.ShortToken, Hits = t.Hits, CreateTime = t.CreateTime, })); return View(shortUrlList); } //短链跳转 public ActionResult ReirectToken(int id) { if (id == 0) return RedirectToAction("UrlNotFound", "ShortUrl"); else { var shortUrlRecord = db.ShortUrl.FirstOrDefault(t => t.Id == id); if (shortUrlRecord == null) return RedirectToAction("UrlNotFound", "ShortUrl"); else { ShortUrlModels shortUrlModel = new ShortUrlModels(); shortUrlModel = Mapper.GetMapper.Map<ShortUrlDbEntity.ShortUrl, ShortUrlModels>(shortUrlRecord); ShortUrlStatModels stats = new ShortUrlStatModels(Request); stats.UrlId = id; stats.ShortUrl = shortUrlModel.BaseShortUrl; stats.CreateTime = DateTime.Now; var dbstats = Mapper.GetMapper.Map<ShortUrlStatModels, ShortUrlStat>(stats); db.ShortUrlStat.Add(dbstats); db.SaveChanges(); shortUrlRecord.Hits++; shortUrlRecord.LastUpdateTime = DateTime.Now; db.SaveChanges(); return Redirect(shortUrlModel.LongUrl); } } } public ActionResult UrlNotFound() { return View(); } public ActionResult AddDetail(ShortUrlModels model) { ShortUrlModels shortmodels=new ShortUrlModels(); return View("AddDetail", shortmodels); } //添加url model.LongUrl = HttpUtility.UrlDecode(model.LongUrl) ?? "";
public JsonResult Add(ShortUrlModels model) { try {
if (string.IsNullOrEmpty(model.LongUrl)) return Json(new { DoResult = "请输入Url地址" }, JsonRequestBehavior.AllowGet); else { if (CheckLongUrlExists(model.LongUrl)) { if (!HasHttPProtocol(model.LongUrl)) model.LongUrl = "http://" + model.LongUrl; var existingUrl = db.ShortUrl.FirstOrDefault(u => Equals(u.LongUrl.ToLower(), model.LongUrl.ToLower())); if (existingUrl == null) { ShortUrlModels shortUrl = new ShortUrlModels() { LongUrl = model.LongUrl, BaseUri = model.BaseUri, Hits = 0, CreateTime = DateTime.Now, LastUpdateTime = DateTime.Now, Enable = true, //ShortToken = GenerateRandomShortUrl() //ShortToken = GenerateRandomString(6) ShortToken = Guid.NewGuid().ToString().Substring(0, 6) }; var shortUrlDb = Mapper.GetMapper.Map<ShortUrlModels, ShortUrlDbEntity.ShortUrl>(shortUrl); db.ShortUrl.Add(shortUrlDb); db.SaveChanges(); var result = new {DoResult = "新增成功", DoFlag = true}; return Json(result, JsonRequestBehavior.AllowGet); } else { var result = new {DoResult = "新增失败,Url已被添加过", DoFlag = false}; return Json(result, JsonRequestBehavior.AllowGet); } } else { var result = new { DoResult = "Url地址不存在或已失效,请填写正确的地址", DoFlag = false }; return Json(result, JsonRequestBehavior.AllowGet); } } } catch (Exception ex) { return Json(new { DoResult = "新增异常", DoFlag = false }, JsonRequestBehavior.AllowGet); } } //校验url开头带不带http private bool HasHttPProtocol(string url) { url = url.ToLower(); if (url.Length > 5) { if (url.StartsWith(Constants.Protocol.HTTP) || url.StartsWith(Constants.Protocol.HTTPS)) return true; else return false; } else return false; } //生成随机的6位串 public string GenerateRandomShortUrl() { string number = ""; int j; Random random = new Random(); for (int i = 0; i < 6; i++) { j = random.Next(0, 35); if (j < 10) j += 48; else j += 87; number = number + char.ConvertFromUtf32(j); } return number; } //生成随机的串(方法二) public static string GenerateRandomString(short len = 11) { string rand = string.Empty; while (rand.Length < len) { rand += GetCleanRandString(); } return rand.Substring(0, len); } private static string GetCleanRandString() { char[] AmbiguousChars = { 'l', '1', '.' }; return string.Join(string.Empty, System.IO.Path.GetRandomFileName().ToLower().Split(AmbiguousChars)); } //removed 'I', 'l', '1', 'O' and '0' const string chars = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ"; private readonly int theBase = chars.Length; public string Encode(int value) { var hash = ""; if (value > 0) { var remainder = value % theBase; hash += chars[remainder]; value = value / theBase; } hash += chars[value]; return hash; } public int Decode(string hash) { var result = 0; for (var i = hash.Length - 1; i >= 0; i--) { result += (chars.IndexOf(hash[i]) * (int)(Math.Pow(theBase, i))); } return result; } //检测url有没有过期 public bool CheckLongUrlExists(string url) { if (!HasHttPProtocol(url)) url = Constants.Protocol.HTTP + url; try { //Creating the HttpWebRequest HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; //Setting the Request method HEAD, you can also use GET too. request.Method = "HEAD"; //Getting the Web Response. HttpWebResponse response = request.GetResponse() as HttpWebResponse; //Returns TRUE if the Status code == 200 return (response.StatusCode == HttpStatusCode.OK); } catch { return false; } } } }
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace ShortUrl { public class ShortUrlModels { public int Id { get; set; } public string LongUrl { get; set; } public int BaseUri { get; set; } public string ShortToken { get; set; } public int Hits { get; set; } public string Creator { get; set; } public DateTime CreateTime { get; set; } public DateTime LastUpdateTime { get; set; } public string LastOperator { get; set; } public bool Enable { get; set; } public bool IsDelete { get; set; } private Dictionary<int, string> _shortUrl; public Dictionary<int, string> ShortUrl { get { _shortUrl= new Dictionary<int, string>() { {1,"t.cn"}, {2,"dwz.cn"}, {3,"qq.cn.hn"}, {4,"jd.cn.hn"}, {5,"tb.cn.hn"}, {6,"sina.lt"}, {7,"tinyurl.com"}, {8,"qr.net"}, {9,"goo.gl"}, {10,"is.gd"}, {11,"j.mp"}, {12,"bit.ly"} }; return _shortUrl; } set { _shortUrl = value; } } public string BaseShortUrl { get { return "http://" + ShortUrl[BaseUri]+"/"+ShortToken; } } } }
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace ShortUrl.Models { public class ShortUrlStatModels { public int Id { get; set; } //短链的Id public int UrlId { get; set; } //短链地址 public string ShortUrl { get; set; } //获取Url链接当前客户端的主机部分 public string UrlRefferer { get; set; } //获取客户端完整的用户代理字符串 public string UserAgent { get; set; } //获取客户端ip的主机地址 public string UserHostAddress { get; set; } //获取客户端语言首选项 public string UserLanguage { get; set; } //获取浏览器请求标头中发送的浏览器字符串 public string Browser { get; set; } //获取浏览器主版本号 public int MajorVersion { get; set; } //获取浏览器是否已标识为移动设备 public bool IsMobile { get; set; } //创建时间 public DateTime CreateTime { get; set; } public ShortUrlStatModels(HttpRequestBase request) { if (string.IsNullOrEmpty(request.UrlReferrer.Host)) UrlRefferer = Constants.UNKNOWN; else UrlRefferer = request.UrlReferrer.Host; if (string.IsNullOrEmpty(request.UserAgent)) UserAgent = Constants.UNKNOWN; else UserAgent = request.UserAgent; if (string.IsNullOrEmpty(request.UserHostAddress)) UserHostAddress = Constants.UNKNOWN; else UserHostAddress = request.UserHostAddress; if (string.IsNullOrEmpty(request.UserLanguages[0])) UserLanguage = Constants.UNKNOWN; else UserLanguage = request.UserLanguages[0]; if (string.IsNullOrEmpty(request.Browser.Browser)) Browser = Constants.UNKNOWN; else Browser = request.Browser.Browser; MajorVersion = request.Browser.MajorVersion; IsMobile = request.Browser.IsMobileDevice; } } }
生成随机串其它参考:
/// <summary> /// 短网址应用 ,例如QQ微博的url.cn http://url.cn/2hytQx /// </summary> /// <param name="url"></param> /// <returns></returns> public static string[] ShortUrl(string url) { //可以自定义生成MD5加密字符传前的混合KEY string key = "fooo_2016"; //要使用生成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 hex = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(key + url, "md5"); string[] resUrl = new string[4]; for (int i = 0; i < 4; i++) { //把加密字符按照8位一组16进制与0x3FFFFFFF进行位与运算 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索引 int index = 0x0000003D & hexint; //把取得的字符相加 outChars += chars[index]; //每次循环按位右移5位 hexint = hexint >> 5; } //把字符串存入对应索引的输出数组 resUrl[i] = outChars; } return resUrl; } protected void Button1_Click(object sender, EventArgs e) { string[] Shor = ShortUrl(this.TextBox1.Text); // Response.Write( ); //得到值fAVfui //ShortUrl(http://www.jb51.net)[1]; //得到值3ayQry //ShortUrl(http://www.jb51.net)[2]; //得到值UZzyUr //ShortUrl(http://www.jb51.net)[3]; //得到值36rQZn for (int i = 0; i < Shor.Length; i++) { Response.Write("<br/>" + i + ">>" + Shor[i]); } }
// url + (url.EndsWith("?") ? "" : "?" //string host = txtWebUrl.Text.Trim().TrimEnd('/').ToLower(); url = (host.StartsWith("http") || host.StartsWith("https"))? host:"http://" + host;