.net实现.aspx页面自动加载.cs程序定义的变量并按照格式输出

做网站,少不了页面,用.net做的话,aspx文件基本都是页面布局什么的,cs文件则是处理程序,这些都很普通啦

但每次在页面里调用变量的时候,都需要在cs里写一大堆东西用来支持页面调用,就很繁琐,很麻烦,很恶心了

然后,老顾就又想着怎么偷懒了。。。。。。怎么能减少cs的改动呢?

首先,我们把需要输出的内容定义成一个Hashtable,然后将Hashtable输出到页面

那么,我们先来实现这个吧

    public static class PageControlHelper
    {
        private static Page CurrentPage
        {
            get
            {
                return HttpContext.Current.CurrentHandler as Page;
            }
        }
        public static void SetToControls(Hashtable ht)
        {
            Page page = CurrentPage;
            SetToControls(page, ht);
        }
        public static void SetToControls(Control ctl, Hashtable ht)
        {
            if (ht.Count != 0)
            {
                int size = ht.Keys.Count;
                foreach (string key in ht.Keys)
                {
                    object val = ht[key];
                    if (val == null)
                    {
                        continue;
                    }
                    Control control = ctl.FindControl(key);
                    if (control != null)
                    {
                        Type t = val.GetType();
                        if (t.Name == "bool" || t.Name == "Boolean")
                        {
                            val = (bool)val ? 1 : 0;
                        }
                        #region 根据control类型进行不同的赋值设置
                        #region CheckBoxList
                        if (control is CheckBoxList)
                        {
                            CheckBoxList cbl = (CheckBoxList)control;
                            string[] v = val.ToString().Split(new string[] { "," }, StringSplitOptions.None);
                            foreach (ListItem li in cbl.Items)
                            {
                                for (int i = 0; i < v.Length; i++)
                                {
                                    if (v[i] == li.Value || v[i].Trim() == li.Value)
                                    {
                                        li.Selected = true;
                                    }
                                }
                            }
                        }
                        #endregion
                        #region RadioButtonList
                        if (control is RadioButtonList)
                        {
                            RadioButtonList rbl = (RadioButtonList)control;
                            rbl.SelectedValue = val.ToString();
                        }
                        #endregion
                        #region DropDownList
                        if (control is DropDownList)
                        {
                            DropDownList ddl = (DropDownList)control;
                            ddl.SelectedValue = val.ToString();
                        }
                        #endregion
                        #region TextBox
                        if (control is TextBox)
                        {
                            TextBox tb = (TextBox)control;
                            tb.Text = val.ToString();
                        }
                        #endregion
                        #region Label
                        if (control is Label)
                        {
                            Label lab = (Label)control;
                            lab.Text = val.ToString();
                        }
                        #endregion
                        #region HtmlSelect
                        if (control is HtmlSelect)
                        {
                            HtmlSelect hs = (HtmlSelect)control;
                            //hs.Items.FindByValue(val.ToString()).Selected = true;
                            hs.Value = val.ToString();
                        }
                        #endregion
                        #region HtmlInputText,input type=text
                        if (control is HtmlInputText)
                        {
                            HtmlInputText hit = (HtmlInputText)control;
                            hit.Value = val.ToString();
                        }
                        #endregion
                        #region HtmlInputHidden,input type=hidden
                        if (control is HtmlInputHidden)
                        {
                            HtmlInputHidden hih = (HtmlInputHidden)control;
                            hih.Value = val.ToString();
                        }
                        #endregion
                        #region HtmlInputPassword,input type=password
                        if (control is HtmlInputPassword)
                        {
                            HtmlInputPassword hip = (HtmlInputPassword)control;
                            hip.Value = val.ToString();
                        }
                        #endregion
                        #region HtmlInputCheckBox,input type=checkbox,仅单一选项可用
                        if (control is HtmlInputCheckBox)
                        {
                            HtmlInputCheckBox htmlinputcheckbox = (HtmlInputCheckBox)control;
                            if (val.ToString() == "1")
                            {
                                htmlinputcheckbox.Checked = true;
                            }
                        }
                        #endregion
                        #region HtmlTextArea,textarea标签
                        if (control is HtmlTextArea)
                        {
                            HtmlTextArea area = (HtmlTextArea)control;
                            area.Value = val.ToString();
                        }
                        #endregion
                        #region HtmlImage,img标签
                        if (control is HtmlImage)
                        {
                            HtmlImage img = (HtmlImage)control;
                            img.Src = val.ToString();
                        }
                        #endregion
                        #region HtmlAnchor,a标签
                        if (control is HtmlAnchor)
                        {
                            HtmlAnchor ha = (HtmlAnchor)control;
                            ha.InnerHtml = val.ToString();
                        }
                        #endregion
                        #region HtmlGenericControl
                        if (control is HtmlGenericControl)
                        {
                            HtmlGenericControl hgc = (HtmlGenericControl)control;
                            hgc.InnerHtml = val.ToString();
                        }
                        #endregion
                        #endregion
                    }
                }
            }
        }
    }

这个是用来实现,所有带有runat="server"的控件,自动获得Hashtable对应的值的

然后我们定义一个基类,让所有页面继承他

        public Hashtable HT = new Hashtable();
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e); // 在继承的页面里定义Hashtable的值
            PageControlHelper.SetToControls(HT);
        }

这样就能直接输出到页面了,但这样还是不太方便,因为我们可能需要将值进行格式化,按照特定格式输出

怎么能支持一下呢?

于是老顾写了一个格式化的类

    public static class TemplateParser
    {
        public static string Parse(string html, Hashtable ht = null)
        {
            string result = html;
            #region 替换$field$设置的变量
            if (ht != null && ht.Count > 0)
            {
                // hashtable 转成datarow
                DataRow dr = DataBaseHelper.ToDataRow(ht);
                foreach (string key in ht.Keys)
                {
                    result = RegexExpand.Replace(result, @"\$" + key + @"\$", ht[key] == null ? string.Empty : ht[key].ToString(), RegexOptions.IgnoreCase);
                    MatchCollection ks = RegexExpand.Matches(result, @"\$" + key + @"\.[^$]+\$", RegexOptions.IgnoreCase);
                    foreach (Match m in ks)
                    {
                        // 将 $field$格式变形成^field^格式进行解析
                        result = result.Replace(m.Value, Parse(dr, RegexExpand.Replace(m.Value, @"^\$|\$$", "^", RegexOptions.IgnoreCase)));
                    }
                }
            }
            result = RegexExpand.Replace(result, @"[\$][a-z][a-z0-9_]*(\.[^\$\.]+)*[\$]", "");
            #endregion
            return result;
        }
        public static class RefFun
        {
            public static string RefFun_Tostring(object val, string args = null)
            {
                string result = string.Empty;
                if (!string.IsNullOrEmpty(val.ToString()))
                {
                    if (string.IsNullOrEmpty(args))
                    {
                        result = val.ToString();
                    }
                    else
                    {
                        Type t = val.GetType();
                        MethodInfo mi = t.GetMethod("ToString", new Type[] { typeof(string) });
                        if (mi != null)
                        {
                            result = (string)mi.Invoke(val, new object[] { args });
                        }
                        else
                        {
                            result = val.ToString();
                        }
                    }
                }
                return result;
            }
        }
        public static string Parse(DataRow row, string format)
        {
            string result = format;
            MatchCollection mc = RegexExpand.Matches(result, @"[\^](\w+)(?:\.([^\.]+?)((?:(\.[^\^\.]+)*?)?))?[\^]");
            for (int i = 0; i < mc.Count; i++)
            {
                string field = mc[i].Groups[1].Value.ToUpper();
                string arg = mc[i].Groups[2].Value.ToLower();
                string para = mc[i].Groups[3].Value;
                // 如果DataRow存在对应字段
                if (row.Table.Columns.IndexOf(field) > -1)
                {
                    try
                    {
                        // 使用枚举定义链接类型
                        LinkType lt = LinkType.Default;
                        OutputLinkType olt;
                        object obj = row.ItemArray[row.Table.Columns.IndexOf(field)];
                        string val = obj.ToString();
                        #region 无参数仅字段名的直接输出
                        if (string.IsNullOrEmpty(arg))
                        {
                            if (!string.IsNullOrEmpty(val.Trim()))
                            {
                                switch (obj.GetType().Name)
                                {
                                    case "DateTime":
                                        val = ((DateTime)obj).ToString("yyyy-MM-dd");
                                        break;
                                    case "Money":
                                        val = RegexExpand.Replace(val, @"\.\d+$", "");
                                        break;
                                    case "Decimal":
                                        val = RegexExpand.Replace(val, @"\.\d+$", "");
                                        break;
                                }
                                result = RegexExpand.Replace(result, RegexExpand.Replace(mc[i].Value, @"\^", "\\^"), val);
                            }
                            else
                            {
                                if (RegexExpand.IsMatch(result, @"(?<=<[^<>]*?)" + RegexExpand.Replace(mc[i].Value, @"\^", "\\^") + "(?=[^<>]*?>)", RegexOptions.IgnoreCase))
                                {
                                    result = RegexExpand.Replace(result, @"<(\w+)(?!\w)[^<>]*?" + RegexExpand.Replace(mc[i].Value, @"\^", "\\^") + @"([^<>]*?/>|([\s\S](?!<\1(?!\w)))*?</\1(?!\w)[^<>]*?>)", "", RegexOptions.IgnoreCase);
                                }
                                else
                                {
                                    result = RegexExpand.Replace(result, @"(?<=(^|>))[^>]*?" + RegexExpand.Replace(mc[i].Value, @"\^", "\\^") + @"[^<]*?(?=(<|$))", "");
                                }
                            }
                        }
                        #endregion
                        #region 限长字符串
                        else if (RegexExpand.IsMatch(arg, @"^\d+$"))
                        {
                            int len = 0;
                            int.TryParse(arg, out len);
                            if (len > 0)
                            {
                                val = StringExpand.ByteSubstring(RegexExpand.Replace(val, @"<[^<>]*?>|[\r\n\s\t]|&nbsp;", ""), len);
                            }
                            result = RegexExpand.Replace(result, RegexExpand.Replace(mc[i].Value, @"\^", "\\^"), val);
                        }
                        #endregion
                        #region 尝试判断是否是链接格式
                        else if (Enum.TryParse<OutputLinkType>(arg, out olt))
                        {
                            lt = (LinkType)olt;
                            result = RegexExpand.Replace(result, RegexExpand.Replace(mc[i].Value, @"\^", "\\^"), MakeLink(row.ItemArray[row.Table.Columns.IndexOf(field)].ToString(), lt, true));
                            // MakeLink用来生成链接,自行设置
                        }
                        #endregion
                        #region 尝试反射到方法
                        else
                        {
                            #region 尝试反射成功则以反射处理
                            Type t = typeof(RefFun);
                            MethodInfo method = t.GetMethod("RefFun_" + RegexExpand.Replace(arg, @"^[a-z]+", RegexExpand.ToTitleCase, RegexOptions.IgnoreCase));
                            if (method != null)
                            {
                                try
                                {
                                    ParameterInfo[] paras = method.GetParameters();
                                    // 由于反射时,反射方法形参具有不同类型,所以根据形参类型预判断需要传递的实参值
                                    if (paras[0].ParameterType == typeof(object))
                                    {
                                        result = RegexExpand.Replace(result, RegexExpand.Replace(mc[i].Value, @"\^", "\\^"), (string)method.Invoke(null, new object[] { obj, RegexExpand.Replace(para, @"^\.", "") }));
                                    }
                                    else
                                    {
                                        result = RegexExpand.Replace(result, RegexExpand.Replace(mc[i].Value, @"\^", "\\^"), (string)method.Invoke(null, new object[] { val, RegexExpand.Replace(para, @"^\.", "") }));
                                    }
                                }
                                catch (Exception ex)
                                {
                                    LogHelper.LogMessage(logType, ex, "RefFun_" + RegexExpand.Replace(arg, @"^[a-z]+", RegexExpand.ToTitleCase, RegexOptions.IgnoreCase) + " 值:" + val + ",异常:" + RegexExpand.Replace(para, @"^\.", ""));
                                }
                            }
                            #endregion
                            #region 当反射失败且未输出时使用最终处理
                            else
                            {
                                LogHelper.LogMessage(logType, mc[i].Value + " 无解析方法");
                                result = RegexExpand.Replace(result, RegexExpand.Replace(mc[i].Value, @"\^", "\\^"), row.ItemArray[row.Table.Columns.IndexOf(field)].ToString());
                            }
                            #endregion
                        }
                        #endregion
                    }
                    catch (Exception ex)
                    {
                        LogHelper.LogMessage(logType, ex, "字段:" + field + ",参数:" + arg + para);
                    }
                }
            }
            return result;
        }
    }

这样,我们可以对html存在的$field$类型的内容进行变量解析了,如果要输出特定格式,就自己再RefFun类里追加自己的解析方法即可,只要是RefFun_开头,后边跟方法名,然后方法名首字母大写,都可以通过反射调用了

那么,现在我们来实现,怎么通过基类进行调用这个解析吧

在PageControlHelper里,追加一个方法

        public static void BindHashtableParameters(Hashtable ht, Control ctls = null)
        {
            ControlCollection cc = ctls == null ? CurrentPage.Controls : ctls.Controls;
            foreach (Control ctl in cc)
            {
                if (ctl.Controls.Count > 0)
                {
                    BindHashtableParameters(ht, ctl);
                }
                if (ctl is RadioButtonList)
                {
                    RadioButtonList rbl = (RadioButtonList)ctl;
                    for (int i = 0; i < rbl.Items.Count; i++)
                    {
                        ListItem li = rbl.Items[i];
                        li.Text = TemplateParser.Parse(li.Text, ht);
                    }
                }
                Type t = ctl.GetType();
                string text = string.Empty;
                PropertyInfo pi = t.GetProperty("InnerHtml");
                if (pi == null)
                {
                    pi = t.GetProperty("Text");
                }
                if (pi != null)
                {
                    try
                    {
                        text = pi.GetValue(ctl, null).ToString();
                    }
                    catch
                    {
                        continue;
                    }
                }
                else
                {
                    continue;
                }
                string parsed = TemplateParser.Parse(text, ht);
                if (text != parsed)
                {
                    try
                    {
                        if (pi.CanWrite)
                        {
                            pi.SetValue(ctl, parsed, null);
                        }
                        else
                        {
                            if (ctl is DataBoundLiteralControl)
                            {
                                if (ctl.Parent is RepeaterItem)
                                {
                                    RepeaterItem ri = ctl.Parent as RepeaterItem;
                                    ri.Controls.Clear();
                                    LiteralControl lc = new LiteralControl(parsed);
                                    ri.Controls.Add(lc);
                                }
                                else
                                {
                                    HtmlGenericControl parent = ctl.Parent as HtmlGenericControl;
                                    parent.InnerHtml = parsed;
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
            }
        }

然后,修改我们的基类

        public Hashtable HT = new Hashtable();
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e); // 在继承的页面里定义Hashtable的值
            PageControlHelper.BindHashtableParameters(HT);
            PageControlHelper.SetToControls(HT);
        }

这样,我们就可以对所有继承了这个基类的页面直接输出变量了,支持runat="server"控件,Hmmmm,但这个不支持格式化输出,支持$field$格式变量,这个支持格式化输出,例如$content.40$就是输出40个字符的内容,$datetime.tostring.yyyy-MM-dd HH:mm$就是格式化输出日期和时间

好了,这就可以偷懒了,除了部分特定运算,基本不再修改cs文件就可以将内容输出出来了,把所有从数据库获得的数据直接扔到hashtable里,让他自动解析吧!

有人说了,比如我的数据库里,有一个地域信息,但他是数值型的,我输出可不能是数字,那么,就自己定义RefFun吧,$city.city.full$,变量定义成类似这样的格式即可,第一个city是字段名,第二个city是RefFun_City这个方法的方法名,full就是输出格式什么的了

多定义几个常用的输出方式,那么后期就基本不再需要考虑变量输出问题了,越来越偷懒了

  • 1
    点赞
  • 2
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

文盲老顾

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值