• 【转】小知识4


    1.关于页面的内置对象(现在先大体讲一下这些ASP.NET内置对象的本质及研究方法,关于它们的使用请看5)

    以前只知道在cs里可以直接用什么Session啦Response啦Request啦Server啦Cache啦Application啦等等这些在ASP时代就已经知道的所谓的内置对象,从来没有想过这些内置对象到底是什么,直到最近在J2EE里用到了Session时却要先实例化一个Session对象才能用:HttpSession mysession=request.getSession(); 我就想为什么在ASP.NET里可以直接用呢?原来Session等在ASP.NET中被称为"内置对象",那么何为内置对象呢?其实也是类的实例,只不过这些对象的实例化比较特殊,是通过Page类的属性来实例化的(我们可以敲出Page类然后转到定义,会发现其有很多属性名就是我们的这些内置对象的名字,这些属性的get方法将实例化并返回一个这些内置对象所属类型的实例,而这个实例的引用名与内置对象名相同),这样我们在我们自己的页面里就可以直接敲出属性名(别忘了我们的页面是继承自Page类,当然可以这样做)就可以得到那些内置对象了。按照这样的逻辑只要我们知道这些内置对象所属的类型,就可以在我们页面中通过new的方式实例化这些内置对象了,我们还是以Session为例(Session.Timeout设置获取Session的过期时间默认是20分钟,Session.SessionID获取Session的唯一标识):我们敲出Session时会通过智能提示会发现内置对象Session所属类型是System.Web.SessionState命名空间里的HttpSessionState类(按照这样看来Page类所在的命名空间一定引入了System.Web.SessionState命名空间,于是敲出Page类然后转到定义,发现果然引入了System.Web.SessionState命名空间),于是就在我自己的页面也引入了System.Web.SessionState命名空间,然后用new的方式实例化了一个Session对象: HttpSessionState mysession = new HttpSessionState();然后编译...出错(System.Web.SessionState.HttpSessionState类型未定义构造函数无法实例化),于是又转到HttpSessionState的定义,发现确实没有构造函数(不过HttpSessionState类连空构造函数都没有吗?那Page类里的Session里的get方法是怎样实例化HttpSessionState类的?补:最近通过Reflector工具发现在Page类的属性里这些内置对象是通过Context对象的属性实例化的(还有种说法是这些对象是在ASP.NET页面初始化请求时自动创建的,而无需对类进行实例化操作),Context本身也是一种内置对象,其类型是HttpContext,在下面有讲解)有类似情况的还有Application,Server等,而Request和Response等虽然有构造函数,但其构造函数的参数要求都非常苛刻。那么我们只能用敲出属性名(这些内置对象的引用)的方法来获得这些内置对象的实例吗?而在J2EE中可以通过request.getSession()的方式实例化出许多HttpSession类的实例(不过个人感觉也没必要,呵呵),在JSP里可以使用Servlet中实例化的HttpSession类的引用,也可以实例化HttpSession类(但其引用不能和Servlet中相同)而Servlet中实例化的HttpSession类的引用可以相同,如在两个Servlet中都实例化了HttpSession类且引用相同,那么修改了其中一个对象也会修改另一个对象(到了这,感觉就和ASP.NET中的Session对象不同啊,每敲出Session属性就相当于实例化一个HttpSessionState类(通过Reflector工具可以看出该类实现了ICollection和IEnumerable接口,所以其是一个集合类),而该实例的引用就是Session是一个集合的引用,所以我们可以在同一个Session里添加很多键值对)。另外我们也可以在自己的页面内敲出Page属性,通过智能提示我们可以看出Page属性是所有控件的祖先Control类(到其定义中会看到很多控件的"根属性"如ID,ClientID,UniqueID等还有我们常用的FindControl方法,返回其内部控件集合的属性Controls等)的属性,通过该属性也会返回一个Page类的实例,引用名也是Page,所以根据我们前面的分析,Page也是一种内置对象。之所以我们可以敲出Page属性是因为我们的页面继承自Page类而Page类又从Control类继承,所以其实页面也是一种控件。通过Page属性得到的是Page类的实例,而通过this关键字得到的是当前页面类的实例,所以this包含的东西>=Page包含的东西。

    2.之所以写1是因为在http://kendezhu.iteye.com/blog/745538里用到了Context这个内置对象,当时是通过httpcontext.current获得的这个内置对象,那么现在让我们来简单看一下Context(http上下文类HttpContext的实例):

    http://msdn.microsoft.com/zh-cn/library/system.web.httpcontext(v=VS.80).aspx

    1.Context.Handler(获得"传送页"的实例的引用(而且是传送页的aspx页面类的实例引用:http://kendezhu.iteye.com/blog/788770),类似于http://kendezhu.iteye.com/blog/748769的17补)(注意:Context.Handler只能通过在"传送页"使用Server.Transfer("接收页"),才能在接收页得到传送页的实例引用,而PreviousPage既能Server.Transfer("接收页")又能PostBackUrl)

    http://www.cnblogs.com/suchenge/articles/1530142.html

    传送页 D.aspx cs:

    public partial class D : System.Web.UI.Page

        {

            private string s = "我来自D";

            public string S

            {

                get { return s; }

                set { s = value; }

            }

            protected void Button1_Click(object sender, EventArgs e)

            {

                Server.Transfer("C.aspx");

            }

        }

    接收页 C.aspx cs:

     public partial class C : System.Web.UI.Page

        {

            protected void Page_Load(object sender, EventArgs e)

            {

      关于is和as:http://blog.csdn.net/kendezhu/archive/2009/12/07/4959312.aspx

    Context.Handler的方式只能用Server.Transfer()         

                if (Context.Handler is D)

                {

    要知道Context.Handler实质上就是ASP.D_aspx类,其继承自D(http://kendezhu.iteye.com/blog/788770)所以能够进行强制转换

                      D d = (D)Context.Handler;

                    Label1.Text = ((TextBox)d.FindControl("TextBox1")).Text + d.S;

                }

            }

        }

    如果有多个传送页,比如还有一个B.aspx,可以在接收页里根据不同的传输页进行不同的操作(这里用is判断是可以的,因为不同的页面是不能强制转换的,基类页与派生页是可以进行强制转换的,也就是is将返回true),而对于PreviousPage也可以在接收页里根据不同的传输页进行不同的操作:

    context.handler接收页:

     public partial class C : System.Web.UI.Page

        {

            protected void Page_Load(object sender, EventArgs e)

            {

                if (Context.Handler is B)

                {

                    B b = (B)Context.Handler;

                    Label1.Text = ((TextBox)b.FindControl("TextBox1")).Text + b.S;

                }

                if (Context.Handler is D)

                {

                      D d = (D)Context.Handler;

                    Label1.Text = ((Label)d.FindControl("Label1")).Text;

                }

            }

        }

    PreviousPage接收页:

       public partial class G : System.Web.UI.Page

        {

            protected void Page_Load(object sender, EventArgs e)

            {

    PreviousPage的方式可以用Server.Transfer(),也可以用PostBackUrl

                if (PreviousPage is E)

                {

    要知道Previous实质上就是ASP.E_aspx类,其继承自E(http://kendezhu.iteye.com/blog/788770)所以能够进行强制转换

                    Label1.Text = ((TextBox)PreviousPage.FindControl("TextBox1")).Text + ((E)PreviousPage).S;

                }

                if (PreviousPage is F)

                {

                    Label1.Text =((Label)PreviousPage.FindControl("Label1")).Text;

                }

            }

        }

    2.Context.RewritePath

    http://www.cnblogs.com/zhchongyao/archive/2009/10/21.html

    单独写貌似没有用:Context.RewritePath("Rewirtepath.aspx?w=23");

    这样写:

    Context.RewritePath("Rewirtepath.aspx?w=23");

    Server.Transfer("Rewirtepath.aspx);

    效果上等于:Server.Transfer("Rewirtepath.aspx?w=23");

    3.Context.Items(可以起到页面间传值的作用)

    http://www.cnblogs.com/barney/archive/2008/07/19/1246626.html

    比Session功能要弱一些(主要体现在Context.Items在做转页时必须用Server.Transfer,否则在接收页得不到值):

     public class Class1

        {

            public string name;

            public int age;

        }

    传送页 cs:

     protected void Page_Load(object sender, EventArgs e)

            {

                Class1 c = new Class1();

                c.name = "小刘";

                c.age = 20;

                Context.Items["person"] = c;

                Server.Transfer("接收页");

               //Response.Redirect("接收页");  用Session的话是可以的

            }

    接收页 cs:

    protected void Page_Load(object sender, EventArgs e)

            {

                if (Context.Items["person"] != null)

                {

      关于is和as:http://blog.csdn.net/kendezhu/archive/2009/12/07/4959312.aspx

                    Class1 c = Context.Items["person"] as Class1;

      也可直接粗鲁地强制转换 Class1 c =(Class1)Context.Items["person"];

                    Label1.Text = c.name + " " + c.age.ToString();

                }

            }

    值得一提的是也有Items这种内置对象,但却实现不了这种效果,必须要写Context.Items["*"]才可以。

    3.动态添加控件:http://www.cnblogs.com/ringwang/archive/2008/05/07/1187213.html

    http://www.cnblogs.com/lovecherry/archive/2005/04/16/138968.html

    http://www.cnblogs.com/chenxizhang/archive/2009/05/19/1460544.html

    http://www.cnblogs.com/blusehuang/archive/2007/04/26/728079.html(动态添加控件ID一定要不同)

    http://kendezhu.iteye.com/admin/blogs/690772

    这种添加的自然是各种服务器端控件了,样式设置可以直接在生成控件时设置也可以后来通过CSS来设置,不过关于定位问题,最好将生成的控件添加在容器控件里(如Panel,Table等),这样我们只要给这些容器控件定位就可以了。

    关于网上很多人说在回发后这些控件不见了,原因可能有两点1.写在Page_Load()里面的!IsPostBack(只有第一次请求才进行)里了(IsPostBack自然是第一次不进行,回发时才进行)2.写在控件事件里了(回发后你没有触发该事件自然不会处理了)

    还有一点很重要,在动态添加控件时要注意控件的ID一定要不同,因为服务器端与浏览器端对控件的状态(包括最重要的控件的属性值)的来回交流靠的就是viewstate(可禁)和控件状态(不可禁),而viewstate和控件状态就是根据不同控件ID及其不同属性等来分发数据的。当然只有服务器的控件的状态可以在回发后被保存(一个TextBox一个<input type="text">都被设值,回发后TextBox的值还会在),不过客户端控件也有办法:http://www.cnblogs.com/Randy0528/archive/2007/01/07/614368.html (保存客户端控件的状态的方法(以textarea为例))

    关于ViewState和控件状态:http://book.51cto.com/art/200902/109016.htm

    http://www.cnblogs.com/chenxizhang/archive/2009/04/02/1427827.html

    http://kendezhu.iteye.com/admin/blogs/752240里的

    还可以直接用Response.Wirte(客户端控件)直接往页面上输出,然后用CSS设置样式(当然这种仅限客户端控件,而且定位也要靠CSS,当然对于样式和定位的设置你也可以写在Response.Wirte里,但这样会使代码看起来很乱)

    4.一个页面使用多个表单分别提交到不同的页面

    <body>

        <form id="form1runat="server" style="border:solid 1px yellow; margin-bottom:3px;">

            <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>

            <input type="text" name="username" />

            <asp:Button ID="Button1" runat="server" Text="表单1" PostBackUrl="B.aspx" />

        </form>

        <form id="form2action="C.aspx" style="border:solid 1px yellow;" method="post">

        <input type="text" name="username" />

        <input type="password" name="password" />

         <input type="submit" name="tijiao" value="表单2"/>

        </form>

    </body>

    值得注意的是ASP.NET中一个页面中只能有一个表单有runat="server",其他表单由于没有runat="server"所以将不能使用大部分服务器端控件。 这里B.aspx只能得到form1中的值    C.aspx只能得到form2中的值。

    5.ASP.NET一些常用内置对象的使用

    用来存储信息(一般都是集合类型的内置对象):Session(HttpSessionState) Application(HttpApplicationState) Cache(Cache) 更多请参考这里Cookies的使用

    其他非集合类的内置对象的使用

    6.数据库的每一张表中只能有一个标识字段。

    7.将指定字符串按指定长度进行剪切

            <param   name= "oldStr "> 需要截断的字符串 </param> 

            <param   name= "maxLength "> 字符串的最大长度 </param> 

            <param   name= "endWith "> 超过长度的后缀 </param> 

            <returns> 如果超过长度,返回截断后的新字符串加上后缀,否则,返回原字符串 </returns> 

            public static string StringTruncat(string oldStr, int maxLength, string endWith)

            {

                if (string.IsNullOrEmpty(oldStr))

                    //   throw   new   NullReferenceException( "原字符串不能为空 "); 

                    return oldStr + endWith;

                if (maxLength < 1)

                    throw new Exception("返回的字符串长度必须大于[0] ");

                if (oldStr.Length > maxLength)

                {

                    string strTmp = oldStr.Substring(0, maxLength);

                    if (string.IsNullOrEmpty(endWith))

                        return strTmp;

                    else

                        return strTmp + endWith;

                }

                return oldStr;

            }

    注意:如果前台绑定时用到此函数<%# StringTruncat(Eval("title").ToString(),30,"...")%>,因为Eval()返回Object

    http://qun.51.com/xinchaoliu/topic.php?pid=456

    8.CSS 伪类与伪对象  具体参考CSS手册

    9.JavaScript里的this    ②

    10. JavaScript内置函数和JavaScript 对象   ②  (本地对象,就是那些官方定义好了的类的对象。内置对象是本地对象的一种,其只包含Global对象和Math对象等。而宿主对象则是那些官方未定义,你自己构建的对象加上DOM和BOM对象组成的。 )

    要使用相应的JavaScript对象才能使用相应的JavaScript内置函数。具体参考JavaScript参考手册

    11.图片放大镜效果

    CSS:

     <style type="text/css">

        #smallImgCon {position:relative;left:0;top:0;}

    #magnifierCon {height:276px;276px;position:absolute;overflow:hidden;z-index:3}

    #magnifierCon img#magnifierBg {position:absolute;z-index:2}

    #magnifierCon img#largeImg {position:absolute;z-index:1}

        </style>

    HTML:

    1  <div onmousemove="imgZoomOut(event)" id="smallImgCon"> 
    2         <img alt="" src="images/smallimg.jpg" id="smallImg"/>    
    3         <div id="magnifierCon" style="display:none"> 
    4             <img alt="" src="images/magnifier.png" id="magnifierBg"/> 
    5             <img alt="" src="images/largeimg.jpg" id="largeImg"/>    
    6         </div> 
    7     </div> 

     JavaScript:

    Js代码
     1 <script type="text/javascript">
     2     var smallImgCon = document.getElementById("smallImgCon");
     3     var smallImg = document.getElementById("smallImg");
     4     var magnifierCon = document.getElementById("magnifierCon");
     5     var magnifierBg = document.getElementById("magnifierBg");
     6     var largeImg = document.getElementById("largeImg");
     7     
     8     function getImageSize(imageEl) {
     9         var i = new Image();
    10         i.src = imageEl.src;
    11         return new Array(i.width, i.height);
    12     }
    13     
    14     function imgZoomOut(event) {
    15         magnifierCon.style.display = "block";
    16         smallImgConLocationX = smallImgCon.offsetLeft;//得到小图片X坐标
    17         smallImgConLocationY = smallImgCon.offsetTop;//得到小图片Y坐标
    18         
    19         x = event.clientX - smallImgConLocationX;//光标相对小图片左上角X坐标
    20         y = event.clientY - smallImgConLocationY;//光标相对小图片左上角Y坐标
    21         
    22         var smallSize = getImageSize(smallImg);
    23         smallImgWidth = smallSize[0];
    24         smallImgHeight = smallSize[1];
    25         
    26         var largeSize = getImageSize(largeImg);
    27         largeImgWidth = largeSize[0];
    28         largeImgHeight = largeSize[1];
    29         
    30         var magnifierSize = getImageSize(magnifierBg);
    31         magnifierWidth = magnifierSize[0];
    32         magnifierHeight = magnifierSize[1];
    33         
    34         
    35         if ( x < 0 || x > smallImgWidth || y < 0 || y > smallImgHeight) {
    36             dispear();
    37         }else {
    38             magnifierCon.style.left = x - magnifierWidth/2 + "px";//放大镜X坐标
    39             magnifierCon.style.top = y - magnifierHeight/2 + "px";//放大镜Y坐标
    40         
    41             x = - x*(largeImgWidth/smallImgWidth) + magnifierWidth/2;
    42             y = - y*(largeImgWidth/smallImgWidth) + magnifierHeight/2;
    43                         
    44             largeImg.style.left = x + "px";
    45             largeImg.style.top = y + "px";
    46         
    47         }
    48         
    49     }
    50     function dispear() {
    51         magnifierCon.style.display = "none";
    52     }
    53     </script>
  • 相关阅读:
    Chrome开发者工具详解(1)Elements、Console、Sources面板
    在Mac下运行ASP.NET Core应用程序
    网络性能优化实战
    Chrome开发者工具详解(5)Application、Security、Audits面板
    Chrome开发者工具详解(3)Timeline面板
    Chrome开发者工具详解(2)Network面板
    Chrome开发者工具详解(4)Profiles面板
    1.1专题介绍「深入浅出ASP.NET Core系列」
    1.2环境安装「深入浅出ASP.NET Core系列」
    1.3创建项目「深入浅出ASP.NET Core系列」
  • 原文地址:https://www.cnblogs.com/gates/p/3461740.html
Copyright © 2020-2023  润新知