msgbartop
Somethings you can’t control,just go ahead
msgbarbottom

16 Aug 07 穿1.0的鞋,走2.0的路

已经大半年没有运动过,其实不是不想动,而是好多因素的制约让想法一直停留在想法。
最近下定决心要把以前曾经打过大半年的羽毛球运动恢复起来,于是特意做了计划,每周二四。同时开始找人,同事朋友加起来,能玩到一起的到目前为止也就7,8个,但不是不打,就是离的远,距离近又打球的就那么一两个,还要时不时的被约会之类的“人祸”所阻挠。到现在一个月下来真正能去打的也就一次。所以我决定网上去找球友,这一搜不光搜出了球友,还搜出了之前没听过更没见过的—圈网

之所以能注意到圈网是因为Google了一下,找了7,8个有组织打球信息的链接进去,竟然发现有3,4个来自同一家网站。Google一下,圈网2004年就已经成立,在Web2.0站点里算的上是“老人”了,圈网成立的时候我还没接触到2.0的概念,也许圈网被”IT尝鲜症候群“疯狂谈论的时候(不知道这种情况是否曾经出现过),我还没完全搞懂RSS是什么东西,当我开始关注2.0了,圈网是否又成了昨日黄花?以至于不搜都不知道。

在圈子里来来回回,上上下下逛了几个小时,“博客” “相册” “好友” “最近访客”…一个感觉—大众脸,现在的SNS网站几乎都长这样。

同时也发现一个问题,里边的圈子有很多,人也不少,但活跃程度好像普遍不怎么样。首页有个栏目“热门话题”,但回复数量平均下来每个话题最多5~6个,相当多的是1/0,这样的话题如何称得上“热门”?因此,我得到的结论是,这不是什么热门话题,应该改叫“最近话题”,凡是这两天发的话题都是“热门”,可即便是这样,总的“热门话题”数也只有区区250条左右。

这个数字和圈网截止06年3月160W的注册用户显然不成比例。用户的“有兴趣”造就了网站庞大的注册用户数,服务内容的“不实用”又让庞大的注册用户仅是一面之缘。

为什么说服务内容不实用?
1,SNS的核心是人,人以类聚。虽然不同的小圈子似乎给大家分了类,但让不同类别的人呆都呆在同一个“大圈子”里,那也是不现实的。
2,网站的内容导向。前边写过一篇文章探讨网站的气质与文化氛围,内容决定氛围,氛围决定气质。作为2.0 UGC内容的网站,什么样的用户,生产什么样的内容,什么样子的内容,决定网站什么样的氛围与气质。如果所有类别的用户都有,那么文化氛围与气质就没了。

文化氛围与气质是SNS站点的灵魂,没有了这个,何来用户忠诚度?你的产品大而全,但没有一个能拿的出来跟别人专业的小站点单挑,用户有什么理由非留在你这里?

又回到了当初门户的时代,当门户们一个个建立起来之后,包罗万象的内容让它们看起来很有“面子”,但似乎有很多东西也就停在了面子上,想从门户中挖一些更深点的东西出来好像有点难,因此“垂直”站点出来了。

到了2.0时代,似乎门户热情又重新燃起,“包罗万众”是很多2.0站点追求的目标。但市场永远是理智的,市场不会去迎合概念,2.0们只能去适应市场—细分,才是最终的出路。

看看1.0们走过的路,路之所以这样走是它一定的有道理的。

光脚跑不但脚会痛,而且跑不快,在2.0们还没有“新鞋”的时候,就先把1.0的鞋子穿上,让自己的路走的更快些。

Tags:

09 Aug 07 BlogEngine.NET皮肤制作

自己试着改了个BlogEngine.NET的皮肤,主要是想通过修改皮肤的过程熟悉BlogEngine.NET的程序结构,作为Asp.net学习的一个途径。

原皮肤:Leaves

修改:

1,更改了原有的三栏布局
2,部分css的修改(链接颜色,字体等)
3,修改了postfooter的布局
4,更改postview以发布日期为主标题显示

还有一些想增加的功能:

1,last posts
2,recent comments
3, ……

Tags:

08 Aug 07 Microsoft Founding Team

Mr.6在文章《周一下午,為何我們要看CD-PRO2?》中的插图。就是这帮人缔造了微软。

Tags:

07 Aug 07 从QQ MSN and Gtalk看2.0网站的用户定位

Web2.0时代的到来,让之前一直蜗居在“网”后的广大用户们有机会来了个“华丽的转身”,跳到了互联网的前台。而网络公司们则成了“幕后工作者”,用尽浑身解数,只为让这个舞台能引来更多的“舞者”。

这时候,如何吸用户过来,并留住它们,便成了一个让人头痛的问题。

每个网站都有自己独特的一面,不同的特点形成了不同的气质,这个气质可能来自站点创办者个人,可能来自这个站点建站之初就确立的鲜明定位,也可能来自最初具体在这里的几个用户……不论来自哪里,每个能坚持存在的站点都有自己明显的或是不怎么明显,但被大家默认的“文化氛围”。这种气质对于2.0网站来讲是十分重要的,它决定了哪些人会来你的网站,哪些人会留在你的网站。

中国目前拥有总数庞大的网民,如果要对整个的网民进行一下分类,还真是一件不容易的事情,如何分呢?既然要分类,就必须找到一个每个人都拥有的“属性”,这个“属性”是什么呢?我觉得让IM软件来做这个分类的标准再合适不过了。你也许不玩网游,你也许不泡论坛,你也许根本不知道博客是怎么回事,但我相信你一定在使用某个IM软件。

所以,按照IM软件,我们大致可以把网民分为QQ们,MSN们和Gtalk们。分类的意义就在于,属于同一类的人必然有着共同的特点,我们可以就这个共同的特点对这类人进行研究。

QQ们:这是一个人数最为庞大的群体,我相信98%以上的网民都有这个东西,现在有没有在用是另外一回事。从年龄层面看QQ用户基本为年轻人(大学毕业之前的年龄段),从文化层面看,这群用户的整体平均文化水平不高。

MSN们:这群人年龄段主要集中在23岁(大学毕业)以上,从文化层面看,整体平均文化水平较高。这群人希望与众不同,喜欢强调品味。

Gtalk们:我在之前的blog中给这帮人取了个名字叫“IT尝鲜症候群”。它们是站在互联网风口浪尖的一批人,是互联网风潮的导向。这帮人对MSN们可以产生很大的影响,但对QQ们的影响似乎很微弱。

这是三个有着截然不同“气质”的群体,要把他们放到一个锅里煮,结果必然是哪个也煮不熟,锅反而给煮坏了。2.0网站的核心是用户,所以我们在建立一个网站的时候首先考虑到的就应该是用户群体的定位。大虾小虾都抓是不现实的,我们必须选择。

3类用户,2类是有商机的。没商机的那类是Gtalk,这是对互联网十分了解的一批人,是各种新潮流的追随者,各种新应用的尝试者,等一个应用能发展到“收费”阶段,那这个地方对这帮人来说吸引力就不大了,更别指望这帮人能再money上对你的网站做出什么贡献,它们所能贡献的就是给你网站一个不错的评价,然后引来更多的人。

选择的过程是痛苦的,但不加选择的结果也必定是痛苦的。

可以拿国内两个比较有代表性的2.0网站,豆瓣和51.com,做一个设想。如果豆瓣的用户(这里的用户指的是非边缘用户)来到51,我相信他也就逛逛,是不会呆下去的,也呆不下去。如果51的用户来到豆瓣,我相信他同样也就逛逛,同样不会呆下去,同样也呆不下去。

Tags: ,

06 Aug 07 20块

Blogool对俺的博客的定价-20块

Tags:

04 Aug 07 Asp.net Study(17)

Panel & PlaceHolder控件的使用

Panel控件的属性:Visible,BackImageUrl,HorizontalAlign,Wrap

PlaceHolder控件在定义时不能向其中添加子控件,添加工作必须在程序中完成。这正是PlaceHolder控件存在的意义,可以根据程序的执行情况,动态的添加需要的控件,而Panel控件则不具体动态添加的功能。

PanelandPlaceHolder.aspx代码:

<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”PanelandPlaceHolder.aspx.cs” Inherits=”PanelandPlaceHolder” %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<html xmlns=”http://www.w3.org/1999/xhtml” >
<head runat=”server”>
<title>无标题页</title>
</head>
<body>
<form id=”form1″ runat=”server”>
<div>
<asp:Panel ID=”Panel1″ Wrap=true HorizontalAlign=Right runat=server>
<asp:Label Text=”This is first” runat=server/>
</asp:Panel>
<asp:Panel ID=”Panel2″ Wrap=true HorizontalAlign=Center runat=server>
<asp:Label Text=”This is second” runat=server/>
</asp:Panel>
<asp:Panel ID=”Panel3″ Wrap=true HorizontalAlign=Left runat=server>
<asp:Label Text=”This is third” runat=server/>
</asp:Panel>
<hr>
<asp:PlaceHolder ID=”Holder” runat=server/>
<hr>
Please choose the panel that you want:<br>
<asp:DropDownList ID=”DropDown” OnSelectedIndexChanged=”Selected” AutoPostBack=true runat=server>
<asp:ListItem>Panel1</asp:ListItem>
<asp:ListItem>Panel2</asp:ListItem>
<asp:ListItem>Panel3</asp:ListItem>
</asp:DropDownList>
</div>
</form>
</body>
</html>

PanelandPlaceHolder.aspx.cs代码:

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Drawing;

public partial class PanelandPlaceHolder : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
Panel1.Visible = false;
Panel2.Visible = false;
Panel3.Visible = false;
}
}
public void Selected(object sender, EventArgs e)
{
Panel p = (Panel)FindControl(DropDown.SelectedItem.Text);
p.Visible = true;
p.ForeColor =Color.Red;

string selindex = DropDown.SelectedIndex.ToString();
Label lbl = new Label();

switch (selindex)
{
case “0″:
lbl.Text=”You selected Panel1″;
break;
case “1″:
lbl.Text=”You selected Panel2″;
break;
case “2″:
lbl.Text=”You selected Panel3″;
break;
default:
lbl.Text=”You haven’t selected anyone”;
break;

}

Holder.Controls.Add(lbl);

}
}

Tags:

04 Aug 07 Asp.net Study(16)

文件上传

利用HtmlInputFile控件进行文件上传

用到的属性:PostedFile

HttpPostedFile是System.Web命名空间中的一个类,它的属性和方法包括:ContentLength,ContentType,FileName,InputStream,SaveAs

1,首先通过HtmlInputFile控件的PostedFile属性建立HttpPostedFile实例
2,通过HttpPostedFile的FileName属性取得文件名
3,通过HttpPostedFile的SaveAs方法进行保存
同时可以通过ContentLength,ContentType属性取得文件长度和文件类型。

代码(用code-behind进行代码分离):

说明:亲密接触Asp.net教材中提到,使用Code-behind进行代码分离时要在.cs文件中对主文件中的Html控件进行声明。但实践发现,使用vs2005创建web form后vs会自动进行主文件和后台.cs文件的关联,不需要特别声明。

DoUpload.aspx代码:

<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”DoUpLoad.aspx.cs” Inherits=”DoUpLoad” %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<html xmlns=”http://www.w3.org/1999/xhtml” >
<head runat=”server”>
<title>无标题页</title>
</head>
<body>
<form id=”form1″ enctype=”multipart/form-data” runat=”server”>
<div>
Please choose the file that you want to upload:<Input type=file id=”UpLoadFile” runat=server><br>
<Input type=submit value=”UpLoad” onserverclick=”UpLoad” runat=server>
<hr>
Uploaded filename:<asp:Label ID=”FileName” Text=”UnUpload” runat=server/><br>
File size:<asp:Label ID=”FileSize” Text=”UnUpload” runat=server/><br>
Real Filename:<asp:Label ID=”rFileName” Text=”UnUpload” runat=server/><br>
File Type:<asp:Label ID=”FileType” Text=”UnUpload” runat=server/><br>
Content of InputStream:<asp:Label ID=”InputStream” Text=”UnUpload” runat=server/>
</div>
</form>
</body>
</html>

DoUpload.aspx.cs代码:

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class DoUpLoad : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
UpLoadFile.MaxLength = 5300493;
UpLoadFile.Size = 20;
}

public void UpLoad(object sender, EventArgs e)
{
HttpPostedFile hpf = UpLoadFile.PostedFile;
FileName.Text = hpf.FileName;
FileSize.Text = hpf.ContentLength.ToString();
FileType.Text = hpf.ContentType.ToString();
InputStream.Text = hpf.InputStream.ToString();

char[] de ={ ‘\\’ };
string[] AFileName = hpf.FileName.Split(de);
string strFileName = AFileName[AFileName.Length - 1];
rFileName.Text = strFileName;

hpf.SaveAs(Server.MapPath(”.”) + “\\UpLoadFile\\” + strFileName);
}
}


问题点:在测试的时候发现,大文件上传时会出错。google了一下思归提供了解决办法,但作为一个初学者,没有完整的代码,看不大懂。

下边是在itepub.net里有完整代码的解决办法,原文地址:http://www.itepub.net/html/kaifajingcui/Asp_Net/2006/0828/41240.html
在这里保存一下,以后查阅起来方便点。

利用隐含的HttpWorkerRequest用它的GetPreloadedEntityBody ReadEntityBody方法处理文件流

HttpApplication application1 = sender as HttpApplication;
HttpWorkerRequest request1 = (HttpWorkerRequest) ((IServiceProvider) HttpContext.Current).GetService(typeof(HttpWorkerRequest));
try
{
if (application1.Context.Request.ContentType.IndexOf(”multipart/form-data”) <= -1)
{
return;
}
//Check The HasEntityBody
if (!request1.HasEntityBody())
{
return;
}
int num1 = 0;
TimeSpan span1 = DateTime.Now.Subtract(this.beginTime);

string text1 = application1.Context.Request.ContentType.ToLower();

byte[] buffer1 = Encoding.ASCII.GetBytes((”\r\n–” + text1.Substring(text1.IndexOf(”boundary=”) + 9)).ToCharArray());
int num2 = Convert.ToInt32(request1.GetKnownRequestHeader(11));
Progress progress1 = new Progress();

application1.Context.Items.Add(”FileList”, new Hashtable());

byte[] buffer2 = request1.GetPreloadedEntityBody();
num1 += buffer2.Length;

string text2 = this.AnalysePreloadedEntityBody(buffer2, “UploadGUID”);
if (text2 != string.Empty)
{
application1.Context.Items.Add(”LionSky_UpLoadModule_UploadGUID”, text2);
}
bool flag1 = true;
if ((num2 > this.UpLoadFileLength()) && ((0 > span1.TotalHours) || (span1.TotalHours > 3)))
{
flag1 = false;
}
if ((0 > span1.TotalHours) || (span1.TotalHours > 3))
{
flag1 = false;
}
string text3 = this.AnalysePreloadedEntityBody(buffer2, “UploadFolder”);
ArrayList list1 = new ArrayList();
RequestStream stream1 = new RequestStream(buffer2, buffer1, null, RequestStream.FileStatus.Close, RequestStream.ReadStatus.NoRead, text3, flag1, application1.Context, string.Empty);
list1.AddRange(stream1.ReadBody);
if (text2 != string.Empty)
{
progress1.FileLength = num2;
progress1.ReceivedLength = num1;
progress1.FileName = stream1.OriginalFileName;
progress1.FileCount = ((Hashtable) application1.Context.Items["FileList"]).Count;
application1.Application["_UploadGUID_" + text2] = progress1;
}

if (!request1.IsEntireEntityBodyIsPreloaded())
{
byte[] buffer4;
ArrayList list2;
int num3 = 204800;
byte[] buffer3 = new byte[num3];
while ((num2 - num1) >= num3)
{
if (!application1.Context.Response.IsClientConnected)
{
this.ClearApplication(application1);
}
num3 = request1.ReadEntityBody(buffer3, buffer3.Length);
num1 += num3;
list2 = stream1.ContentBody;
if (list2.Count > 0)
{
buffer4 = new byte[list2.Count + buffer3.Length];
list2.CopyTo(buffer4, 0);
buffer3.CopyTo(buffer4, list2.Count);
stream1 = new RequestStream(buffer4, buffer1, stream1.FileStream, stream1.FStatus, stream1.RStatus, text3, flag1, application1.Context, stream1.OriginalFileName);
}
else
{
stream1 = new RequestStream(buffer3, buffer1, stream1.FileStream, stream1.FStatus, stream1.RStatus, text3, flag1, application1.Context, stream1.OriginalFileName);
}
list1.AddRange(stream1.ReadBody);
if (text2 != string.Empty)
{
progress1.ReceivedLength = num1;
progress1.FileName = stream1.OriginalFileName;
progress1.FileCount = ((Hashtable) application1.Context.Items["FileList"]).Count;
application1.Application["_UploadGUID_" + text2] = progress1;
}
}
buffer3 = new byte[num2 - num1];
if (!application1.Context.Response.IsClientConnected && (stream1.FStatus == RequestStream.FileStatus.Open))
{
this.ClearApplication(application1);
}
num3 = request1.ReadEntityBody(buffer3, buffer3.Length);
list2 = stream1.ContentBody;
if (list2.Count > 0)
{
buffer4 = new byte[list2.Count + buffer3.Length];
list2.CopyTo(buffer4, 0);
buffer3.CopyTo(buffer4, list2.Count);
stream1 = new RequestStream(buffer4, buffer1, stream1.FileStream, stream1.FStatus, stream1.RStatus, text3, flag1, application1.Context, stream1.OriginalFileName);
}
else
{
stream1 = new RequestStream(buffer3, buffer1, stream1.FileStream, stream1.FStatus, stream1.RStatus, text3, flag1, application1.Context, stream1.OriginalFileName);
}
list1.AddRange(stream1.ReadBody);
if (text2 != string.Empty)
{
progress1.ReceivedLength = num1 + buffer3.Length;
progress1.FileName = stream1.OriginalFileName;
progress1.FileCount = ((Hashtable) application1.Context.Items["FileList"]).Count;
if (flag1)
{
progress1.UploadStatus = Progress.UploadStatusEnum.Uploaded;
}
else
{
application1.Application.Remove(”_UploadGUID_” + text2);
}
}
}
byte[] buffer5 = new byte[list1.Count];
list1.CopyTo(buffer5);
this.PopulateRequestData(request1, buffer5);
}
catch (Exception exception1)
{
this.ClearApplication(application1);
throw exception1;
}

Tags:

29 Jul 07 湖南台的《变形计》是一栏不仁道的节目

不知道湖南台什么时候搞出这么一栏节目,由于平时基本上不怎么看电视,我是昨天才看到的。
 
我想说想出这个“创意”的工作人员是混蛋,要赢得商业利益固然没错,但作为一个知名媒体,最起码应该考虑一下道德方面的问题。

我们常说的忆苦思甜,换位思考,固然没错,但任何事情的存在都需要有一个环境,完全的抛开社会环境,个人心里因素,而去单纯的强调互换,如果说你湖南台没想到这个环境和心里因素,那说明你是白痴,如果说你想到了仍然这样干,那说你混蛋一点都没错。

个人认为:这款节目能实现的最大价值就是,当富人的孩子在体验了一把贫苦生活之后,成长了,懂事了。知道了面对现实应该珍惜,面对未来应该更加努力。

可这个所谓的“价值”是单边的,这种价值只可能出现在富人孩子的一边,而穷人的孩子能得到的价值在哪里?过了一两个礼拜的优裕生活,然后再将他毫不犹豫的抛进贫困。别扯什么,穷人的孩子知道了外边世界的美好会更加发奋努力之类的屁话,这只是你们为了演示自己的不道德的说辞。我相信通过这样的互换,让穷人孩子感受更多的是社会的不公,与现实的残酷。而面对这样的不公与残酷,他们能做什么?别说什么,更加努力的读书,那些孩子连书都根本读不起,面对巨大的现实差异,不知道这些孩子的心里会产生怎样的变化?

况且上边说的所谓能实现的价值,是最好的情况,能实现这种价值的比率肯定不超过30%,更多的情况是,富人的孩子过了这个“村”以后,就忘了这个“店”。能起到的教育效果实在有限。

这种垃圾节目,麻烦湖南台,积积德,快点停掉吧。

Tags:

29 Jul 07 让Web2.0的路更宽些

Myspace的繁荣让我们羡慕.

Digg的兴起让我们期待.

特别是YouTobe,FaceBook的成功,更让互联网创业者们对2.0充满了幻想.

Twitter更是现在的新宠.

美国模式已经成了当今互联网创业的潜规则,将美国2.0们的成功模式copy to china,成了国内2.0创业的不二法则.于是我们有了一批Myspace;两批Digg;三,四批YouTobe;N批Twitter.

互联网的发展和传统行业是有区别的,似乎总是先有一个概念,然后引来眼球,最后才寻找赢利模式.无论哪个行业,只要属于商业范畴就避不开要赢利这个硬指标.想想当年的门户概念,海龟们将美国的门户copy到了中国,一时间门户概念声名鹊起,门户有了,眼球有了,可在国内当时的互联网普及程度却暂时还支撑不起一个有效的赢利模式.于是寒冬来了,这段时间对门户来讲是痛苦的,幸好手机的普及救了门户们一命,有了赢利模式,自然有了活下来的理由.

现在轮到2.0了,同样是概念,同样引来了眼球,同样暂时还没有清晰的赢利模式.不可否认2.0是未来的方向,以人为本的互联网最终将取代门户们主宰”世界”的格局.

但目前的2.0似乎有点问题,我们能看到的应用都集中在”生活”and”娱乐”上.一方面,创业者门挖空心思的想给大家创造更便捷的”沟通方式”,更有趣的”娱乐内容”.另一方面,2.0的这些东西的影响范围大多还只局限在”IT追鲜症候群”,同时这些所谓的更便捷的”沟通方式”,更有趣的”娱乐内容”似乎有点超出了正常生活范围内的需求,基本上是一个功过于求的状态.在这种状态下,赢利模式似乎是一个比较遥远的事情.

让我们暂且抛开”沟通”和”娱乐”,从另一个角度去思考一下2.0.如果将现在2.0概念的”人”换成”企业”,会是怎样的一个景象?

从为企业服务的角度出发,去思考2.0;从企业的需求出发,去思考2.0.也许在那里会有一个”中国模式”.

Tags: , , , ,

26 Jul 07 在自己博客新增的两个博客推广的服务

今天新增了两个博客推广的服务,记录一下。

1,FeedBurnerHeadline Animator 将博客的前5篇文章生成一个banner(Html代码),支持到My space,TypePad,Blogger,Wordpress.com的直接输出,同时你可以将这段代码做成你的论坛签名,或者邮件签名,让你的博客内容跟着帖子或邮件一起展现到大家面前。

遗憾的是,目前为止这项服务不支持中文,中文标题的文章,无法正常显示。(下边是我的输出)

Go ahead

↑ Grab this Headline Animator

2,criteo.com的Blogroll。这个服务就是在你的Blogroll中展示曾经安装了criteo服务,并且博客内容与你相近的blog链接。一个博客关联性的推广服务。关联过程完全是程序自动计算,应该是比较客观的展示。

注册很简单,提供你的email地址,然后输入你的blog地址就可以了。

但完全由算法来控制,就有可能带来一些“非常规”手段。比如:你可以找一个安装了此服务的“知名人士”的blog,时常去关注一下他的blog内容and关键词and tag,然后在你的blog中“有意无意”的让这些“关键词,tag”露露脸,那么你的链接出现在他的blogroll中的几率就会比较高,这样的case不用太多,有那么几个“知名的”就够了。比如:keso,想象如果真的可以这样,那么带来的流量应该还是很可观的。

总的来说,是一项很不错的服务,值得一试。

Tags: ,