您的位置:首页 > 编程语言 > ASP

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

2009-11-01 14:41 441 查看
<!--
/* 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)&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
进行清除操作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: