[转载]RESTful routing in ASP.NET MVC

mikel阅读(1195)

[转载]RESTful routing in ASP.NET MVC – CodeProject.

Introduction

This sample application demonstrates how to use the SimplyRestfulRouteHandler to provide a RESTful approach to client-server communication. The SimplyRestfulRouteHandler is included in the MVC Contrib project, which extends the functionality of the ASP.NET MVC framework.

Background

MvcContrib is packed with quite a few gems. One of these is the SimplyRestfulRouteHandler, a route utility created by Adam Tybor. Using the SimplyRestfulRouteHandler, the following 10 Routes are assigned to the 8 Actions below.

Action URL HTTP Method Form Method
Show [controller]/[id] GET
Create [controller] POST
Update [controller]/[id] PUT
Update [controller]/[id] POST PUT
Destroy [controller]/[id] DELETE
Destroy [controller]/[id] POST DELETE
Index [controller] GET
New [controller]/new GET
Edit [controller]/[id]/edit GET
Delete [controller]/[id]/delete GET

* Based on information from Adam Tybor’s site.

The route handler is surprisingly easy to use, but it can be tricky to set up if you are not familiar with the new method signatures of the latest MVC source code refresh. I created this sample application based on the MVC HomeController that highlights the 8 Actions defined by SimplyRestfulRouteHandler. To follow along, you will need the 4/16 MVC source code refresh (build 0416) and the 4/19 release of the MvcContrib library (0.0.1.101).

Using the Code

First, you should create a new ‘ASP.NET MVC Web Application’ project from the ‘My Templates’ portion of the ‘New Project’ dialog. If you use the template of the same name under the ‘Visual Studio installed templates’ portion, you will be using the latest official release of MVC and not the source code refresh. In the global.asax.cs file, replace the RegisterRoutes method with the following:

Collapse
public static void RegisterRoutes(RouteCollection routes)
{
  SimplyRestfulRouteHandler.BuildRoutes(routes);
}

This will allow the route handler to build all 10 routes for you, based on templates listed in the table above.

Next, we open the HomeController.cs file and add the corresponding actions.

Collapse
public ActionResult Show(string id)
{
    ViewData["Title"] = "Show";
    ViewData["Message"] = "This will <em>Show</em> resource " + id;

    return RenderView("Index");
}

public ActionResult Create()
{
    ViewData["Title"] = "Create";
    ViewData["Message"] = "This will <em>Create</em> a new resource";

    return RenderView("Index");
}

public ActionResult Update(string id)
{
    ViewData["Title"] = "Update";
    ViewData["Message"] = "This will <em>Update</em> resource " + id;

    return RenderView("Index");
}

public ActionResult Destroy(string id)
{
    ViewData["Title"] = "Destroy";
    ViewData["Message"] = "This will <em>Destroy</em> resource " + id;

    return RenderView("Index");
}

public ActionResult Index()
{
    ViewData["Title"] = "Index";
    ViewData["Message"] = "This is the <em>Index</em>";

    return RenderView("Index");
}

public ActionResult New()
{
    ViewData["Title"] = "New";
    ViewData["Message"] = "This will create a <em>New</em> resource";

    return RenderView("Index");
}

public ActionResult Edit(string id)
{
    ViewData["Title"] = "Edit";
    ViewData["Message"] = "This will <em>Edit</em> resource " + id;

    return RenderView("Index");
}

public ActionResult Delete(string id)
{
    ViewData["Title"] = "Delete";
    ViewData["Message"] = "This will <em>Delete</em> resource " + id;

    return RenderView("Index");
}

For this sample app, all we really want to do is simply display a brief message letting us know which action the user wanted to take. The generated ‘Index.aspx‘ view is fine for this, so we can set the viewName parameter of the RenderView() method to “Index” for all actions, as shown above:

Now, we have just about everything we need. Let’s move on to the ‘Site.Master’ file and enable the user to generate all 8 Actions via click events.

Collapse
<ul id="menu">
    <li> <%= Html.ActionLink("Show GET", "Show",  "Home", new { @id="1" }) %> </li>
    <li> <%= Html.ActionLink("Index GET", "Index", "Home")%> </li>
    <li> <%= Html.ActionLink("New GET", "New", "Home")%> </li>
    <li> <%= Html.ActionLink("Edit GET", "Edit", "Home", new { @id = "1" })%> </li>
    <li> <%= Html.ActionLink("Delete GET", "Delete", "Home", new { @id = "1" })%> </li>
    <li> 
        <form action="<%= Url.Action("Create", "Home") %>" method="post" > 
            <a onclick="parentNode.submit();">Create POST</a>
        </form>
    </li>
    <li> 
        <form action="<%= Url.Action( "Update", "Home", new { @id = "1" }) %>" 
              method="post" > 
            <input type="hidden" name="_method" value="put" />
            <a onclick="parentNode.submit();">Update POST</a>
        </form>
    </li>
    <li> 
        <form action="<%= Url.Action( "Destroy", "Home", new { @id = "1" }) %>" 
              method="post" > 
            <input type="hidden" name="_method" value="delete" />
            <a onclick="parentNode.submit();">Destroy POST</a>
        </form>
    </li>
</ul>

If you were watching closely, you should have noticed that the POST events have a hidden input element named “_method” whose value is an HTTP method (PUT or DELETE). Well, most browsers don’t support these two methods, so we sometimes need a clever way of initiating these requests. Adam was kind enough to wire up our Destroy and Update Actions so that they fire when the route manager receives standard HTTP PUT and DELETE methods or when it receives a browser-friendly HTTP POST request with a PUT or DELETE “_method” defined. Next, we need to make the form elements of our menu look pretty, so we add the following to our ‘Site.css‘ file.

Collapse
ul#menu li form
{
    display: inline;
    list-style: none;
} 

And, that’s all there is to it. You should be able to launch the application and click on all of the menu items to generate any of the 8 RESTful actions.

History

  • 05/26/2008: Article created.
  • 05/30/2008: Simplified the source code using the “Index” view name for all Actions.

License

This article, along with any associated source code and files, is licensed under The Mozilla Public License 1.1 (MPL 1.1)

About the Author

Kevin Ortman

CEO
Technology Today, LLC
United States United States

Member

[转载]一个架构的演化--从All in One到SOA的实践

mikel阅读(884)

[转载]一个架构的演化–从All in One到SOA的实践 – 倚楼听风雨 – 博客园.

那一年,有个小程序

image_thumb[10]

业务简单,规模小,一个小程序直接搞定。

后来规模大了

image_thumb[23]

将前台逻辑和后台业务分开了,变成了客户/服务器模式。

再后来用的人多了,安装特麻烦

image_thumb[24]

换成了B/S结构,前台0安装了。

然后,使用范围扩大,上线的人更多了,响应变慢了

image_thumb[25]

将处理用户请求和业务计算的任务分离了。

稳定了,规模大了,后台业务计算变慢了

image_thumb[26]

将业务按照业务种类垂直切分后台。

后台多了,RPC连接麻烦又低效

image_thumb[27]

换成基于消息的通信方式,提高性能相互解耦。

性能高了,规模不断扩大,新需求不断出现,发布时间不断缩短

image_thumb[28]

所以,按照语言无关的契约定义服务,用最适合业务的语言实现服务,通过SR(Service Runtime)将服务请求和应答转换成消息,由MQ负责通信。一个业务一种服务,开发一个发布一个。搭上了SOA的班车-_-!

[转载]Android开发基础2-NDK安装和使用(图)

mikel阅读(846)

[转载]Android开发基础2-NDK安装和使用(图) – Thinker – 博客园.

使用C/C++开发的使用这个SDK,可以很方面的进行开发,对于已有C/C++代码的移植是个很关键的部分

The Android NDK is a complement to the Android SDK that helps you to:

– Generate JNI-compatible shared libraries that can run on the Android

1.5 platform (and later) running on ARM CPUs.

– Copy the generated shared libraries to a proper location of your

application project path, so they will be automatically added to your

final (and signed) .apks

Cygwin安装

http://www.cygwin.com/下载安装程序

可以先下载后再安装,全部下载1.7G,安装后大小5.6G

clip_image002

开发

命令行编译

注意按照“前置条件(JDK和环境变量)”设置好环境变量,能够找到cygwin和NDK的目录

在cygwin的命令行下即可编译NDK的sample文件

IDE中编译

ADT

http://dl-ssl.google.com/android/eclipse/

CDT

http://download.eclipse.org/tools/cdt/releases/helios

clip_image004

使用如上的地址在线安装好ADT和CDT即可编译

注意:

如下是对于具体的NDK项目(hello-jni)的设置,需要把NDK新建的Builder放在第一个(新加的builder设置为NDK_Builder)

clip_image006

clip_image008

这样IDE编译这个项目时先编译NDK的文件

Hello-jni的例子

编译NDK库文件

clip_image010

在Eclipse中打开项目[由于NDK的IDE功能不是很强,可以不使用CDT,使用上面的命令行编译库即可]

clip_image012

此时可以和界面整合跟踪

文档

android-ndk-r5\docs可以看到文档,包括make文件的格式、文件的结构等等都可以看到

调试

NDK的调试功能目前比较弱,可以使用CDT或者Visual studio调试库文件

参考:http://zhoujianghai.javaeye.com/blog/897212

[转载]Windows下配置使用MemCached

mikel阅读(18430)

[转载]Windows下配置使用MemCached – 调调儿 – 博客园.

  1. 安装配置MemCached服务端
    1. 下载memcached-1.2.6-win32-bin.zip ,解压后得到memcached.exe,就是memcached的主程序了。比如我们放到MemCached服务器下的C:\Program Files\MemCacheD下
    2. 下载安装Memcached Manager ,通过这个来管理memcached的服务端。

      打开MemCacheD Manager,点击 add Server,填写服务器信息。我这里直接在本地安装了memcached。如图,填完后点击apply,成功的话右侧会出现服务器。

      点击Add Instance添加memcached实例。这里有一些配置信息。Ip,端口,内存等等,不解释了。点击apply后会提示你是否现在启动,我们这里选是

      成功后发现右侧已经有实例了,到此服务端配置完毕。

  2. 客户端调用
    1. 首先需要下载Memcached .NET client Library 客户端类库,解压得到一个memcacheddotnet目录,一堆文件。

    为测试MemCached,我们建立一个web项目。引用Memcached.ClientLibrary.dll,这个dll在memcacheddotnet\trunk\clientlib\src\clientlib\bin\2.0\Release

    1. 使用比较简单,1个存 ,1个取。我们简单弄两页面。

      加上using

using Memcached.ClientLibrary;

存:

代码:

protected void Page_Load(object sender, EventArgs e)

{

if (!IsPostBack)

{

string[] serverlist = { server.Text };

SockIOPool pool = SockIOPool.GetInstance();

pool.SetServers(serverlist);

pool.InitConnections = 3;

pool.MinConnections = 3;

pool.MaxConnections = 5;

pool.SocketConnectTimeout = 1000;

pool.SocketTimeout = 3000;

pool.MaintenanceSleep = 30;

pool.Failover = true;

pool.Nagle = false;

pool.Initialize();

}

}

protected void SetValue_Click(object sender, EventArgs e)

{

MemcachedClient mc = new MemcachedClient();

mc.EnableCompression = false;

mc.Set(Key.Text, Value.Text);

Response.Write(“<script>alert(‘ok’)</script>”);

}

取:

代码:

protected void GetValue_Click(object sender, EventArgs e)

{

string[] serverlist = { server.Text };

SockIOPool pool = SockIOPool.GetInstance();

pool.SetServers(serverlist);

pool.InitConnections = 3;

pool.MinConnections = 3;

pool.MaxConnections = 5;

pool.SocketConnectTimeout = 1000;

pool.SocketTimeout = 3000;

pool.MaintenanceSleep = 30;

pool.Failover = true;

pool.Nagle = false;

pool.Initialize();

MemcachedClient mc = new MemcachedClient();

mc.EnableCompression = false;

string value = (string)mc.Get(Key.Text);

Value.Text = value;

}

看看效果:

点add存到memcached

点get。得到结果啦。

Ok,完毕。你也可以把客户端的代码再封装一下,让调用来的更简单。

[转载]Google Reader 使用技巧及OPML订阅源分享

mikel阅读(1080)

[转载]Google Reader 使用技巧及OPML订阅源分享 – Alexis – 博客园.

前几天参加了一个周金根组织的敏捷个人的学习交流群,在群里有人讨论起了Google Reader的使用技巧,更多的人还不知道Google Reader是何许神器。这里写一篇博客分享下我使用Google Reader的技巧以及分享下由周金根老师提供的技术订阅源,文中部分资源来自网络。

1. Google Reader 何许神器

Google reader是google提供的在线rss阅读工具,是你了解最新博客、新闻、资讯的快捷方式,只要你订阅了某个支持RSS的网站,你就可以使用Google Reader获取最新的更新。

我们程序员可以使用Google Reader订阅某些技术大牛的博客、IT界最新发生的新闻、软件的更新等等,这些都可以使用Google Reader来实现。

Google Reader的另一个神奇之处就是在于其穿墙的能力。建议如果还没有Google Reader的你赶紧注册一个。

2. Google Reader的快捷键

以上是Google Reader的快捷键表,有中英文对照的解释,英文更利于记忆快捷键,标红是我常用的快捷键,大家常用用就自然而然就记住了。下面讲一些不错的快捷键效果。使用快捷键可以极大程度调高阅读订阅的速度。

当我们打开Google Reader,想要快捷到达我们的某个自定义标签,我们可以使用gt(先按g键,然后按t键),打开标签选择页,如下图:

然后我们就可以使用方向键选择我们自己的标签。

3. Google Reader 遇到错误时咋办?

大家在使用Google Reader的时候,或多或少会遇到下图的尴尬,被“墙”阻隔了

我们只能等一会再开Google Reader,甚至放弃那个被阻隔的订阅源。现在已经有办法解决这个问题个,就是在浏览器地址中输入:https://www.google.com/reader/view/ 来登录你的Google Reader,使用https代替http即可

4. 导入其他的订阅源

我们可以将别人提供的OPML订阅源导入自己的Google Reader,OPML订阅源是一个遵守xml格式的xml文档。

进入Google Reader,进入管理订阅,如下图:

然后找到导入/导出选项卡,即可导入xml资源。

以下是我的Google Reader订阅源的标签的部分截图,其中很多订阅源来自周金根老师,在此表示感谢。

我的订阅源下载:

周金根的订阅源下载:

还有更多的技巧,如订阅别人的分享条目等。当然如果你有更好的技巧,欢迎与我分享

广告时间,如果觉得我的博客不错的话,可以使用Google Reader订阅我的博客,地址:http://www.cnblogs.com/alexis/rss

[转载]c#扩展方法奇思妙用基础篇七:IsBetween 通用扩展

mikel阅读(875)

[转载]c#扩展方法奇思妙用基础篇七:IsBetween 通用扩展 – 鹤冲天 – 博客园.

相信大家在看了本文的题目之后,马上就能写出 IsBetween 扩展来:

public static bool IntIsBetween(this int i, int lowerBound, int upperBound, 
    bool includeLowerBound = false, bool includeUpperBound = false)
{
    return (includeLowerBound && i == lowerBound) ||
        (includeUpperBound && i == upperBound) ||
        (i > lowerBound && i < upperBound);
}

大家的写法可能不尽相同,但效果都是一样的,以上可能是最精简的写法了吧,类似可以写出其它数据类型 IsBetween 来:

public static bool IntIsBetween(this long i, long lowerBound, long upperBound,
        bool includeLowerBound = false, bool includeUpperBound = false)
{
    return (includeLowerBound && i == lowerBound) ||
        (includeUpperBound && i == upperBound) ||
        (i > lowerBound && i < upperBound);
}
public static bool DoubleIsBetween(this float i, float lowerBound, float upperBound,
        bool includeLowerBound = false, bool includeUpperBound = false)
{
    return (includeLowerBound && i == lowerBound) ||
        (includeUpperBound && i == upperBound) ||
        (i > lowerBound && i < upperBound);
}

不过这样写下去可是很罗嗦的,.net 中的数值类型太多了,除了上面几个还有:short、long、ushort、uint、ulong、double、decimal…

此外,我们还有其它要类型如:string、DateTime 等也要进行 IsBetween 判断,一个一个写来不优雅。

泛型版本 IsBetween 扩展

.Net 中 IComparable<T> 接口 定义了值类型或类的通用比较方法,借助于此接口,写一个通用的 IsBetween 就容易多了:

public static bool IsBetween<T>(this T t, T lowerBound, T upperBound,
    bool includeLowerBound = false, bool includeUpperBound = false)
        where T: IComparable<T>
{
    if(t == null) throw new ArgumentNullException("t");

    var lowerCompareResult = t.CompareTo(lowerBound);
    var upperCompareResult = t.CompareTo(upperBound);

    return (includeLowerBound && lowerCompareResult == 0) ||
        (includeUpperBound && upperCompareResult == 0) ||
        (lowerCompareResult > 0 && upperCompareResult < 0);
}

这个是相当通用的,支持 .net 中的所有数值类型,也支持 string、DateTime,因为它们都实现了 IComparable<T> 接口,下面是一些调用代码:

//int
bool b0 = 3.IsBetween(1, 5);
bool b1 = 3.IsBetween(1, 3, includeUpperBound: true);
bool b2 = 3.IsBetween(3, 5, includeLowerBound: true);
//double
bool b3 = 3.14.IsBetween(3.0, 4.0);
//string
bool b4 = "ND".IsBetween("NA", "NC");
//DateTime
bool b5 = new DateTime(2011, 2, 17).IsBetween(new DateTime(2011, 1, 1), new DateTime(2011, 3, 1));

带 IComparer<T> 参数的 IsBetween 扩展

上面的扩展很通用,但还不够好,比如下面的 Person 类:

public class Person
{
    public string Name { get; set; }
    public DateTime Birthday { get; set; }
}

没有实现任何 IComparable<T> 接口,但我们需要确定某人是否界于另外两人这间,根据生日或其它条件判断。

使用 .Net 中另外一个关于通用比较的接口 IComparer<T> 接口,我们再创建一个扩展:

public static bool IsBetween<T>(this T t, T lowerBound, T upperBound, IComparer<T> comparer, 
    bool includeLowerBound = false, bool includeUpperBound = false)
{
    if (comparer == null) throw new ArgumentNullException("comparer");

    var lowerCompareResult = comparer.Compare(t, lowerBound);
    var upperCompareResult = comparer.Compare(t, upperBound);

    return (includeLowerBound && lowerCompareResult == 0) ||
        (includeUpperBound && upperCompareResult == 0) ||
        (lowerCompareResult > 0 && upperCompareResult < 0);
}

这个扩展需要一个 IComparer<T> 的实例,我们先来实现人员生日的“比较器” :

public class PersonBirthdayComparer : IComparer<Person>
{
    public int Compare(Person x, Person y)
    {
        return Comparer<DateTime>.Default.Compare(x.Birthday, y.Birthday);
    }
}

人员生日 IsBetween 示例代码如下:

var p1= new Person{ Name = "鹤冲天",  Birthday  = new DateTime(1990, 1, 1)};
var p2= new Person{ Name = "鹤中天",  Birthday  = new DateTime(2000, 1, 1)};
var p3= new Person{ Name = "鹤微天",  Birthday  = new DateTime(2010, 1, 1)};
bool b6 = p2.IsBetween(p1, p3, new PersonBirthdayComparer());

类似,我们还可以对人员进行身高、体重、人品等其它方面的 IsBetween 判断,只需要传入不同的 comparer。

针对 IComparable<T> 接口的 IsBetween 扩展

之前一篇文章中,我曾说过要针对接口扩展,我们何不针对 IComparable<T> 接口 进行扩展呢:

public static bool IsBetween<T>(this IComparable<T> t, T lowerBound, T upperBound,
    bool includeLowerBound = false, bool includeUpperBound = false)
{
    if (t == null) throw new ArgumentNullException("t");

    var lowerCompareResult = t.CompareTo(lowerBound);
    var upperCompareResult = t.CompareTo(upperBound);

    return (includeLowerBound && lowerCompareResult == 0) ||
        (includeUpperBound && upperCompareResult == 0) ||
        (lowerCompareResult > 0 && upperCompareResult < 0);
}

这个扩展的应用场景可能不多,这里举一个方便大家理解,假定我们自定义了一个大整数类形:

public class BigInt: IComparable<int>, IComparable<double>
{
    //...
    public int CompareTo(int other)
    {
        //...
    }
    public int CompareTo(double other)
    {
        //...
    }
}

因为它实 IComparable<int> 和 IComparable<double>,所以可以和 int 和 double 进行比较,则可以如下使用:

BigInt bi = new BigInt();
bool b8 = bi.IsBetween(10, 20);
bool b9 = bi.IsBetween(1.424E+12, 2.3675E+36);

( .Net 中已经有了大整数类型,请参见:BigInteger 结构,不过没有实现 IComparable<int> 和 IComparable<double> )

其它比较扩展

有了上面的 IsBetween 扩展,再写其它比较扩展就易如反掌了,比如下面几个:

  • LessThan
  • LessOrEquals
  • GreatOrEquals
  • GreatThan

[转载]Android (C开发)底层开发之一 环境搭建

mikel阅读(764)

[转载]Android (C开发)底层开发之一 【环境搭建】 – qixiinghaitang – 博客园.

Android是基于Linux的操作系统,处理器是ARM的,所以要在Linux或Windows等x86系统上编译Android能运行的程序,你需要一个交叉编译器。
在Linux下面,你可以自已编译一个交叉编译环境,但Windows下面,就比较复杂(也可以在cygwin中编译一个),但你可以选择下载一个现成的交叉编译环境:
http://www.codesourcery.com/gnu_toolchains/arm/download.html
Windows: http://www.codesourcery.com/gnu_toolchains/arm/portal/package3400/public/arm-none-linux-gnueabi/arm-2008q3-41-arm-none-linux-gnueabi.exe
Linux: http://www.codesourcery.com/gnu_toolchains/arm/portal/package3399/public/arm-none-linux-gnueabi/arm-2008q3-41-arm-none-linux-gnueabi.bin
安装好了之后,将 CodeSourcery编译器的bin目录 (我的是D:\Program Files\CodeSourcery\Sourcery G++ Lite\bin) 加入你的PATH环境变量中,就可以开始你的Android Native C开发之旅了,写好一个简单的C程序:
#include <stdlib.h>
int main(int argc, char** argv) {
printf(“hello android!\nI’m %s!\nI like android very much!!!\n”, “Martin Foo”);
return 0;
}
另存成hello.c,进入命令行模式,确保交叉编译器的bin目录,及Android SDK的tools目录在你的系统环境变量的path里面,用如下命令编译:
arm-none-linux-gnueabi-gcc -static hello.c -o hello
注意,一定要加上static参数,否则编译好的可能会在Android上不能运行。
启动Android模拟器,用如下命令将文件push到Android模拟器上:
adb shell mkdir /dev/sample
adb push hello /dev/sample/hello
adb shell chmod 777 /dev/sample/hello
先创建 /dev/sample目录,再将编译好的hello上传上去,最后将hello改成可执行的。
再进入命令行模式,进入Android的shell环境:
adb shell
#cd /dev/sample
#./hello
进入 /dev/sample目录,执行hello,运行结果如下图:

[转载]GoogleReader用户登陆验证

mikel阅读(1024)

[转载]GoogleReader用户登陆验证 – 编程点滴 – 博客园.

google账户支持多种认证方式,详细可参考http://code.google.com/intl/zh-CN/apis/accounts/

在做GoogleRead的帐号验证我选取了ClientLogin

利用 ClientLogin,您的桌面或移动设备应用程序能够将编程登录并入其界面中。与通过各个请求发送用户的登录凭据相比,ClientLogin 是一个更好的选择;ClientLogin 有着更好的效果和更高的安全性。(摘自google官方介绍)

请求 google登录接口
https://www.google.com/accounts/ClientLogin
参数
POST parameter name POST parameter value
service ‘reader’ (可选)
Email google账号
Passwd 密码
source 客户端的标识 例如 Mobile Newspaper/0.1 (可选)
continue ‘http://www.google.com/’ (可选)

返回值:SID=DQAAAIIAAADLOgquebmwAmluwdkqloneF3FvQAZZvG6EcPSqHLeXrBhfM1VFr2S36FT3C9YHNvzqjQl5ugBMlUgePDhtONnJujvUOrF11QV_DSg4I03b4HLndFnRQzZ2KmidxorykoB-3mf-gQH8NWmYOVYh-VXyM1Hursdr0tBatDDedQqs4R9CfZUzc9WV2erbKHmifF8
LSID=DQAAAIQAAACXQ9n7yPnAL7I18wEWQRx7lY4mssTO3aZ8NOn69h38fPBPzehq2jMyDIlqyetB2wVqu9_GKBxEwPbokfL-89a0hrXUNNFp4RQbV2tKiiuIGIcPLGA6n8mkkn4-4E3TxCnxSzvSiX1Pt2Q4zUhifDzSZ2NHZLw2TCXotsdpHpy18raGnWto3FoVSyxYe9EAafA
Auth=DQAAAIUAAACXQ9n7yPnAL7I18wEWQRx7lY4mssTO3aZ8NOn69h38fPBPzehq2jMyDIlqyetB2wUc1Ls7OzGP0qnFCvjbIi1EZz_3kvNLcjIm9N_ZD5yFu0TxbJLUH3oskRAM5s8ffGQPKKtFEWzHqAAQLEO-R-BViHsVOuox5zbcFmeIQbGXoY1Hy1YkZnTWg5HeaIbIWAE

拿到返回值后,

1,分离出 SID,添加cookie
domain .google.com
path /
expires 1600000000

2,分离出Auth,添加webRequest.Headers.Add(“Authorization”, “GoogleLogin auth=” + Auth的值

登陆完成,具体实现代码见下一篇,稍后送上!

[转载]水果忍者游戏评测及移动应用推广思路

mikel阅读(1708)

[转载]SocialBeta » Blog Archive » 水果忍者游戏评测及移动应用推广思路—-社会化媒体|社会化媒体营销|社会化设计|社区型网站运营|社会化媒体相关资源分享|We dream of being a Mashable in China..

一款简单的休闲游戏。目的只有一个 ——砍水果!屏幕上会不断跳出各种水果–西瓜,凤梨,猕猴桃,草莓,蓝莓,香蕉,苹果等等—在它们掉落之前要快速的全部砍掉! 不过不能砍到炸弹,另外还有时间限制,也有一定几率弹出具有技能的水果(比如冰冻减速、双倍积分)。水果忍者作为一款简单有趣的游戏,上市以来大受欢迎, 名列apple store畅销排行版前十位。

水果忍者游戏体验

第一印象:画风


无论是在应用商店下载,还是进入app后,给予用户的第一印象十分重要。对于休闲类游戏来说,画面风格对用户的第一印象有至关重要的作用。

休闲类游戏用户女性所占的比例高些,所以无论是angry birds(上图是angry birds情人节版的游戏首页)还是水果忍者,其画面风格倾向于简洁、可爱。不过对于硬核游戏来说,往往会加入更酷的形象、减少可爱的影响,加入暴力因素 等等。当然这都视目标用户而定,angry birds和水果忍者显然不是针对硬核游戏玩家的。

另外,动态背景、游戏选项图标都为第一印象提高不少,画面更显活泼,色调丰富不失层次。我们看看一个反例(下图是星际塔防,属于硬核游戏,类似魔兽争霸中的TD RPG,游戏可玩性不错)。

音乐音效

Angry birds和水果忍者的背景音乐贯穿这个游戏中,有鸟鸣水声,这为用户营造了一个很好的游戏环境,这也是许多PC经典单机游戏的必备因素(老玩家肯定无法 忘记大菠萝、魔兽争霸那些经典的背景音乐吧!还有不同道具所对应的音效)。水果忍者在音效上更为出色,忍者刀一旦碰上水果,马上听到切开水果那种爆裂的响 声,还有果汁溅射的声音,十分逼真,非常刺激,不过背景音乐比较单调,只有鸟鸣和水声。Angry birds情人节版在背景音乐上采用教堂上婚礼的背景音乐,符合浪漫的主题。

对于一款游戏来说,画面和音乐音效是基本因素,在手机游戏画面仍无法媲美PC时,做到极致仍旧是一个硬性要求(angry bird和水果忍者画面不华丽,但是简洁可爱,可玩性也是重要的因素。),对于游戏推广来说,资料片一直都是最主要的宣传方式,据调查,国内用户往往凭借 资料片的好坏来判断一款游戏。

可玩性


水果忍者的可玩性体现在

-游戏上手简单,但是想玩好不简单,上手简单,就是用手在屏幕划动,切掉弹出的水果;
-限定时间,一般是1分钟;
-会随机弹出炸弹,如果玩家切到炸弹,会给予游戏结束或者扣除游戏积分等惩罚;
-随机弹出功能性水果(减速、双倍积分以及frenzy);
-每次游戏结束后,会有积分榜(bonus),显示玩家完成的成就(比较有意思的是,还会有欢呼声哦!);
-设有相应任务,玩家完成相应任务后可解锁道具(比如忍者刀和游戏背景画面),忍者刀也有特效,比如蝴蝶忍者刀,玩家在划动时会出现蝴蝶(道具在画面和音效上的表现对游戏来说也很重要);
-可利用openfeint账号邀请好友开展多人对战游戏模式;
-用户的feint账号记录用户的游戏积分以及排行榜(用户可以增加好友,查看好友的积分,邀请好友参加游戏)。

不足之处:

-功能性水果出现几率不固定,有时候甚至一把都不出现,而且功能性水果对玩家的积分有着很大的影响,容易增加玩家的挫折感!(在angry birds中向用户提供了tips选项,玩家可以搜索相关游戏技巧。)
-游戏要求高度集中,需要用户投入全额注意力。(在被窝里玩还是很爽的!在车上很容易失败,一般玩几次就不想玩了)

社区

水果忍者一开始只提供单机模式,openfeint账号也只是提供邀请好友和积分排行榜的功能,但是并不提供多人游戏模式,单机模式情况下 Halfbrick工作室通过设计不同游戏模式(经典模式、香蕉模式、苹果模式)来提高游戏的可玩性,增加用户粘度(Angry birds还推出电影、玩具、资料片,这一切都是品牌附加值的开发以及营销),不过这显然不够。

随后在1.4更新版中,水果忍者登陆Game Centre,支持多人在线游戏了(由于没玩过,所以没法说体验了)。

这一切其实与PC上的单机游戏发展模式是差不多,国内的众多游戏竞技平台对许多提供局域网游戏模式的单机游戏的发展起到至关重要的推动作用(VS、浩方、qq对战平台、YY语音对于星际、魔兽、暗黑等等都有着非常重要的作用)。

其他细节


1:上图就是对新手玩家的操作提示/教程了,而没有采用对话框的形式,idea很赞。对于游戏提示,要慎用对话框。
2:单一的游戏任务(切水果),连游戏选项也是水果…
3:虽然画面和音效丰富,但是背景音乐很单一
4:另外由于是单机游戏,社交性不强,也不提供分享游戏到主流的社交平台。

手机游戏市场的一些看法

PS:这里是《2010年中国手机网游用户行为调查报告》(不过并非仅限于Android、ios平台,MTK平台的用户是相当巨大的。)

从中我们可以看出几个中国用户特有的消费习惯(许多玩家仍有着“武侠梦”,中国用户更加偏爱竞技性强的游戏,月末效应,晚上23:00至24:00属于流量最高峰、论坛仍旧是许多用户下载客户端的主要渠道)

对手机游戏市场认识的5个误区(引自游戏邦):

  1. 用户在外出时才玩手机游戏(在家、上班使用比例很高)
  2. 手机游戏主要是休闲类游戏(硬核也很关键)
  3. 可以一本万利地开发游戏(事实上,靠手机游戏赚钱并不容易。在去年3月,独立游戏节(Independent Games Festival)名誉主席Simon Carlesss曾在一个会议上公布了一组数据:90%的iPhone应用颗粒无收,仅7%的应用幸运地实现收支平衡,只有更少的3%开发商实现了盈利。 )
  4. 品牌无关紧要
  5. 这一行业的发展已经成熟(显然未成熟,随着硬件技术的发展,AR/NFC/移动支付等等都将为手机游戏提供更多的发展空间)

移动应用的推广思路

在采访国内手机应用开发者中发现,许多开发者一直为app的推广而烦恼。在iphone上,众多的应用中只有排名top100才能得到曝光,而 Android平台上,由于手机应用商店繁多,不统一,而且硬件也不一致,也给Android开发者带来不少的烦恼,这里说下自己的意见。

1:病毒式传播(推荐《社交游戏的那些事》)

病毒式传播分为直接手段和间接途径;

直接手段——好友邀请 由一名用户给另一名用户发送信息,直接邀请对方参与游戏,通常采用请求的方式。

不过目前许多手游开发者一般采用比较硬性直接的直接传播(比如通过短信发送“推荐一款好玩的…”给用户的好友,或者在微博上发布),这样的传播方式一具有冒犯性,二对用户也没有激励。首先可以通过徽章等游戏道具来激励用户,比如邀请多少个好友可以获得徽章,赢得奖励;另外可以设定只有邀请了好友才能进入下一阶段的游戏;最后也可以采用好友间互动来达到病毒式传播,比如互赠礼物。

间接途径——信息墙传播

利用社会化媒体来宣传玩家的自我成就、虚拟人物的screenshot等等。另外利用社会化媒体来号召大家一起行动,发起活动也会成为一个有效的传播推广方式。

2:微博

目前微博在中国如火如荼,许多企业也纷纷开展微博营销。微博营销成本低,很适合个人开发者为自己的产品做推广,下面是自己的一些理解:

A:微博是媒体

微博首先是个媒体,媒体就要提供内容,那么首先就必须有一个内容规划。

目前许多企业要么把微博看做一个销售营销渠道,直接发布特价亦或者有奖活动等等;也有的企业把微博看做及时听取用户反馈的渠道,许多内容都是自己产品的相关介绍和改进,而无其他。

1:要有内容规划,首先必须知道你的目标用户喜欢什么样的内容(趣味性的、知识性的、娱乐性的等等),利用相关性的内容去吸引目标用户(内容营销)。
2:另外内容要精细。所谓精细,就是不要粗制滥造。
3:内容的分类要做好;多利用@+用户来吸引转发;内容的格式要多样,视频图像…:
4:保持固定的更新频率。

B:微博是自媒体

自媒体意味着个性化,代表着你的品牌特征,另外还代表着不是自上而下的传播,而是平等具有人性化的互动(鼓励你的团队成员去开微博,当然每个员工的微博可以有不同的特色,但最好有一个统一的主题)。

开始可能你的微博没人评论也没人转发,那么就去评论你的目标用户的微博(尤其是意见领袖的微博,但前提是这位意见领袖也是你的目标用户,否则你的评论只会淹没在茫茫大海中)或者邀请互粉等等。

3:论坛和应用商店

前面提过论坛仍旧是许多用户下载app的渠道,不过相比微博,论坛和应用商店对于许多开发者来说仍旧是不可控的,不过你同样可以通过发布精华帖子来积累自己的影响力。一个没有丝毫影响力的人在论坛上推广自己的应用不会有多大效果。

另外有没有做到用户到哪,你就到哪!你在多少个论坛上算是活跃用户。

推荐主题、最新主题、最新回复、本周热门、社区精华、日发帖排行、一周排行榜、一月排行榜中,你的应用有没有出现,这些都是能提高你的应用的曝光率。

你有任何关于移动应用推广方面的想法,欢迎留言。

本文链接:http://www.socialbeta.cn/articles/mobile-app-promotion.html
作者:wisp@SocialBeta
欢迎转载,请注明出处和作者。

[转载]google reader api

mikel阅读(1029)

[转载]google reader api – 编程点滴 – 博客园.

Google Reader 是一个使用了大量JavaScript构建的feed聚合器,它能非常及时地抓取最新的feed数据。Google的Ajax前台调用到的数据采用了 Atom格式,这种数据技术降低了Google Reader的开发难度,同时也使得第三方应用很容易对其进行扩展。

Feed获取

/reader/atom/feed/

不管feed一开始采用了什么格式,Google都将其转化为Atom格式。所有的RSS feed包含一切在提要里边出现的所有元素,这一点和My Yahoo! backend不一样,Yahoo的不包含任何附加的元数据。

你可以一下的格式从Google Reader访问任何feed:

  • http://www.google.com/reader/atom/feed/ + [Feed地址]

你可以通过参数n设置返回的文章数量,默认为20。

Google忽略掉在阅读器里边没有用的数据,它们包括命名空间(如Apple iTunes podcast、Yahoo! Media RSS的命名空间)、作者信息(如email、主页地址等)、甚至于版权等内容。

订阅列表

/reader/atom/user/[user id]/pref/com.google/subscriptions

Google Reader的feed订阅列表包含用户当前订阅的和已经被删除的订阅。每个feed包含其地址、发布和更新时间、用户标记的标签(如果有的话)。当前订阅都被归类到阅读列表状态。通过设置complete为true,你还可以获取到所有的feed列表。

这里是我在Google Reader用户ID全部为0的账户的订阅列表。我没有订阅我自己的RSS feed,不过给我的Atom feed打上了标签。不管在原feed里边是否声明了作者,在每个列出的feed包含author元素都是空的。也许Google计划增加feed的认领服务,不过即使是他们自己的Google Blog,也还是没有任何额外的作者信息。

阅读列表

/reader/atom/user[user id]/state/com.google/reading-list

我最喜欢Google Reader的阅读列表功能,它能直接访问到我订阅feed中所有未读的文章,以一种“新闻流”的方式展现它们。

这里有一个我的阅读列表的例子,你同样可以通过参数n设置返回文章的数量。

已阅读文章

http://www.google.com/reader/atom/user/[user ID]/state/com.google/read

你可以通过这个API获取到用户在Google Reader里边已读的文章。如果想通过用户最近阅读的100篇文章分析其趋势或者实现对它们的查询,那么这个功能就很有用了。参数n同样可以设置返回的文章数量。

某标签下的文章列表

/reader/atom/user/[user id]/label/[tag]

你 还可以查看指定标签下最近发表的文章。比如你把很多feed标记为“营销”,只是想访问有关营销的feed,这就很有用了。返回的内容中包含已读和未读的 文章。已读的文章被归类到已读(state/com.google/read),你可以通过这判断是否将它们隐藏起来。返回的数量可以通过参数n来判断。

标星文章

/reader/atom/user[user id]/state/com.google/starred

Google Reader允许用户对文章标星。这些标星文章包括有feed地址、标签、发布/更新时间。你可以通过参数n指定返回的数量,默认为20。

Google将标星项目视作一种特殊的标签,因此输出的内容和标签下文章列表结构一致。

添加或删除订阅

/reader/api/0/edit-subscription

使用POST请求访问Google Reader的API,你可以添加任何feed到Google Reader的订阅列表。

  • /reader/api/0/edit-subscription — 基本地址
  • ac=[“subscribe” 或者 “unsubscribe”] — 请求动作
  • s=feed%2F[feed URL] — 请求的订阅
  • T=[命令标识] — Google发布的具有时效性的标识,可以通过/reader/api/0/token获取。

添加标签

/reader/api/0/edit-tag

通过HTTP的POST请求可以给一个feed或单独的文章打上标签。

  • /reader/api/0/edit-tag — 基本地址
  • s=feed%2F[feed URL] — 你想打标签的feed地址
  • i=[item id] — 出现在feed中的文章的id,可选,用来给个别的文章打标签。
  • a=user%2F[user ID]%2Flabel%2F[标签] — 请求动作,添加标签给feed,文章,或者两者。
  • a=user%2F[user ID]%2Fstate%2Fcom.google%2Fstarred — 标星文章。
  • T=[special scramble] — 关于用户和新标签的信息。可能处于安全因素考虑,尚未公开。

总结

基于对Google上面这些和县官服务的请求,你有可能构建自己的feed阅读器。你可以把Google作为你的后台,创建具有全新体验的在线和离线的程序,利用Google的ID,略施小计,你还可以创建更加高级的功能。

Google 已经在这些数据API之上建立了第一个程序——Google Reader,从他们对API地址的选择之上来看的话,Google Reader应该不是最后一个基于这些数据集的程序。我喜欢数据调用的开放,Google Reader 的API是如此简单,相信会引导Google和第三方开发者创建更多的新应用!

参考资料:http://code.google.com/p/pyrfeed/wiki/GoogleReaderAPI