生成商品静态页的类和方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Web;
using System.Threading;



/// <summary>
/// 用于生成商品详细页的类
/// </summary>
public class ProductHtmlCreate
{
    /// <summary>
    /// 存储商品静态文件的文件夹路径,在Application_Start事件中被设置为磁盘的绝对路径
    /// </summary>
    public static string ProductFolder = "~/Pro/";

    /// <summary>
    /// 根据商品ID,生成静态文件
    /// </summary>
    /// <param name="pid">商品ID</param>
    /// <param name="productUrl">商品页面绝对Url地址</param>
    /// <param name="useProTypeFolder">是否根据商品类型来存放静态页面的文件夹,如果为true,则根据商品类型来存放静态页面的文件夹,否则统一使用ProductHtmlCreate.ProductFolder指定的文件夹</param>
    public static void CreateHtml(ProductHtmlSaveConfig config, string productUrl, bool useProTypeFolder)
    {

        //获取HTML
        string html = MySpider.GetResponseText(string.Format(productUrl + "?pid={0}", config.ProductID), null);
        //存储静态HTML文件的文件夹路径
        string folderPath = ProductFolder;
        if (useProTypeFolder)
        {
            folderPath = GetFolderByProType(config.TypeID);
            if (!Directory.Exists(folderPath))
            {
                Directory.CreateDirectory(folderPath);
            }
        }
        //静态文件本地路径
        string filePath = folderPath + config.ProductID + ".html";
        var model = AppCache.Product.GetProduct(int.Parse(config.ProductID));
        if (model != null)
        {
            //如果已经存在静态文件,则删除其静态文件
            if (!string.IsNullOrEmpty(model.HtmlPath))
            {
                string oldFilePath = HttpRuntime.AppDomainAppPath + model.HtmlPath.Substring(1).Replace('/', '\\');
                if (File.Exists(oldFilePath))
                {
                    File.Delete(oldFilePath);
                }
            }
        }
        //将静态文件的路径更新至数据库
        AppCache.Product.SetHtmlPath(int.Parse(config.ProductID), "/" + filePath.ToLower().Substring(HttpRuntime.AppDomainAppPath.Length).Replace('\\', '/'));

        //将所有href替换为正确的相对路径
        html = RegexCollection.RegHref.Replace(html, (mat) =>
        {
            return "href=" + mat.Groups[1].Value + GetHref(productUrl, mat.Groups[2].Value) + mat.Groups[1].Value;
        });

        //将所有src替换为正确的相对路径
        html = RegexCollection.RegSrc.Replace(html, (mat) =>
        {
            return "src=" + mat.Groups[1].Value + GetHref(productUrl, mat.Groups[2].Value) + mat.Groups[1].Value;
        });
        //生成静态文件
        using (StreamWriter writer = new StreamWriter(filePath, false, Encoding.UTF8))
        {
            writer.Write(html);
        }
    }

    /// <summary>
    /// 从一个商品类型集合里,批量生成商品详细页的静态页
    /// </summary>
    /// <param name="arr">商品信息配置集合</param>
    /// <param name="productUrl">商品页绝对url</param>
    /// <param name="isAsyn">是否使用异步</param>
    /// <param name="act">异步结束后调用的委托</param>
    /// <param name="useProTypeFolder">是否根据商品类型选择存储文件夹</param>
    public static void CreateHtmlList(IEnumerable<ProductHtmlSaveConfig> arr, string productUrl, bool isAsyn, Action<int, int> act, bool useProTypeFolder)
    {
        if (isAsyn)
        {
            Action asynAct = () =>
            {
                int successCount = 0;
                foreach (var item in arr)
                {

                    try
                    {
                        CreateHtml(item, productUrl, useProTypeFolder);
                        //没成功生成一个html文件,则successCount自增
                        successCount++;
                    }
                    catch (Exception ex)
                    {

                    }
                }
                if (act != null)
                {
                    act(arr.Count(), successCount);
                }
            };
            asynAct.BeginInvoke(new AsyncCallback(
                isr => ((Action)isr.AsyncState).EndInvoke(isr)
           ), asynAct);
        }
        else
        {
            foreach (var item in arr)
            {
                CreateHtml(item, productUrl, useProTypeFolder);
            }
        }
    }


    /// <summary>
    /// 根据页面url地址,和资源url地址,生成一个引用资源的绝对url地址
    /// </summary>
    /// <param name="currentUrl">页面url地址</param>
    /// <param name="href">资源url地址</param>
    /// <returns></returns>
    public static string GetHref(string currentUrl, string href)
    {
        href = href.Trim().ToLower();
        //如果实在href里面调用JS,则返回当前JS调用
        if (href.StartsWith("javascript"))
        {
            return href;
        }
        string scheme = "";
        if (href.Length > 5)
        {
            scheme = href.Substring(0, 6).ToLower();
        }
        //如果是http开头,则直接返回
        if (scheme.StartsWith("http:") || href.StartsWith("https:"))
        {
            return href;
        }

        Uri uri = new Uri(currentUrl);
        //获取,域名加端口号,类似http://a.com:789
        string start = uri.Scheme + "://" + uri.Authority;

        //如果href使用绝对路径,直接返回绝对路径
        if (href.StartsWith("/"))
        {
            return href;
        }//如果href使用类似 ../之类的相对路径
        else if (href.StartsWith("../"))
        {
            int count = 0;
            int index = 0;
            while ('.' == href[index] && '.' == href[index + 1] && '/' == href[index + 2])
            {
                count++;
                index += 3;
            }

            for (int i = 0; i < uri.Segments.Length - 1 - count; i++)
            {
                start += uri.Segments[i];
            }
            start += href.Substring(index);
            //返回资源的绝对路径
            return new Uri(start).AbsolutePath;

        }//如果href和当前路径在同一目录
        else
        {
            //如果currentUrl是类似于http://aa.com或者http://aa.com/aa/之类的路径,则应该将uri.Segments中的最后一个字符串也算进去
            for (int i = 0; i < (uri.Segments[uri.Segments.Length - 1].EndsWith("/") ? uri.Segments.Length : uri.Segments.Length - 1); i++)
            {
                start += uri.Segments[i];
            }
            start += href;
            //返回资源的绝对路径
            return new Uri(start).AbsolutePath;
        }
    }

    /// <summary>
    /// 根据商品类型ID,获取商品静态页面保存的完整目录
    /// </summary>
    /// <param name="typeId"></param>
    /// <returns></returns>
    public static string GetFolderByProType(string typeId)
    {
        //如果没用商品类别,则返回存储商品静态页的顶级目录
        if (typeId == "0")
        {
            return ProductFolder;
        }
        var list = MyCache.GetCache<Dictionary<string, ProType>>(CacheConfigList.AllProType.Name, CacheConfigList.AllProType.Func, CacheConfigList.AllProType.TimeSpan);
        StringBuilder sb = new StringBuilder(50);
        sb.Append(ProductFolder);
        int index = sb.Length;
        //递归商品类型
        while (list.ContainsKey(typeId))
        {
            sb.Insert(index, list[typeId].ImgFolderName);
            index += list[typeId].ImgFolderName.Length;
            sb.Insert(index, '\\');
            typeId = list[typeId].FatherID.ToString();
        }
        return sb.ToString();
    }
}


/// <summary>
/// 保存商品静态页需要使用的参数
/// </summary>
public class ProductHtmlSaveConfig
{
    public string ProductID { get; set; }
    public string TypeID { get; set; }
}
原文地址:https://www.cnblogs.com/mxw09/p/1923383.html