首页 > 学院 > 开发设计 > 正文

如何在ASP.NET环境中建立基于WML的站点

2019-11-17 04:07:38
字体:
来源:转载
供稿:网友
<!-- /* Font Definitions */ @font-face {font-family:Wingdings; panose-1:5 0 0 0 0 0 0 0 0 0; mso-font-charset:2; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:0 268435456 0 0 -2147483648 0;} @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} h1 {mso-style-next:正文; margin-top:17.0pt; margin-right:0cm; margin-bottom:16.5pt; margin-left:0cm; text-align:justify; text-justify:inter-ideograph; line-height:240%; mso-pagination:lines-together; page-break-after:avoid; mso-outline-level:1; font-size:22.0pt; font-family:"Times New Roman"; mso-font-kerning:22.0pt;} PRe {margin:0cm; margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:12.0pt; font-family:宋体; mso-bidi-font-family:宋体;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:36.0pt; mso-footer-margin:36.0pt; mso-paper-source:0;} div.Section1 {page:Section1;} -->

一、 asp.net 环境下实现手机浏览页面的几种方法
    
ASP.NET
本身就提供了对Mob
ile
页面的支持,只要页面继承这个对象就可以了:“System.Web.UI.MobileControls.MobilePage
”。但是由于其目标宏大,为了在各种设备的请求下有相应的回应,需要作出各种不同的回应,因此需要很复杂的配置。而且为了应对不支持Cookie
的设备,需要在有Cookie
和无Cookie
的会话管理方式中切换,此时涉及到相对URL
时就会出现很大的问题。当前许多站点的手机页面和Internet
页面是放在同一个web
服务器下的,这无疑将影响Internet
页面的会话管理方式。

  

    现在还有很多工具和嵌入式平台(如 QuickWAP )可以用来很便利地实现 WAP 页面,这些平台一般都因为能够提供一定的便利性(如控件、状态管理等)而流行,笔者不是不建议大家使用,而是希望我们做软件的,能够知其然亦知其所以然,还是要花些时间在 wml 和 xhtml 上(就和普通 aspx 网页,也不要满足于在设计模式下拖拽控件,而是要习惯于直接编写 html 和 CSS 代码一样)。

  

我们自己生成 WML 文档并 Response 回去,其原理相当于在普通 aspx 页面中,我们不拖拽控件,而是直接 Response.Write(“<html><head><title>hello</title></head><body>Hello world</body></html>”); 一样,而且不需要任何其他配置。

二、服务器端生成 xml 文档的方式来生成页面
为了支持绝大多数的手机用户,我们只能使用最基本的 wml1.1 语法来生成文档。一个 wml 文档,就是一个合法的 xml 文档,要了解 wml 语法, “ OReilly Learning WML & WMLScript.pdf ”这本书给出了比较详尽的讲述。这里仅就基本结构、常用的链接、图片、段落等给出一些事例,能看懂 html 代码的人应该也能看懂是什么意思。

<?xml version="1.0"?>

  <!DOCTYPE wml PUBLIC      "-//WAPFORUM//DTD WML 1.1//EN"

     "http://www.wapforum.org/DTD/wml_1.1.xml">

  <wml>

     <card title=" 标题 ">

         <p> 段落 1</p>

<!— 图片的 width 和 height 属性一般仅用来提示浏览器在图片装载之前保留适当位置,如果这与图片实际大小不符,将可能被忽略 . -->

<p><img src="img/pic.wbmp" alt=" 图片示例 "/></p>

<!— 和 html 里一样,注释 . -->

<setvar name="variable1" value=" 变量 variable1 的值 "/>

<setvar name="v2" value="v2"/>

<!— 下面这个是输入框,和上面的变量 v2 都用来作为 QueryString 的一部分 -->

<input name="input1" size="18" emptyok="true"/>

<!— 下面这个 anchor 内有个 go ,除了自身的 arg1 外,还有来自 v2 的 arg2 和来自 input1 的 arg3 ,假设用户点击“搜索”时输入框内的文字为 abcd ,则页面跳转到 test.aspx?arg1=1&arg2=v2&arg3=abcd ,这样就实现了基本的百度搜索功能了 à

<anchor>

<go href="test.aspx?arg1=1" method="get">

<postfield name="arg2" value="$(v2)"/>

<postfield name="arg3" value="$(input1)"/>

</go> 搜索

</anchor>

<input name=”passWordInput1” type=”password”/>

  

<!— 本段落演示登录页 . -->

<p>

<p>Username: <input name="user" format="*x"/></p>

<p>Password: <input name="pass" type="password"/></p>

    <do type="accept" title="Log In">

       <go href="login.aspx?u=$(user:e)&amp;p=$(pass:e)"/>

    </do>

</p>

  

<!— 本段落演示下拉框 . -->

<select name="airport">

     <option value="LHR">London Heathrow</option>

     <option value="LGW">London Gatwick</option>

     <option value="STN">London Stansted</option>

      <option value="LCY">London City</option>

     <option value="LTN">London Luton</option>

  </select>

  

<!— 普通的链接 . -->

<a title=" 链接 1" href="testPage2.aspx"> 点击我来跳转页面 </a>

  

<!— 和 html 一样功能的换行 . -->

<br/>

  

<!— 下划线、粗体和斜体 . -->

<p align="left">

  Some text with bits in <b> 粗体 </b> and <i> 斜体 </i> and <u> 下划线 </u>.

  </p>

     </card>

  </wml>

  

看懂了上面的示例,我们就有能力创建一些普通功能的页面了。由于绝大部分应用的页面都是动态的,我们需要动态地生成 wml 文档。生成 xml 文档有多种方式,可以用 System.Xml.XmlDocument 、可以用字符串拼接( StringBuilder )、 System.Xml.XmlTextWriter 以及使用 System.Xml.Linq.Xdocument 。基于性能和便利性结合考虑,推荐使用 XmlTextWriter 来生成页面 xml 文档。

protected void Page_Load(object sender, EventArgs e)

    {

        Response.ContentType = "text/vnd.wap.wml";

MemoryStream ms = new MemoryStream();

        Encoding ec = new System.Text.UTF8Encoding(false);

        StreamWriter sw = new StreamWriter(ms, ec);

        XmlTextWriter xtw = new XmlTextWriter(sw);

  

        //xtw.Formatting = Formatting.Indented;

        xtw.WriteStartDocument();

  

        xtw.WriteDocType("wml", wmlUsage.s_wmlPubId, wmlUsage.s_wmlSysId, null);

         xtw.WriteStartElement("wml");

  

        wmlUsage.WriteWmlHead(xtw);

  

        xtw.WriteStartElement("card");

        xtw.WriteAttributeString("id", "home");

        xtw.WriteAttributeString("title", " 标题 ");

        xtw.WriteStartElement("p");

        xtw.WriteStartElement("img");

        xtw.WriteAttributeString("src", "images/logo.jpg");

        xtw.WriteAttributeString("alt", " 网站 logo");

        xtw.WriteEndElement();

        xtw.WriteElementString("br", null);

  

// 在这里生成页面其他信息,最后要让每个 WriteStartElement 都有一个 WriteEndElement

// 与之对应

  

xtw.WriteEndElement();

        xtw.WriteEndElement();

  

        xtw.WriteEndDocument();

  

        xtw.Flush();

        sw.Flush();

  

        string str = Usage.GetStreamString(ms, ec);

        Response.Write(str);

        sw.Close();

try

        {

            Response.End();

        }

        catch

        {

        }

}

  

  

三、如何解决图片显示问题
    手机客户端对图片的支持良莠不齐,且很多 wap 浏览器都不支持图片的大小设置,这样就要求我们对过大的图片进行设置。 .net Framwork 提供的 System.Drawing 命名空间内有很多对图像处理的类,使用 System.Drawing.Bitmap 就可以轻松实现生成新大小的图片。具体请查看 msdn 。

  

四、如何解决用户状态相关问题
很多应用都要求手机用户也能支持用户登陆、购物车等会话相关的功能。在 Internet 网页中,一般都是使用 session 或 Profile 来实现的。手机页面,为了保证最大程度的通用性,不应该再依赖于 Session 和 Profile 。本文提供一种基于 URL 的方法。

该方法原理很简单,为每个需要存储相关登陆状态的用户生成全局唯一的 ID ,并将此 ID 以明文或加密的方式存放在返回给用户的每个 URL 中,作为 QueryString 的一部分。这样用户进行任何操作后,再次与服务器通信时,服务器都可以通过这个 ID 来识别该用户。

<a href=”test.aspx?uid=11223344”> 点击进入测试页面 </a>

在服务器端,提供一个通用的用于识别用户的对象 IdentitiVerification ,页面把当前的 Request 对象传入,就能够得到相关请求用户的相关信息( UserInfo ) :

  

public class UserInfo

    {

        public string ID { get; set; }

        public string Name { get; set; }

        public bool IsAnnonymous { get; set; }

        public ShppingCart Sc { get; set; }

        public string IdentityID { get; set; }

    }

  

  

大部分页面的处理模式:

protected void Page_Load(object sender, EventArgs e)

    {

        UserInfo ui = IdentitiVerification.GetUserInfo(Request);

        if (ui.IsAnnonymous)

        {

            // 未登录用户的页面生成

        }

        else

        {

            // 已登录用户

        }

        // 在可能与服务器通信处的链接,都加上 String.Format("xxx.aspx?uid={0}", ui.IdentityID) 字样。

        ...

  

}

  

  

注 1 :   如果网页页面程序使用 Profile 来存储用户信息,那么这个 UserInfo 基本上可以与之通用。

注 2 :   用户信息与 ID 对照表可使用 ASP.NET 全局缓存来保存。

注 3 :   为了安全性考虑,生成的 ID 应该复杂且不可被猜测、没有上下文相关信息、最好也没有用户相关信息。建议使用 GUID 之类无上下文信息生成技术。同时 ID 不能太短,以免被人手工改动试出。 IdentitiVerification 对象还应该具有一些基本的智能识别攻击的技术(比如某段时间频繁调用 GetUserInfo 方法时,传入的 id 都是不存在的,这时基本可以判定有人在恶意攻击,应对 Request 对象进行日志记录并通知管理员等)。

注 4 :   为了性能考虑, IdentitiVerification 应具有对长时间无动作的存储 ID 进行清除操作。 
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表