荟萃馆

位置:首页 > 设计 > 网页设计

ASP.NET 2.0 中跨网页提交的方法有哪三种

当在一个

ASP.NET 2.0 中跨网页提交的方法有哪三种

Web页面中进行操作时,在默认情况下向当前页进行提交。这种行为在出现之前并没有什么关系,但在中当我们想向另外一个Web页提交一个Web

Form时该如何做呢?在1.0中这个问题变得很难解决,但在2.0中为开发人员提供了更容易的解决的技术:跨网页提交。这种技术允许一个网页在提交数据时提交给另外的一个页面。在跨网页提交中,用于初始化提交代码的页面叫源页面,而客户提交的页面叫目标页面。

为了方便起见,目标页面仍然获得原页面提交的所有数据。换名话说,从技术观点出发,我们可以用同样的方式处理其他页面提交的数据。

这个新特性意味着2.0开发人员目前有三种可供选择的技术来将数据从一个web页面传送到另外一个页面。这三种方法是:响应重定向,服务端传输和新的跨网页提交特性。我们可以已经熟悉前两种技术了,因此,我们只是简要地复习一下它们,然后我们会将主要精力放到学习如何使用跨网页提交特性,以及阐述一下这种方法和响应重定向以及服务传输方式有什么不同。

一、响应重定向方法

响应重定向方法是目前为止将一个网页重定向到另一个网页的最简单的方法的最简单的方法。当Web服务器接到一个重定向请求后,它会将一个响应头送给客户端,这将导致客户端发送一个新的请求到服务器。按句话说,一个重定向请求实际上是两个请求响应:一个是最初的请求响应,另一个是新的重定向请求响应。

在中实现重定向很容易。下面的代码演示了如何使用rect方法实现网页重定向:

protected

void

Redirect_Click(object

sender,

EventArgs

e)

{

rect("");

}

要注意的是重定向请求只是一个GET请求,这就意味着我们不能从源页中通过重定向命令提交数据。但是我们可以在重定向中使用查询字符串来传递数据。如下面代码所示:

protected

void

Redirect_Click(object

sender,

EventArgs

e)

{

rect("

));

}

上面的例子将一个查询字符串作为参数传递给了rect方法的目标URL。我们可以通过如下的代码获得源数据。

protected

void

Page_Load(object

sender,

EventArgs

e)

{

string

userName

Request["userName"];

}

二、服务器传输方法

和依赖于客户端向另一个新页发请求不同,服务器传输是一种服务器重定向技术,这种技术通过简单的改变Web服务器所处理的代码来达到请求一个新页的目的。当被请求页和源页面在同一个服务器时,服务器传输要比rect方法更有效,这是由于这种技术可以避免额外的开销,仅仅使用服务器的资源就可以进行重定向。要注意的这种技术有一个副作用,在页面进行重定向时,客户端的URL仍然会保持源页面的URL,这可能会使客户认为他们所获得的数据是源页面产生的。当然,在大多数情况下,这不是问题,但是这将使调试变得更困难。

sfer方法还可以保存初始页的HttpContext。因此,目标页可以访问源页面的值。我们可以使用FormsCollection属性来从目标页面中获得源页面的值。首先,要确定我们使用了被重载的方法,这个方法有两个参数:目标URL和一个Boolean类型的值,告诉服务器是否保存用于描述源页面值的Form。如下面的代码所示:

[NextPage]

sfer("",true);

然后,我们在目标页面中获得一个叫txtUserName的Textbox控件的值的代码如下:

object

obj

["txtUserName"];

三、rect和sfer的比较

由于rect方法要进行两次请求响应操作,因此,我们应该在对性能要求高的网站尽量避免使用这种方法。然而,只从技术上说,使用redirect方式确实可以从一个网页跳到另一个网页。相比之下,sfer会更有效率,但是跳转的范围仅限于同一个Web服务器的不同网页。从本质上说,我们可以使用sfer来消除不必要的请求响应操作。如果我们需要重定位到不同服务器的网页,就需要使用rect方法。

四、跨页提交概述

2.0中,我们可以通过实现IbuttonControl接口提交给不同的WebForm,来实现跨网页的提交。和rect类似,跨网页提交是一个基于客户端的传输机制,但也有点象sfer,目标网页也可以访问源网页的数据。为了使用跨网页提交,我们需要在源网页中的PostBackUrl属性中指定目标URL。

五、实现跨网页提交

这部分将讨论一下如何在2.0中实现跨网页提交。为了开始我们的学习,假设有两个Web页,一个是源Web页,另一个是目标Web页。在源网页中初始化了使用按钮进行的跨网页提交操作。我们首先必须设置目标网页按钮的PostBackUrl属性,顺便说一句,所有实现了tonControl接口的Web控件都有跨网页提交的特性。下面的代码将演示这一过程。

PostBackUrl="~/"

text

"Post

to

a

target

page"/>

当我们设置PostBackUrl属性时,框架将相应的控件绑定到一个新的叫WebForm_DoPostBackWithOptions的JavaScript函数,产生的Html代码如下:

onclick="javascript:WebForm_DoPostBackWithOptions(

new

WebForm_PostBackOptions("btnSubmit",

false,

"",

false,

false))"

id="btnSubmit"

/>

对于上面的html代码来说,当用户单击按钮时,浏览器将提交目标URL(),而不是源URL。

六、从目标页面中获得源页面控件的值

2.0提供了一个叫PreviousPage的新的属性,这个属性无论在何时当前页面进行跨网页提交操作时都会指向源页面。要注意的是,当源页面和目标页面在不同的应用程序中时,这个属性包含null(这个null并不是未初始化的意思)。还有要注意的是当目标网页访问PreviousPage属性时可以获得源页面的数据,运行时装载并执行了源页面。这将引发ProcessChildRequest事件的发生。而且,它还会引发Page_Init事件、Page_Load和任何其他的源页面按钮单击事件。

因此,我们要避免由于不小心进行误操作,所以最好通过IsCrossPostBack属性来确认是否为一个跨网页提交发生,如果这个属性值为true,那么目标网页就是通过一个跨网页提交动作而调用的。如果是通过另外一种方式调用的(如一般的请求、rect或是一个sfer),这个属性的值为false。下面的例子演示了如何使用这个属性。

if

ossPagePostBack)

{

//执行代码

}[NextPage]

这个PreviousPage属性在sfer和跨网页提交中都可以使用。在2.0中,我们可以在调用sfer操作后使用PreviousPage属性在目标页面中来获得源页面的数据,代码如下:

{

sfer("");

}

protected

void

Redirect_Click(object

sender,

EventArgs

e)

在这个接收面中我们现在可以获得Web页面的数据,代码如下:

protected

void

Page_Load(object

sender,

EventArgs

e)

{

if

(PreviousPage

null)

{

TextBox

txtBox

(TextBox)

Control("txtUserName");

if

(textBox

null)

string

userName

;

//其他可执行的代码

}

}

要注意的是上面的代码必须将txtUserName控件转换为TextBox类型,以便可以访问其中的值。

七、使用PreviousPageType

PreviousPageType属性提供了在跨网页操作中访问源页面的强类型能力,下面让我们演示一下如何不通过任何类型转换来从源页面中获得控件值。代码如下:

<

asp:Textbox

ID="txtUserName"

Runat="server"

/>

<

asp:Textbox

ID="txtPassword"

Runat="server"

/>

<

asp:Button

ID="Submit"

Runat="server"

Text="Login"

PostBackUrl=""

/>

要注意的是单击按钮可以重定向到一个叫“”的目标页。这个目标页可以使用如下的代码获得用户名和密码:

八、保存视图状态

对于跨网页提交来说,2.0

内嵌了一个叫__POSTBACK的隐藏字段,这个字段包含了关于源页面的视图信息

也就是由源页面提供了,包含了一个带有一个非空PostBackUrl属性值的服务端控件。目标页可以使用__POSTBACK中的信息来获得源页面的视图状态信息。代码如下:

if(PreviousPage!=null

&&

ossPagePostBack

&&

lid)

{

TextBox

txtBox

Control("txtUserName");

e();

}

在上面的代码中核对了用于确保PreviousPage属性不为null的检查代码。顺便提一下,如果目标页和源页面不在同一个应用程序中,这个PreviousPage属性的值为null。只有在进行跨网页提交操作时,IsCrossPagePostBack属性才为true。

这个跨网页提交的特性,是2.0中最强有力的特性之一,这种技术将允许在一个页面中提交到另外一个页面,并且可以在目标页面地无缝地操作源页面中的数据。

2.0 权限树的控制

做权限的时候,主要实现如下功能

1、该节点可以访问,则他的父节点也必能访问;

2、该节点可以访问,则他的子节点也都能访问;

3、该节点不可访问,则他的子节点也不能访问。

使用带CheckBox的数型结构能得到很好的用户体验,可是编程的难度也是有点增加,如果全部有服务端来完成,那点下刷下,肯定不行,只能使用javascript,javascript调试的时候郁闷的很,一个字类,还有郁闷的递归,麻烦

我以前是使用以下该方法

<script

language="javascript">

//oncheck事件

function

tree_oncheck(tree)

{

var

i;

var

node=reeNode(kedNodeIndex);

var

Pchecked=reeNode(kedNodeIndex)ttribute("checked");

setcheck(node,Pchecked);

setParent(node,Pchecked);

//t(Pchecked);

e

if

(hildren()th

>

0)

{

for

(i=0;i<=hildren()th-1;i++)

{

if

(hildren()[i]ttribute("Checked"))

{

AddChecked(hildren()[i]);

}

FindCheckedFromNode(hildren()[i]);

}

}

}

//设置子节点选中

function

setcheck(node,Pchecked)

{

var

i;

var

ChildNode=new

Array();

ChildNode=hildren();

if(parseInt(th)==0)

{

return;

}

else

{

for(i=0;i<th;i++)

{

var

cNode;

cNode=ChildNode[i];

ttribute("Checked",Pchecked);

//ked

Pchecked;

if(parseInt(hildren()th)!=0)

{

setcheck(cNode,Pchecked);

}

}

}

}

//设置子节点选中/取消;

//同时需要设置父节点的状态(如果是取消选中的话,仅仅设置本节点及其所有字接点,不涉及父接点)

function

setParent(node,Pc)

{

var

parentNode

arent();

if(parentNode)

{

var

parentNodeFather

arent();

if(parentNodeFather)

{

setParent(parentNode,Pc);

}

if(Pc)

{ttribute("checked",Pc);}

else

{

checkBrother(parentNode,Pc,ttribute("NodeData"))

}

}

}

//检查子接点是否有选择的,如果有一个选择了,那返回true

//只查第一级节点.

function

checkBrother(parentNode,Pc,NodeData)

{

var

childNodes

new

Array();

childNodes

hildren();

if(th

>0)

{

var

bChecked

true;

for(var

i=0;i<th;i++)

{

if(childNodes[i]ttribute("checked")

true

&&

childNodes[i]ttribute("NodeData")

NodeData)

{

//alert(i+childNodes[i]ttribute("Text"));

bChecked

false;

break;

}

}

if(bChecked)

{

ttribute("checked",Pc);

}

else

{

//所有父结点选择

setParent(parentNode,!Pc)

}

}

else

{

ttribute("checked",Pc);

}

}

//获取所有节点状态

function

FindCheckedFromNode(node)

{

var

i

0;

var

nodes

new

Array();

nodes

hildren();

for

(i

0;

i

<=

th

1;

i++)

{

if

(nodes[i]ttribute("Checked"))

{

AddChecked(nodes[i]);

}

if

(parseInt(nodes[i]hildren()th)

{

FindCheckedFromNode(nodes[i]);

}

}

}

//添加选中节点

function

AddChecked(node)

{

e

ttribute("NodeData")

}

//-->

这种方法有个很大的问题,就是他客户端设置的CheckBox在服务器端是不能获取的,现在只能在Check的时候遍历树,并把Checked的值放在一个文本里,然后提交到服务器,然后服务器来解析1@2@这种字符

现在我使用的是2.0,使用的是以下的方法

function

public_GetParentByTagName(element,

tagName)

{

var

parent

ntNode;

var

upperTagName

perCase();

//如果这个元素还不是想要的tag就继续上溯

while

(parent

&&

(perCase()

upperTagName))

{

parent

ntNode

ntNode

ntElement;

}

return

parent;

}

//设置节点的父节点Cheched——该节点可访问,则他的父节点也必能访问

function

setParentChecked(objNode)

{

var

objParentDiv

public_GetParentByTagName(objNode,"div");

if(objParentDiv==null

objParentDiv

"undefined")

{

return;

}

var

objID

ttribute("ID");

objID

tring(0,xOf("Nodes"));

objID

objID+"CheckBox";

var

objParentCheckBox

lementById(objID);

if(objParentCheckBox==null

objParentCheckBox

"undefined")

{

return;

}

if(ame!="INPUT"

&&

"checkbox")

return;

ked

true;

setParentChecked(objParentCheckBox);

}

//设置节点的'子节点uncheched——该节点不可访问,则他的子节点也不能访问

function

setChildUnChecked(divID)

{

var

objchild

dren;

var

count

th;

for(var

i=0;i<th;i++)

{

var

tempObj

objchild[i];

if(ame=="INPUT"

&&

"checkbox")

{

ked

false;

}

setChildUnChecked(tempObj);

}

}

//设置节点的子节点cheched——该节点可以访问,则他的子节点也都能访问

function

setChildChecked(divID)

{

var

objchild

dren;

var

count

th;

for(var

i=0;i<th;i++)

{

var

tempObj

objchild[i];

if(ame=="INPUT"

&&

"checkbox")

{

ked

true;

}

setChildChecked(tempObj);

}

}

//触发事件

function

CheckEvent()

{

var

objNode

lement;

if(ame!="INPUT"

!="checkbox")

return;

if(ked==true)

{

setParentChecked(objNode);

var

objID

ttribute("ID");

var

objID

tring(0,xOf("CheckBox"));

var

objParentDiv

lementById(objID+"Nodes");

if(objParentDiv==null

objParentDiv

"undefined")

{

return;

}

setChildChecked(objParentDiv);

}

else

{

var

objID

ttribute("ID");

var

objID

tring(0,xOf("CheckBox"));

var

objParentDiv

lementById(objID+"Nodes");

if(objParentDiv==null

objParentDiv

"undefined")

{

return;

}

setChildUnChecked(objParentDiv);

}

}这种方法最大的好处就是服务端能得javascript设置的Checked的值,不用没点下就全部把树遍利下,直接在服务端遍利一次就行了

//遍历子节点

public

void

GetChildNode(TreeNode

Node)

{

foreach

(TreeNode

node

in

dNodes)

{

if

(ked)

{

StrChecked

e+"@";

}

GetChildNode(node);

}

}

我照样能得到它的Check的值

2.0中XML数据的处理

SqlDataSource和ObjectDataSource控件都是平面表格式的数据源控件,操作也相对简单,在这里我就不细说了.

在这里我主要谈下用于连接XML文件的XmlDataSource和用于连接站点导航数据的SiteMapDataSource这两个层次数据源控件中XmlDataSource数据绑定到平面表格控件的一起东东.

XmlDataSource控件允许其它控件绑定到XML数据。XmlDataSource支持DataFile属性,它被用于指定作为输入(input)的XML数据文件的路径。你还可以指定TranformFile属性,给数据应用XSLT转换;设置XPath属性来指定需要暴露的数据源节点的子集。

<asp:XmlDataSource

ID="myXmlDataSource"

runat="server"

DataFile="~/"

TransformFile="~transXml"

XPath="//User">

表格式数据绑定控件绑定到分层数据源也是可行的,但是它只能显示第一层数据。在下面的demo中,Repeater控件绑定到

文件。由于数据源暴露的顶层节点是<User/>节点,Repeater可以在自己的ItemTemplate模板中使用Eval数据绑定语法绑定到这些节点的属性。

<asp:Repeater

runat="server"

ID="myReater2"

DataSourceID="myXmlDataSource">

标题

姓名:<%#

Eval("Name")

%>

Email:<%#

Eval("Email")

%>

除了Eval数据绑定语法之外,

2.0还提供了基于XPath的数据绑定语法,在实现了IXPathNavigable接口的任何数据项上都可以使用它。这里介绍两种常用的表达式类型:

XPath(expression,

[formatString])

根据数据项计算Xpath表达式的值,返回单个值。

XPathSelect(expression,

[formatString])

根据数据项计算Xpath表达式的值,返回节点列表。

下面我们来看看使用Xpath数据绑定方法的优势,通过一个demo来说明.

Repeater的ItemTemplate模板另外增加了一个Repeater,并把这个内部Repeater的属性绑定到一个描述当前User节点的Reply子节点的XPathSelect表达式。在内部Repeater的ItemTemplate模板中,Xpath数据绑定表达式根据这些"Reply"内容节点来计算值。

2.0利用这种技术,使你能够通过组合表格式数据绑定控件简便地构造出丰富的、分层的数据显示方式。

<asp:Repeater

runat="server"

ID="myRpeater"

DataSourceID="myXmlDataSource">

标题

ID:<%#

XPath("@ID")

%>

姓名:

Email:

Content:

<asp:Repeater

runat="server"

ID="childRepeater"

DataSource='<%#

XPathSelect("Reply")

%>'>

留言

ReplyID:<%#XPath("ID")

%>

Time:<%#

XPath("Time")

%>

Content:<%#

XPath("Content")

%>

使用 2.0中的ReportViewer控件

介绍

任何数据驱动型的应用程序都有一个普遍的需求,那就是报表。

但是,在

1.x中并没有给我们提供这个非常重要的特性。

然而很幸运的是,伴随着。NET

2.0而来的ReportViewer控件可以满足你对报表的一些基本需求。

我将会在本文中向你演示如何使用这个控件。

ReportViewer控件既可以在web程序中使用,也可以在windows程序中使用。

在这里,我将只介绍如何在web程序中使用它。

报表示例

我们假设要生成一个如下所示的顾客信息列表:

上面的报表是一个非常简单的以国家分组的顾客信息列表。

报表的数据是从Northwind数据库的Customers表里获取的。

默认情况下,它会显示所有的顾客信息。

但是,你也可以让它显示属于你指定的某个国家的顾客信息。

该报表是使用ReportViewer控件设计的,它可以从强类型的DataSet中或者自定义的对象集合中获取数据。

在实际的程序开发中,我们往往会使用3层架构,数据的获取经常会是从业务层取得的DataSet或一个泛型集合。

在这里,我打算使用一个泛型集合作为数据源,而不是强类型的DataSet.

创建类库

首先,打开Visual

Studio,然后创建一个名为ReportViewerLib的类库项目。

添加一个如下所示的名为Customer的类:

using

System;using

;using

iguration;using

lient;using

ric;namespace

ReportViewerLib{

public

class

Customer

{

public

string

strCustomerID;

public

string

strCompanyName;

public

string

strContactName;

public

string

strCountry;

public

string

CustomerID

{

get

{

return

strCustomerID;

}

set

{

strCustomerID

value;

}

}

public

string

CompanyName

{

get

{

return

strCompanyName;

}

set

{

strCompanyName=

value;

}

}

public

string

ContactName

{

get

{

return

strContactName;

}

set

{

strContactName=

value;

}

}

public

string

Country

{

get

{

return

strCountry;

}

set

{

strCountry=

value;

}

}

public

static

List

GetCustomersForCountry(string

country)

{

SqlConnection

cnn=new

SqlConnection(

ectionStrings["NorthwindConnectionString"]ectionString);

SqlCommand

cmd=new

SqlCommand();

ection=cnn;

andText="select

CustomerID,CompanyName,ContactName,Countryfrom

customers

where

country=@country";

SqlParameter

p=new

SqlParameter("@country",country);

(p);

();

SqlDataReader

reader

uteReader();

List

list

new

List();

while

(())

{

Customer

c

new

Customer();

omerID

tring(0);

anyName

tring(1);

actName

tring(2);

try

tring(3);

(c);

}

e();

return

list;

}

public

static

List

GetAllCustomers()

{

SqlConnection

cnn

new

SqlConnection(

ectionStrings

["NorthwindConnectionString"]ectionString);

SqlCommand

cmd

new

SqlCommand();

ection

cnn;

andText

"select

CustomerID,CompanyName,ContactName,Country

from

customers";

();

SqlDataReader

reader

uteReader();

List

list

new

List();

while

(())

{

Customer

c

new

Customer();

omerID

tring(0);

anyName

tring(1);

actName

tring(2);

try

tring(3);

(c);

}

e();

return

list;

}

}}

123456下一页

GOvar

pager=new

iwmsPager(1,6,true);

[新品]指纹私密 CECT超薄手写S10低价到货! 01-08 -

指纹手机,这一新兴的手机功能在CECT

T100的强势上市后被广大机友所熟知并喜爱起来,而借着这顺风顺水的人气,CECT又推出了一款指纹安全手机S10,它可以轻松实现六大指纹安全功能:指纹加密、指纹隐形、指纹防盗、指纹鼠标、指纹拨号和指纹动作。而CECT

S10的整体表现会不会如T100一样带给我们无限惊喜呢?请机友们跟随汀汀的文字一起去解一下吧,说不定你会在瞬间选中它!

作为热卖机型CECT

T100的升级版本,CECT

S10在外形上略作修改,但更显精练轻巧,商务气息依然浓郁。而直板PDA手机风格造型的S10三围尺寸为113×54×11mm,做工精良,超薄的机身秀气中不乏端庄。屏幕方面,CECT

S10拥有一块26万色的TFT屏幕,分辨率为目前主流的320*240像素QVGA分辨率,采用触摸式设计,支持手写、键盘双输入方式,并支持大字体拨号。

娱乐方面,CECT

S10具有实时流媒体播放,MP3和MP4播放器,录音机、卡拉OK等功能,而内置的任天堂游戏模拟器,附送游戏高达2000个。在摄像头方面,S10内置130万像素CMOS摄像头,最大支持640*460分辨率的照片拍摄,支持数码变焦、三种照片质量等拍摄模式,并支持有声视频拍摄!此外,CECT

S10还能方便上网和收发电子邮件,内置资讯时空包括SMS、MMS、IVR、WAP四大类约160个应用。同时,S10还支持大容量T-FLASH扩展存储卡,并可做U盘使用。

强大的指纹识别和保密功能是CECT

S10的突出特色,它通过指纹加密、指纹隐形、指纹防盗、指纹鼠标、指纹拨号和指纹动作这些功能巧妙地把私密信息保护、通信信息隐藏、通信人身份隐藏与快捷操作方式相结合,使用起来不仅令人放心而且舒心,不会担心因不慎导致的个人信息泄露。另外,S10的电话簿容量为1000个,可以多种方式进行索引,支持群组功能,短信息容量高达400条,足以保留足够多的个人短息和商务短信。

纵观CECT

S10的整体表现,它的主要卖点是集中在QVGA分辨率的26万色TFT屏幕、支持手写键盘双输入、娱乐游戏扩展功能以及最为可圈可点的指纹识别和保密功能。而以上的这些卖点再配以目前北斗手机网699元的售价就更是划算至极了,喜欢的机友没有理由不选它哦!

[新品]拍照新旗舰 500W索爱K858c盛情上市! 01-08 -

拍照手机的迅猛发展是时代大环境所需,同时也出乎了很多人的意料!如今200万像素已经成为了新机上市的家常便饭,320万像素可以和主流手机贴贴边,500万像素才是真正的大势所趋!在看过了其它厂家的500W像素新机上市后,索尼爱立信Cyber-shot品牌下的拍照悍将K858c也终于闪亮登场了,欢迎已经迫不急待想熟知它一切功能的机友和汀汀一起对K858c来个从头至尾的了解,它的强大功能定会令你不由自主的倾心于它!

索爱K858c采用索爱最拿手的直板式造型设计,机身线条笔直硬朗,酷劲十足,尤其是采用黑色为主色调更增强了它的视觉冲击力。在色彩搭配选择上,除了经典的黑色外,K858c的功能键、镜头部分和LOGO标签都是采用银色点缀,再配上眩目的绿色方向导航键和机身周边装饰条,非常惹眼。屏幕方面,K858c采用了一块2.2英寸的26万色TFT显示屏幕,分辨率达到了QVGA级别(240×320像素)。依照索尼爱立信公司的一贯作风,K858c的屏幕显示非常优秀,画面细腻度和文字锐度表现得近乎完美。

索爱K858c的背面设计融入了相机血统,采用双面卡片DC设计原则,所配备的500万像素镜头支持自动对焦、氙气闪光灯、16倍数码变焦等丰富影像功能,完全采用Cyber-shot数码相机的操作界面,影像菜单比以往更加直观,DC感更加强烈。另外,Best

Pic、Photo

fix等优化软件的运用也令照片趋于完美。

索爱K858c内置MP3播放器具备WALKMAN独有的Mega

Bass音效,支持蓝牙2.0,A2DP标准,配合高质量蓝牙立体声耳机,效果震憾。此外,K858c除了拥有40MB机身内存外,还创造了一个行业第一,它不仅支持M2卡,同时还支持Micro

SD卡的扩展,而且两个存储卡的扩展都使用一个插槽,不同的只是插卡的方向。

这一场由索爱K858c所引爆的拍照风潮正向我们袭来,它的整体表现足以成为拍照手机领域里的新旗舰,并有能力与其它各大品牌的500万像素手机相抗衡!北斗手机网4280元的上市售价也算厚道,欢迎有实力尝鲜的机友们先用为快,来体验一下K858c所释放出来无穷魅力!

标签:aspnet 网页 提交