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

 

<!-- /* 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 进行清除操作。

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值