[转载]页面性能测试之二----ShowSlow+Yslow环境搭建

mikel阅读(864)

[转载]页面性能测试之二—-ShowSlow+Yslow环境搭建 – 虫师 – 博客园.

上一节介绍了解页面性能测试及两个测试工具。本节要介绍的页面测试工具是做为浏览器的插件嵌入到浏览器里面的。

----//工具介绍

YslowYSlowYahoo发布的一款基于FireFox的插件。

YSlow可以对网站的页面进行分析,并告诉你为了提高网站性能,如何基于某些规则而进行优化。

ShowSlow: ShowSlow平台用来收集页面性能测试工具Yslow的测试结果,并对测试结果进行分析展示。互联网上有一个在线的showSlow平台,免费提供Yslow的测试结果收集与展示。考虑到企业的某些系统可以存在商业机密,我们会搭建自己的环境。

在线的ShowSlow平台:http://www.showslow.com

----//环境介绍

因为我在搭建的过程中就是卡在版本上;所以以便于你在搭建过程中的排错,我在此列出我的搭建环境。

系统:windows XP sp3

浏览器:FireFox 6.0.2

Yslow版本:Yslow 3.0.4

ShowSlow版本 : http://download.csdn.net/detail/fnngj/3629866

关于showslow,请按照我提供的链接下载,虽然他是比较老,但它是可用的。

最新版本hubgit上有,最新版本为:showslow_1.1.3但试了N次(N大于10),一直有错误。请鄙视我吧。我已经尽力的在网上云游了多日,未找到解决办法。如果你成功了,请写出来与大家分享,谢谢。

AppServ版本 : http://www.appservnetwork.com/

进入下载页面后,请下载appserv-win32-2.5.10版本,虽然它也不是最新的,但它是可用的。请不要在其它网站下载,因为我不能保证它是可用的。哥哥姐姐不是吓你们噢。因为我在其它网站下载的一直报错,找不到解决办法,这也是云游多日的第二个原因。请再次鄙视我吧。

当然了,你可以不用appserv傻瓜一体式安装,你可以先分别安装phpmySQLapache以及缺省的模块等。如果你配置好了,觉得so ease ,也可以分享出来。请写详细点,因为像我这样的菜鸟会看不懂。

----//一起来配置

安装下载的appserv-win32-2.5.10.exe文件,一路随便填写一下就行了,注意你填写的数据库密码。

安装完成之后,打你MySQL数据库(开始—-程序—-SppServ—MySQL Command Line Client

输入你在安装时填写的密码。

mysql>create database showslow; //创建一个数据库

mysql>use showslow; //切换到新建的数据库

在你下载的showslow的文件夹中查找一个叫:tables.sql的文件,然后复制到一个简单的路径下面,我直接放C盘根目录下了,执行下面命令。

mysql>source c:/tables.sql; //将所有的表导入到新建立的数据库里

mysql>show tables; //确认一下导入是否成功

打开showslow文件夹,找到config.sample.php重命名config.php

如果你下载的是我提供的链接,里面就有一个config.php,无须重命名。

修改config.php里面的参数

$db = ‘showslow’;

$user = ‘root’;

$pass = ‘123456’; //密码根据你的情况修改。

最后把你修改好的showslow文件夹放到……\AppServ\www\文件夹下面。

打开你的火狐浏览器,

菜单栏:工具—–附加组件—–搜索:Firebug Yslow两个组件下载安装后重启。下面来张截图提提神。

在火狐地址栏目输入:about:config—–我保证会小心的 🙂

过滤器:yslow

修改下面三项内容:

  • extensions.yslow.beaconUrl = http://www.example.com/showslow/beacon/yslow/
  • extensions.yslow.beaconInfo = grade
  • extensions.yslow.optinBeacon = true

重新启动浏览器:在浏览器内输入http://localhost/showslow/

如果页面上没有任何错误提示的话,恭喜你,你太幸运了。

===================================可能出现的问题===========================================

错误提示:

Fatal error: Call to undefined function mcrypt_get_iv_size()

in C:\AppServ\www\showslow\users\CookieStorage.php on line 62

解决办法:

\AppServ\文件夹下搜索libmcrypt.dlllibmhash.dll文件

将这两个文件复制到系统盘(如C盘)下的Windows\system32\文件夹下。

找到并打开系统盘\winows\php.ini(注意扩展名不要错了)

大概在593行处

extension=php_mcrypt.dll

extension=php_mhash.dll

将上面两句前面的分号(;)去掉并保存。

—————————————————————-

错误提示:

Warning: mysql_fetch_assoc(): supplied argument is not a valid MySQL result resource in C:\AppServ\www\showslow\index.php on line 31

No data is gathered yet

解决办法:

对不起,我一直没解决这个问题,如果你下载的是我提供的showslow应该不会出现这个错误。如果不是,很有可以会报这样的错误。而且我标注红色的部分会在多个地方出现,请高手解答。。。。。

==========================================================================================

----//如何使用

如果你安装顺利的话,来看看怎么用吧。

打开火狐浏览器,输入你要测试的网址:http://fnng.cnblogs.com 打开Yslow插件测试。

然后切换到http://localhost/showslwo/

last 100 measurements”点击你要查看性能的链接:

好吧!最后祝你测试愉快。有疑问欢迎交流,加本博客左侧的QQ群。

Yslow:

[转载]Android中XML文件的三种解析方式

mikel阅读(745)

[转载]Android中XML文件的三种解析方式 – 青春流水指间、 – 博客园.

今天学习了xml文件的三种解析方式,其中包括在学习java时学习的SAX和DOM这两种解析方法。在Android中有一种开源的PULL解析方法,今天我将他们的具体用法和大家分享下。

业务需求:

给定一个xml文件,要求分别用SAX,DOM,PULL三种方法对xml文件进行解析。

运行效果图如下:

下面是具体实现步骤:

首先我们需要一个xml文件,下面是我xml文件的存放位置。

该xml文件中的内容我写的比较简单。仅供实现这个功能。下面是我的xml文件的内容。

persons.xml:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <persons>
 3     <person id="1">
 4         <name>刘备</name>
 5         <age>12</age>    
 6     </person>
 7     <person id="2">
 8         <name>刘欢</name>
 9         <age>14</age>    
10     </person>
11     <person id="3">
12         <name>李明</name>
13         <age>15</age>    
14     </person>
15 </persons>

我们可以看到xml文件中只有一个person对象,所以我们必须定义一个person类。

Android中为了体现封装性,我们需要将不同功能的代码放在不同的包里。下面是我在实现这个功能时,各个代码存放的位置。

Person.java

 1 package cn.yj3g.entity;
 2 public class Person {
 3 
 4     private int id;
 5     private String name;
 6     private int age;
 7     public Person(int id, String name, int age) {
 8         super();
 9         this.id = id;
10         this.name = name;
11         this.age = age;
12     }
13     public Person() {
14         super();
15     }
16     public int getId() {
17         return id;
18     }
19 
20     public void setId(int id) {
21         this.id = id;
22     }
23     public String getName() {
24         return name;
25     }
26     public void setName(String name) {
27         this.name = name;
28     }
29     public int getAge() {
30         return age;
31     }
32     public void setAge(int age) {
33         this.age = age;
34     }
35     @Override
36     public String toString() {
37         return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
38     }
39 }

由于三种解析方法都实现了一个功能,就是对xml文件进行解析,所以在这里我们可以将解析方法定义为一个接口,三种解析方法都实现这个接口。下面是我定义的一个接口

IXmlParseService:

 1 package cn.yj3g.service;
 2 
 3 import java.io.InputStream;
 4 import java.util.List;
 5 import cn.yj3g.entity.Person;
 6 //定义一个接口
 7 public interface IXmlParseService {
 8     //接口中的一个解析方法。如果引用这个接口,就要实现这个方法,这样做更简便,封装性更好。
 9     public List<Person> getPersonsByParseXml(InputStream is) throws Exception;
10 }

下来就是具体用三种方式对xml实现解析。下面是三种解析方式的具体代码:

<1>DOM解析    DomParseService:

 1 package cn.yj3g.service;
 2 
 3 import java.io.InputStream;
 4 import java.util.ArrayList;
 5 import java.util.List;
 6 import javax.xml.parsers.DocumentBuilder;
 7 import javax.xml.parsers.DocumentBuilderFactory;
 8 import org.w3c.dom.Document;
 9 import org.w3c.dom.Element;
10 import org.w3c.dom.Node;
11 import org.w3c.dom.NodeList;
12 import cn.yj3g.entity.Person;
13 /**
14  * DOM解析器在解析XML文档时,会把文档中的所有元素,按照其出现的层次关系,解析成一个个Node对象(节点)。Node对象提供了一系列常量来代表结点的类型
15  * ,当开发人员获得某个Node类型后,就可以把Node节点转换成相应节点对象(Node的子类对象),以便于调用其特有的方法。
16  * Node对象提供了相应的方法去获得它的父结点或子结点。编程人员通过这些方法就可以读取整个XML文档的内容、或添加、修改、删除XML文档的内容.
17  * 
18  * 缺点:
19  * 一次性的完全加载整个xml文件,需要消耗大量的内存。
20  */
21 public class DomParseService implements IXmlParseService {
22 
23     @Override
24     public List<Person> getPersonsByParseXml(InputStream is) throws Exception {
25         List<Person> list = null;
26         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
27         DocumentBuilder builder = factory.newDocumentBuilder();
28         Document document = builder.parse(is);
29         // 得到根元素,这里是persons
30         Element root = document.getDocumentElement();
31         // 得到一个集合,里面存放在xml文件中所有的person
32         NodeList nodeList = root.getElementsByTagName("person");
33         //
34         if (nodeList == null || nodeList.getLength() == 0) {
35             return null;
36         }
37         // 初始化
38         list = new ArrayList<Person>();
39 
40         for (int i = 0; i < nodeList.getLength(); i++) {
41             // xml中的person标签
42             Element element = (Element) nodeList.item(i);
43             Person p = new Person();
44             // 得到person的id属性
45             int id = Integer.parseInt(element.getAttribute("id"));
46             p.setId(id);
47             // 得到name
48             String name = getAttrText(element, "name");
49             p.setName(name);
50             // 得到age
51             String age = getAttrText(element, "age");
52             p.setAge(new Integer(age));
53 
54             list.add(p);
55         }
56         return list;
57     }
58 
59     /**
60      * 获得指定元素的子元素中的文本内容
61      */
62     public String getAttrText(Element element, String name) {
63         NodeList nodeList2 = element.getChildNodes();
64         Node node = null;
65         for (int i = 0; i < nodeList2.getLength(); i++) {
66             node = nodeList2.item(i);
67             if (node.getNodeName().equals(name)) {
68                 return node.getTextContent();
69             }
70         }
71         return null;
72     }
73 }

<2>SAX解析  SAXParseService:

package cn.yj3g.service;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import cn.yj3g.entity.Person;
/**
 * 优点:SAX解析允许在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才会文档进行操作。
 * 
 */
public class SAXParseService implements IXmlParseService {
    public List<Person> getPersonsByParseXml(InputStream is) throws Exception {

        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser = factory.newSAXParser();
        saxHandler handler = new saxHandler();
        //
        parser.parse(is, handler);
        return handler.getList();
    }
    // 自定义一个handler实现DefaultHandler并 重写它的相关方法
    private class saxHandler extends DefaultHandler {
        String currunt = null;
        List<Person> list = null;
        Person p = null;

        @Override
        public void startDocument() throws SAXException {
            list = new ArrayList<Person>();
        }

        @Override
        public void endDocument() throws SAXException {
        }

        // 开始解析元素
        @Override
        public void startElement(String uri, String localName, String qName,
                Attributes attributes) throws SAXException {
            if ("person".equals(localName)) {
                p = new Person();
                p.setId(Integer.parseInt(attributes.getValue("id")));
            } else if ("name".equals(localName) || "age".equals(localName)) {
                currunt = localName;
            }
        }

        // 元素解析结束
        @Override
        public void endElement(String uri, String localName, String qName)
                throws SAXException {
            if ("person".equals(localName)) {
                list.add(p);
            } else if ("name".equals(localName) || "age".equals(localName)) {
                currunt = null;
            }
        }

        // 解析文本
        @Override
        public void characters(char[] ch, int start, int length)
                throws SAXException {
            String s = new String(ch, start, length);
            if ("name".equals(currunt)) {
                p.setName(s);
            } else if ("age".equals(currunt)) {
                p.setAge(Integer.parseInt(s));
            }
        }

        // 返回list
        public List<Person> getList() {
            return list;
        }
    }
}

<3>PULL解析  PullParseService:

package cn.yj3g.service;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import cn.yj3g.entity.Person;
/**
 * 优点:不是一次加载,中途可以停止。
 *
 */
public class PullParseService implements IXmlParseService {
    public List<Person> getPersonsByParseXml(InputStream is) throws Exception {

        List<Person> list = null;
        Person p = null;
        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        XmlPullParser parser = factory.newPullParser();
        //设置输入流
        parser.setInput(is, "utf-8");
        //parser的几种事件类型
        int type = parser.getEventType();
        while (type != XmlPullParser.END_DOCUMENT) {
            //
            String typename = parser.getName();
            switch (type) {
            //文档开始 -->xml中的persons
            case XmlPullParser.START_DOCUMENT:
                list = new ArrayList<Person>();
                break;
            //元素开始
            case XmlPullParser.START_TAG:
                if ("person".equals(typename)) {
                    p = new Person();
                    p.setId(Integer.parseInt(parser.getAttributeValue(0)));
                    //
                } else if ("name".equals(typename)) {
                    p.setName(parser.nextText());
                    //
                } else if ("age".equals(typename)) {
                    p.setAge(Integer.parseInt(parser.nextText()));
                }
                break;
            //元素结束    
            case XmlPullParser.END_TAG:
                if ("person".equals(typename)) {
                    list.add(p);
                    p=null;
                    break;
                }
            }
            //最最重要的一步,pull解析中的特有的方法,解析下一个标签
            type = parser.next();
        }
        return list;
    }
}

下来就是在主界面上通过Button设置监听来调用三种解析方法对xml文件进行解析,并将解析出来的数据放在一个ListView中。

主界面: XMLParseActivity:

 1 package cn.yj3g.XMLParseActivity;
 2 
 3 import java.io.InputStream;
 4 import java.util.ArrayList;
 5 import java.util.HashMap;
 6 import java.util.List;
 7 import java.util.Map;
 8 import android.app.ListActivity;
 9 import android.content.res.AssetManager;
10 import android.os.Bundle;
11 import android.view.View;
12 import android.view.View.OnClickListener;
13 import android.widget.SimpleAdapter;
14 import cn.yj3g.TL23_xml_test.R;
15 import cn.yj3g.entity.Person;
16 import cn.yj3g.service.DomParseService;
17 import cn.yj3g.service.PullParseService;
18 import cn.yj3g.service.SAXParseService;
19 
20 public class XMLParseActivity extends ListActivity implements
21         OnClickListener {
22     @Override
23     public void onCreate(Bundle savedInstanceState) {
24         super.onCreate(savedInstanceState);
25         setContentView(R.layout.main);
26 
27         // 找到Button按钮并添加监听
28         findViewById(R.id.btn_dom).setOnClickListener(this);
29         findViewById(R.id.btn_sax).setOnClickListener(this);
30         findViewById(R.id.btn_pull).setOnClickListener(this);
31     }
32 
33     public void onClick(View v) {
34         int id = v.getId();
35         //定义一个List容器来存放Person对象
36         List<Person> list = null;
37         //
38         InputStream is = null;
39         AssetManager manager = getAssets();
40         try {
41             //找到解析的文件
42             is = manager.open("persons.xml");
43             switch (id) {
44             case R.id.btn_dom:
45                 //调用DOM解析方法对文件进行解析
46                 list = new DomParseService().getPersonsByParseXml(is);
47                 break;
48             case R.id.btn_sax:
49                 //调用SAX解析方法对文件进行解析
50                 list = new SAXParseService().getPersonsByParseXml(is);
51                 break;
52             case R.id.btn_pull:
53                 //调用PULL解析方法对文件进行解析
54                 list = new PullParseService().getPersonsByParseXml(is);
55                 break;
56             default:
57                 break;
58             }
59         } catch (Exception e) {
60             e.printStackTrace();
61         }
62         showUI(list);
63     }
64     
65     //运用Adapter方法将所得到的List<Person>显示在ListView中
66     public void showUI(List<Person> list) {
67         List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
68         for (Person p : list) {
69             Map<String, Object> map = new HashMap<String, Object>();
70             map.put("id", p.getId());
71             map.put("name", p.getName());
72             map.put("age", p.getAge());
73             data.add(map);
74         }
75         String[] from = { "id", "name", "age" };
76         int[] to = { R.id.tv_id, R.id.tv_name, R.id.tv_age };
77         SimpleAdapter adapter = new SimpleAdapter(this, data,
78                 R.layout.person_list_item, from, to);
79         setListAdapter(adapter);
80     }
81 }

我将布局文件也附在下面供大家参考吧。

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <LinearLayout 
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="50dip"
        android:background="#222222">
        <Button  android:id="@+id/btn_dom"
            android:layout_width="fill_parent" 
            android:layout_height="wrap_content" 
            android:text="DOM显示"
            android:layout_weight="1.0"
            android:layout_gravity="center"/>
        <Button  android:id="@+id/btn_sax"
            android:layout_width="fill_parent" 
            android:layout_height="wrap_content" 
            android:text="SAX显示"
            android:layout_weight="1.0"
            android:layout_gravity="center"/>
        <Button  android:id="@+id/btn_pull"
            android:layout_width="fill_parent" 
            android:layout_height="wrap_content" 
            android:text="PULL显示"
            android:layout_weight="1.0"
            android:layout_gravity="center"/>
    </LinearLayout>
    <LinearLayout   
    android:orientation="horizontal"
      android:layout_height="wrap_content" 
       android:layout_width="fill_parent">
        <TextView  
            android:layout_width="fill_parent" 
            android:layout_height="wrap_content" 
            android:text="ID"
            android:layout_weight="1.0"
            android:layout_gravity="center"/>
         <TextView  
            android:layout_width="fill_parent" 
            android:layout_height="wrap_content" 
            android:text="姓名"
            android:layout_weight="1.0"
            android:layout_gravity="center"/>
        <TextView  
            android:layout_width="fill_parent" 
            android:layout_height="wrap_content" 
            android:text="年龄"
            android:layout_weight="1.0"
            android:layout_gravity="center"/>
       </LinearLayout>
    <ListView android:id="@android:id/list"  
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
        android:layout_weight="1"/>
</LinearLayout>

person_list_item.xml:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout
 3   xmlns:android="http://schemas.android.com/apk/res/android"
 4   android:orientation="horizontal"
 5   android:layout_width="match_parent"
 6   android:layout_height="match_parent">
 7     <TextView android:id="@+id/tv_id"
 8         android:layout_width="match_parent"
 9           android:layout_height="wrap_content"
10           android:layout_weight="1"/>
11     <TextView android:id="@+id/tv_name"
12         android:layout_width="match_parent"
13           android:layout_height="wrap_content"
14           android:layout_weight="1"/>
15     <TextView android:id="@+id/tv_age"
16         android:layout_width="match_parent"
17           android:layout_height="wrap_content"
18           android:layout_weight="1"/>
19 </LinearLayout>

这样我们这个项目就做好了,就可以实现解析xml的功能了。运行效果如最前面的效果图。

以上就是三种方式实现对XML文件的解析。希望大家不吝指教。

[转载]开发一个自己的HTML在线编辑器(一)

mikel阅读(968)

[转载][翻译]开发一个自己的HTML在线编辑器(一) – webabcd – 博客园.

原文地址:http://aspalliance.com/1092_Rich_Text_Editor_Part_I
[原文源码下载]

开发一个自己的HTML在线编辑器(一)

摘要
在本文中,Haissam Abdul Malak将给大家详细介绍如何使用JavaScript开发一个HTML在线编辑器,它可以应用于web应用程序中,特别是论坛,社区和博客。这个编辑器支持基于XHTML创建文本的功能。

原文发布日期:2007.01.04
作者:Haissam Abdul Malak
翻译:webabcd

文章内容
介绍
在用户控件中添加HTML代码
javascript文件
编辑器属性
添加一个样式表
结论

介绍
我 的一个朋友在一个正在开发的项目(一个博客网站)中遇到了一些问题,是关于文本编辑器的。在研究了所有免费的编辑器之后,他发现没有一个是他所需要的,所 以我接下了这个任务,帮他开发一个HTML在线编辑器的用户控件,我认为和大家分享这个控件是个好主意,达到了知识共享的目的。

这个编辑器包括如下一些特性
1、工具栏包括了全部的功能(下面已列出)
·排列(居左,居中,居右)
·字体格式(加粗,下划线,斜体,字号,字体,文字颜色)
·计算单词数,删除格式,插入水平线,撤销,重复,插入字符

2、HTML模式结合到了一个框架中,文本模式结合到了另一个框架中。注意这两个框架只能有一个被显示。

3、有两个图标,分别是“HTML视图”和“设计模式”,一个文本框用来显示单词数,最后有两个隐藏文本框用来存储用户输入的数据。

要看懂这个实例,你需要有JavaScript和HTML的相关知识。

在用户控件中添加HTML代码
这部分我们将创建一个用户控件(hamHtmlEditor.ascx),并且在其中写一些必需的HTML代码。注意该用户控件不包含<head>, <body> 或 <form> 标记。

我 们将创建3个表格来显示所有的图标,另外还要有3个下拉列表框。其中2个表格放在控件的顶端,1个表格放在控件的底部。每个图标都有3个事件,分别是 onmouSEOver,onmouseup,onclick,处理这些事件的是javascript文件中的javascript代码。把 javascript代码和HTML代码分开,可以让你更容易理解和调试。然后我们将创建3个层,第一个层包含一个已经有的HTML页 (TextArea.htm)。我使用一个HTML页是因为如果用户输入了一个rul,它可以自动的把它转换为HTML代码并呈现在你的文本中。第二个层 包括了1个textarea,在用户使用期间,它用来显示HTML代码(默认隐藏)。第3个层包含了一些符号,当用户点击“插入符号”后,这个层将被现实 (默认隐藏)。

为了使用户能够输入文字,你必须在控件被使用的时候,将其设置为“设计模式”

列表1

onload=”document.frames[‘HamHtmlEditor1_content’].document.designMode=’on'”

请下载这个项目以知道如何正确的创建所有的HTML标记
图1

javascript文件
这部分我们将写一些处理用户事件的函数。首先,我们将定义一些全局变量,其中每一个变量都有自己的功能,但最多的是用来存储图标在被单击之前或者默认的值—“No”。只有一个变量有另一个功能,这个变量是sourceText,它用来存储用户输入的文本。

列表2

var sourceText= ”;
var imgStatusBold = ‘No’;
var imgStatusItalic = ‘No’;
var imgStatusUnderLine = ‘No’;
var imgStatusLeft = ‘No’;
var imgStatusCenter = ‘No’;
var imgStatusRight = ‘No’;
var imgStatusRemoveF= ‘No’;
var imgStatusWCount = ‘No’;
var imgStatusInsertL = ‘No’;

基于上面这些变量的值,当用户点击了1个图标,将检查相关的变量是否是“Yes”,它用来指明相关的图标并不是第一次加载时的图标。当用户控件全 部加载完毕,我们将立即设置这些图标为他们的初始状态,当我们需要改变图标状态的时候,如果原来的值为“No”,就把它变为“Yes”。

有 三个功能分别被称作onmouSEOver,onmouseup,和onclick。Onmouseover触发函数ChangeImg(),作用是当用 户把鼠标放到图标上则改变所显示的图标的状态,这个函数需要两个参数(容器ID和新图标路径)。注意工具栏上的图标在web应用程序中被放置到 “Images”文件夹下。

列表3

function ChangeImg(id, imgsrc)
{
var imgSrc = Images/ + imgsrc;
document.getElementById(id).src
= imgSrc;
}

Onmouseup函数的功能是用户的鼠标离开一个图标时,把这个图标该回其初始的状态,它需要3个参数(容器ID,新图标路径和1个变量)

列表4

function ReturnImg(id, imgsrc, ownVar)
{
if(ownVar == ‘No’)
{
var imgSrc = Images/ + imgsrc;
document.getElementById(id).src
= imgSrc;
}

}

第3个参数用来说明这个图标是否是被选中的状态,默认值是“No”。

单击图标后执行一个指定的动作,一个单独的javascript方法被调用,每一个动作都有标准的写法。

列表5

document.frames[‘HamHtmlEditor1_content’].document.execCommand(‘JustifyLeft’,false,null);

使用上面这个方法可以使用户输入的文字居左。ExecCommand将在文档中执行一个命令。它使用一个预先组合到一起的功能来直接在浏览器中操作页面的布局。注意,只有在页面完全加载完毕后才能使用它。

列表6

function MakeBold(boldover, bold)
{
var img = document.getElementById(‘Bold’)
var imgBold = Images/ + boldover
var imgNotBold = Images/ + bold
img.src
= imgBold;

if(imgStatusBold == ‘Yes’)
{
imgStatusBold
=‘No’;
img.src
= Images/ + bold;
}

else
{
imgStatusBold
= ‘Yes’
}

document.frames[‘HamHtmlEditor1_content’].document.execCommand(‘bold’,
false,null);
document.frames[‘HamHtmlEditor1_content’].focus();
}

上面这段代码的功能是使用户输入的文字加粗的。当用户点击了加粗按钮,我们要改变这个按钮的状态。设置相关的全局变量为“Yes”,意思是该按钮 已被选中。每次用户单击按钮,我们都要检查相关的变量,来确定之前按钮是否是被选中的状态,然后我们给选中的文字加粗。它需要两个参数,第一个用来存储鼠 标经过时加粗按钮的图标路径,第二个用来存储正常加粗按钮的路径。相同的语法也在,斜体和下划线中适用。

对文字进行排列,我们使用与MakeBold()相似的函数,但是,3个排列功能的按钮只能有一个是被选中状态,其它两个要变为初始的未被选中的状态。

为了完成上面指出的那个execCommand命令,请参考
http://www.course.com/downloads/newperspectives/crweb3/documents/dhtml_t02.html

现 在我们创建一个计算用户输入的单词数的函数。定义一个变量,默认值为0。在定义另一个变量用来存储用户输入的文本,我们将拆开这个变量,并且将拆开的结果 保存到一个数组中,然后检查数组内每个元素的长度,如果是零则不计数,如果不是零则计数变量加1。计数完后,我们把该值赋给用于显示计数的文本框。

列表7

var wordCount = document.frames[‘HamHtmlEditor1_content’].document.body.innerText;
var count = 0;
countWithSpace
= wordCount.replace(‘\n’, ”);
countWithoutSpaces
= countWithSpace.split(‘ ‘);
for(i=0;i<countWithoutSpaces.length;i++)
{
if(countWithoutSpaces[i].length>0)
{
count
+=1;
}

window.parent.document.getElementById(‘HamHtmlEditor1_TxtCount’).value
= count;
}

当单击“删除格式”按钮后,我们调用一个javascript函数,发送命令“RemoveFormat”给execCommand用来删除选中文本的格式。

如果想删除某些已经有格式的文本的格式,这个功能将是非常有用的。

列表8

function RemoveFormating()
{
document.frames[‘HamHtmlEditor1_content’].document.execCommand(‘RemoveFormat’);
document.frames[‘HamHtmlEditor1_content’].focus();
}

“撤销”和“重做”功能与上面这段javascript类似。给execCommand发送“undo”或“redo”将执行撤销和重做功能。需要一个参数来指明命令的名字。

列表9

function Formats (style)
{
document.frames[‘HamHtmlEditor1_content’].document.execCommand(style);
document.frames[‘HamHtmlEditor1_content’].focus();
}

当用户单击“插入符号”按钮,我们将在该按钮之后显示第3个层来出示所有符号图片。我们使用javascript来做这件事。

列表10

function ShowDiv(images)
{
var div = document.getElementById(images);
if(div.style.display == ‘block’)
div.style.display
= ‘none’;
else
div.style.display
= ‘block’;
}

图2:用户单击“插入符号”后,编辑器的外观

当 用户点击第3个层的任意一个符号时,另一个javascript函数被调用,它用来在编辑器中指针的位置处插入符号。这个函数需要3个参数。第一个参数用 来指定execCommand的命令来在文档中插入一个图片(InsertImage),第二个参数是图片的路径,第三个参数是该图片所在的层的id。注 意所有的符号在web应用程序中被放置在一个“Emoticons”文件夹下。

列表11

function insertImages(style,url,images)
{
document.getElementById(images).style.display
= ‘none’
document.frames[‘HamHtmlEditor1_content’].focus();
HamHtmlEditor1_content.document.execCommand(style,”,url)
document.frames[‘HamHtmlEditor1_content’].focus();
}

当单击“HTML视图”按钮后,第二个层被显示,而第一个层则被隐藏。这个层的“readonly”属性被设置成了“true”,意思是用户在此状态下不能对其编辑,我们只能在这个层里看到HTML代码。

列表12

function TransformtoHtml()
{
document.getElementById(‘HamHtmlEditor1_Div2’).style.display
= ‘block’;
document.getElementById(‘HamHtmlEditor1_Div2’).innerText
=
document.frames[‘HamHtmlEditor1_content’].document.body.innerHTML;
}

当单击“设计模式”按钮后,第二个层则被隐藏

列表13

function TransformToText()
{
document.getElementById(‘HamHtmlEditor1_Div2’).style.display
= ‘none’;
}

下拉列表用来让用户选择预先设定好的数据。

第一个是字号,尺寸在1(10pt)到7(22pt)之间。这个按钮被单击后,要调用 一段javascript函数。这个函数获得用户在下拉列表里选择的值,然后作为第三个参数发送给execCommand。第一个参数是 “FontSize”,用来执行设置文字大小的命令。注意,下拉列表中的字号大小是预先在用户控件中的HTML代码里定义好的。

列表14

function ChangeFont()
{
var fontSize = document.getElementById(‘FontDropDownonchange’);
document.frames[‘HamHtmlEditor1_content’].document.execCommand(‘FontSize’,
0,fontSize.options[fontSize.selectedIndex].text);
document.frames[‘HamHtmlEditor1_content’].focus();
}

接下来这段代码用来改变字体。第一个参数是“FontName”,用来执行设置文字字体的命令,第二个参数是false或者0,第三个参数是用户所选择的文字。

列表15

function ChangeFontName()
{
var fontName = document.getElementById(FontFamilyName);
document.frames[‘HamHtmlEditor1_content’].document.execCommand(‘FontName’,
false,fontName.options[fontName.selectedIndex].text);
document.frames[‘HamHtmlEditor1_content’].focus();
}

第三个下来列表用来选择所选文字的颜色。这些颜色是预先定义好的,如果你想可以设置更多的颜色,请修改相关的HTML代码。

列表16

function ChangeFontColor()
{
var fontColor = document.getElementById(Color);
document.frames[‘HamHtmlEditor1_content’].document.execCommand(‘ForeColor’,
false,fontColor.options[fontColor.selectedIndex].text);
document.frames[‘HamHtmlEditor1_content’].focus();
}

最后的功能用来把用户输入的文本值存储到一个隐藏字段中,其详细的HTML值存储到另一个隐藏字段中。这样即使编辑器失去焦点,也可以获取到值,下一部份你可以看到在编码的过程中通过使用两个属性来取得隐藏字段的值。

列表17

function CloneText()
{
document.getElementById(‘HamHtmlEditor1_ContentTxt’).innerText
= document.frames[‘HamHtmlEditor1_content’].document.body.innerText;
document.getElementById(‘HamHtmlEditor1_ContentHtml’).value
= document.frames[‘HamHtmlEditor1_content’].document.body.outerHTML;
}

这部分完成后,你的javascript文件就准备完了。你如果想在你的用户控件中使用这个文件,就需要在代码中加入<head>标签。如下

<script src=”HTMLEditor.js” language=”javascript” type=”text/javascript></script>

如果你想调试javascript,需要加一个词“Debugger”。这样编译时将开始调试模式。或者你也可以设置你的IE浏览器,把“禁用脚 本调试(Internet Explorer)”和“禁用脚本调试(其他)”两个复选框的选中状态取消,然后添加你的端点。(译者注:调试js可以参考这篇文章:在Visual Studio中调试JavaScript

编辑器属性
如果想将用户输入的文本保存为.txt文件或者把HTML代码保存到另一个.txt文件,你可以在这个控件中添加以下两种属性:

首先在你的ascx.cs页面创建两个字段。

列表18

protected System.Web.UI.HtmlControls.HtmlInputText ContentTxt;
protected System.Web.UI.HtmlControls.HtmlInputText ContentHtml;

创建两个被保护的变量,保存以上创建的字段的值。

列表19

protected string _text;
protected string _html;

第一个属性被称为“ContentText”,它可以获取文本并在你的后置代码中赋值给一个变量。

ContentTxt被声明成一个HtmlInputText控件,它的Value属性被存储到_text字符串变量中。

列表20

public string ContentText
{
get
{
return _text = ContentTxt.Value;
}

set
{
_text
= value;
}

}

第二个属性被称为“ContentInnerHtml”,它可以获得详细的HTML代码。

ContentHtml被声明成一个HtmlInputText控件,它的Value属性被存储到_html字符串变量中。

列表21

public string ContentInnerHtml
{
get
{
return _html = ContentHtml.Value;
}

set
{
_html
= value;
}

}

添加一个样式表
在这部分我们将创建一个样式表(Styles.css),用来修改工具栏和框架的UI。我们将设置工具栏的背景颜色为蓝色。框架右侧和底部的也设置成相同的颜色。通过修改下面的代码,你可以随便设置控件的界面(UI)。
列表22

.HtmlView
{
background-color
:white;
border-bottom-width
:medium;
border-bottom-style
:solid;
border-bottom-color
:cornflowerblue;
border-right-width
:medium;
border-right-color
:cornflowerblue;
border-right-style
:solid;
}

.FirstDiv
{
background-color
:white;
border-bottom-width
:medium;
border-bottom-style
:solid;
border-bottom-color
:cornflowerblue;
border-right-width
:medium;
border-right-color
:cornflowerblue;
border-right-style
:solid;
}

.toolbar
{
background-color
:cornflowerblue;
background-repeat
:repeat;
}

现在在你用户控件的<head>标签内链接上这个样式表,代码如下:

<LINK href=”Styles.css” type=”text/css” rel=”stylesheet”>

图3

注意如果你要在用户控件中包含多个实体,你必须为这些div层创建动态的标识。请注意,div层的ID被设置成了“userControlID_divlayer”。

结论
我 们可以看到,开发你自己的HTML在线编辑器并不是很困难。在这篇文章里我详细的解释了javascript语言和XHTML。这是HTML在线编辑器的 第一个版本,我们非常感谢你使用它并且提供给我们你的意见。它的第二个版本,将会有更多的特性,如果你有什么好的注意,欢迎告诉我们。我们目前正在开发第 二个版本,它也将通过这个网站发布出来,其会增加复制,粘贴,剪切,项目符号,项目编号,打印等功能以及一个可自定义的工具栏。

希望这篇文章有阅读的价值。

[原文源码下载]

祝编程愉快!

[转载]ASP.NET的Master和Content之间的事件发生顺序

mikel阅读(792)

[转载]ASP.NET的Master和Content之间的事件发生顺序 – Sangplus – 博客园.

今天自己编织程序验证了Master和Content的Load事件的发生顺序,代码如下:
Content的Load代码:

1 protected void Page_Load(object sender, EventArgs e)
2 {
3 Label1.Text = DateTime.Now.Ticks.ToString();
4 System.Threading.Thread.Sleep(1000);
5 }

Master的Load代码:

1 protected void Page_Load(object sender, EventArgs e)
2 {
4 Label2.Text = DateTime.Now.Ticks.ToString();
5 System.Threading.Thread.Sleep(1000);
6 }

结果:

内容页面时间: 633244468953985968


母板时间:633244468964000368

从上可以看出,Content比Master首先调用Load函数。

今天从看到有人把相关事件顺序进行了排列,总结的相当全面:


母版页和内容页都可以包含控件的事件处理程序。对于控件而言,事件是在本地处理的,即内容页中的控件在内容页中引发事件,母版页中的控件在母版页中引发事件。控件事件不会从内容页发送到母版页。同样,也不能在内容页中处理来自母版页控件的事件。

在 某些情况下,内容页和母版页中会引发相同的事件。例如,两者都引发 Init 和 Load 事件。引发事件的一般规则是初始化事件从最里面的控件向最外 面的控件引发,所有其他事件则从最外面的控件向最里面的控件引发。请记住,母版页会合并到内容页中并被视为内容页中的一个控件,这一点十分有用。

下面是母版页与内容页合并后事件的发生顺序:

母版页控件 Init 事件。

内容控件 Init 事件。

母版页 Init 事件。

内容页 Init 事件。

内容页 Load 事件。

母版页 Load 事件。

内容控件 Load 事件。

内容页 PreRender 事件。

母版页 PreRender 事件。

母版页控件 PreRender 事件。

内容控件 PreRender 事件。

[转载].NET中序列化(三)

mikel阅读(904)

[转载].NET中序列化(三) – 人道编程 – 博客园.

导航:

.NET中序列化(一)

.NET中序列化(二)

—————————————————————————————————————————-

经过前两章的介绍,我想大家应该对序列化有了一定基础认识了,本节将介绍序列化泛型,和序列化事件

序列化泛型

其实泛型和非泛型其实没有什么不同,不过要注意以下两点:

1.泛型只支持BinaryFormatter格式,不支持SOAP格式

2.泛型序列化的类型和反序列化的类型要一致,如果把MyClass<int> 类型序列化,你不能反序列化出MyClass<string>类型。

    [Serializable]
    public class MyClass<T>
    {
        public string Name
        {
            get;
            set;
        }
        public int Age
        {
            get;
            set;
        }
        public T MyWork
        {
            get;
            set;
        }
    }

    [Serializable]
    public class Work
    {
        public string Name
        {
            set;
            get;
        }
        public string Address
        {
            set;
            get;
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            MyClass<Work> my = new MyClass<Work>();
            my.Name = "凤姐";
            my.Age = int.MaxValue;

            Work work = new Work();
            work.Address = "你家隔壁";
            work.Name = "不知道";
            my.MyWork = work;

            //泛型只支持BinaryFormatter格式,不支持SOAP格式
            System.Runtime.Serialization.IFormatter formatter = new BinaryFormatter();

            //创建一个文件流
            Stream stream = new FileStream(@"c:\MyClass.bin", FileMode.Create, FileAccess.Write);

            using (stream)
            {
                //这里就是进行序列化了
                formatter.Serialize(stream, my);
            }
        }
    }

序列化事件

序列化事件在命名空间using System.Runtime.Serialization中,事件共分四个,分别是

OnSerializing:序列化发生之前

OnSerialized:序列化发生之后

OnDeserializing:反序列化发生之前

OnDeserialized:反序列化发生之后

 1     [Serializable]
 2     public class MyClass
 3     {
 4         //数据库连接字符串
 5         string connectionString = "";
 6         [NonSerialized]
 7         SqlConnection conn;
 8         public SqlConnection Conn
 9         {
10             get
11             {
12                 return conn;
13             }
14             set
15             {
16                 conn = value;
17             }
18         }
19 
20         public string Name
21         {
22             get;
23             set;
24         }
25 
26         public int Age
27         {
28             get;
29             set;
30         }
31 
32         [OnSerializing]
33         void OnSerializing(StreamingContext context)
34         {
35         }
36 
37         [OnSerialized]
38         void OnSerialized(StreamingContext context)
39         {
40         }
41 
42         [OnDeserializing]
43         void OnDeserializing(StreamingContext context)
44         {
45         }
46 
47         //因为数据连接不好被序列化,所以反序列化时就为NULL了,我们就应该在反序列化发生之后的事件中人工的实例化数据连接
48         [OnDeserialized]
49         void OnDeserialized(StreamingContext context)
50         {
51             conn = new SqlConnection(connectionString);
52             conn.Open();
53         }
54 
55     }

我们利用OnDeserialized属性事件人工完成了SQLConnection的反序列化。

注意:

1.事件的签名一定要是 void <方法名>(StreamingContext context)这个样子的,context只有在高级的场景中才用到,现在先不讨论。

2.最好是把事件方法写成私有的,以避免子类的重载件方法产生异常。

好了,今天的内容说完了,晕都快12点了,我要洗洗睡了。下节我们将介绍序列化的版本控制。

[转载]Flex与javascript通信

mikel阅读(1409)

[转载]Flex与javascript通信 – 英雄小强 – 博客园.

首先列出代码部分,我们可以先尝试的感受一下效果:

1.Flex代码部分:文件名为Flex_JavaScript.mxml

<!--?xml version="1.0" encoding="utf-8"?-->

<!&#91;CDATA&#91;             import mx.controls.Alert;             public function init():void             {                 ExternalInterface.addCallback("FlexMethod",FlexMethod);             }             private function FlexMethod():void             {                 Alert.show("这是Flex的Alert方法");             }             protected function FlexMethod_clickHandler(event:MouseEvent):void             {                 // TODO Auto-generated method stub                 FlexMethod();             }                          protected function FlexCallJS_clickHandler(event:MouseEvent):void             {                 // TODO Auto-generated method stub                 ExternalInterface.call("JSMethod","这是Javascript的Alert方法");             }                      &#93;&#93;>
<!-- Place non-visual elements (e.g., services, value objects) here -->

2.JavaScript代码部分:将以下代码添加到index.template.html里面(为什么要添加到index.template.html里面呢?因为index.template.html里面的代码会自动添加到Flex自动生成的HTML文件中)。

<script type="text/javascript">// <!&#91;CDATA&#91;
    function JSMethod(info) {
        alert(info);
    }
    function JSCallFlex() {
        document.getElementById("Flex_Javascript").FlexMethod();
    }
// &#93;&#93;></script>

<input onclick="JSCallFlex()" type="button" value="Javascript调用Flex" />
<input onclick="JSMethod('这是Javascript的Alert方法')" type="button" value="Javascript的Alert方法" />

3.修改Flash的大小,否则看不到HTML里面添加的按钮Button,我这里改为400X300

swfobject.embedSWF("${swf}.swf", "flashContent", "400", "300",
            swfVersionStr, xiSwfUrlStr, flashvars, params, attributes);

这里稍微解释一下,不多说,你懂的:

1.Flex里面使用ExternalInterface.call(“Js函数名称”,参数)进行调用javascript方法,其返回的值就是Js函数所返回的值。

2.在init方法中使用ExternalInterface.addCallback(“注册的方法名”,As中的函数名)进行注册,“注册的方法名”可以再javascript中直接调用

3.在js中,就可以用document.getElementById(“Flash在Html中的ID”).注册的方法名(参数)进行调用,当然,默认”Flash在Html中的ID”就是Flex文件的名称,例如,我们这里就是Flex_Javascript,因为我们的Flex文件就是Flex_Javascript.mxml

注:本文章部分内容可能引用于网络,本人进行修改或注释,希望能够帮到更多的人。 作者 姓名:英雄小强 邮箱:hero88821@qq.com QQ :659406804 MSN:hero821@msn.cn

[转载]织梦dedecms标签全攻略

mikel阅读(834)

[转载]织梦标签全攻略.

站点根网址(cfg_basehost):网站根节点网址,主要用于生成一些超链接中加入站点根网址,例如:百度新闻、站点RSS、系统上传附件等
网页主页链接(cfg_indexurl):用于前台模板调用网站主站连接
主页链接名(cfg_indexname):网站主页的连接名称,默认为“主页”
网站名称(cfg_webname):全局站点的名称,通常显示在网页页面的标题栏部分,默认为“我的网站”
文档HTML默认保存路径(cfg_arcdir):网站生成静态页面HTML存放路径,默认为“/html”,可以根据自己需要进行设置
图片/上传文件默认路径(cfg_medias_dir):网站附件上传默认保存路径,默认为“/uploads”,可以根据自己需要进行修改
编辑器(是/否)使用XHTML(cfg_fck_xhtml):控制网站内容编辑器是否启用XHTML类型的标记,默认是不起用的
模板默认风格(cfg_df_style):默认模板的风格,设置后模板的路径变为“/tremplets/[设置模板风格]”,默认是default,即“/tremplets/default/”
网站版权、编译JS等底部调用信息(cfg_powerby):网站底部版权及js调用信息,一般可以将流量统计代码加入到这里,前台进行调用
站点默认关键字(cfg_keywords):用于显示站点默认关键字,便于SEO,通常显示在首页的<meta>中,可以根据自己需求进行修改
站点描述(cfg_description):用于显示站点默认描述,便于SEO,通常显示在首页的<meta>中,可以根据自己需求进行修改
网站备案号(cfg_beian):用于显示网站备案号的相关内容,可以根据自己需要进行设置
DedeCms安装目录(cfg_cmspath):系统默认安装目录,默认如果安装在网站根目录即为空,如果安装在子目录需要对其进行设置,例如“cms”,一般移动网站目录需要对其进行重新设置,并重新生成内容,否则会出现页面无法显示、PHP报错等现象
cookie加密码(cfg_cookie_encode):用于对用户登陆cookie加密设置,默认系统自动生成,通常使用在系统整合等方面
数据备份目录(在data目录内)(cfg_backup_dir):数据库备份文件夹,通常在系统根目录的data文件夹下,默认为backupdata,即在系统“/data/backupdata”文件夹下
网站发信EMAIL(cfg_adminemail):用于站点发信的E-mail地址,默认为“cfg_adminemail”,可以根据自己需要进行修改
Html编辑器选项(目前仅支持fck)(cfg_adminemail):网站内容发布,字段类型为HTML时候使用的编辑器,例如普通文章发布时候内容部分的编辑器,默认为fck,在V5.3中取消了以前的HTML编辑器,并今后不再进行开发
栏目位置的间隔符号(cfg_list_symbol):通常显示在网站当前位置部分的内容,默认为“ > ”即当前位置部分显示为“主页 > 一级栏目 > 二级栏目”,可以根据自己需要进行修改
关键字替换(是/否)使用本功能会影响HTML生成速度(cfg_keyword_replace):系统将会替换HTML编辑器中内容部分的关键词为加亮显示,通常这个选项开启会影响系统生成HTML页面的速度,系统默认是开启的
(是 /否)支持多站点,开启此项后附件、栏目连接、arclist内容启用绝对网址(cfg_multi_site):系统附件生成采用地址类型,一般附 件生成没有开启该选项附件将采用“/uploads/liming/test111.gif”的形式,如果开启将在附件地址前面加上网站地址,会变为“ http://wenwen.soso.com/z/UrlAlertPage.e?sp=Shttp%3A%2F%2Fwww.adc.com%2Fuploads%2Fliming%2Ftest111.gif ”设置有效解决了二级域名附件无法显示的问题,系统默认是关闭的
(是/否)开启管理日志(cfg_dede_log):用于记录管理员登陆操作系统的日志,默认是关闭的
FTP主机(cfg_ftp_host):部分创建将通过ftp形式进行文件创建,系统默认没有这个设置,您可以设置FTP的主机地址为ftp.abc.com,下面的FTP相关设置也是如此,如果是虚拟主机需要空间商提供FTP账号密码等
FTP端口(cfg_ftp_port):同FTP主机部分
FTP用户名(cfg_ftp_user):同FTP主机部分
FTP密码(cfg_ftp_pwd):同FTP主机部分
网站根在FTP中的目录(cfg_ftp_root):同FTP主机部分,一般虚拟主机网站根目录为wwwroot或者htdocs
是否强制用FTP创建目录(cfg_ftp_mkdir):如果系统不支持PHP创建目录,启用后将采用FTP形式强行创建目录,系统默认是关闭这个选项的
服务器时区设置(cfg_cli_time):用于设置系统程序执行的时区影响到全站时间相关功能,如文章添加时间、留言时间等,默认为8
是 否启用smtp方式发送邮件(cfg_sendmail_bysmtp):采用SMTP发送电子邮件,系统默认是关闭的,改设置将影响到找回密码、文档 内容推荐等功能,如果开启需要设置以下SMTP信息,如果启用还需要保证服务器拥有邮件发送的功能,如果是主机空间可以和空间商取得联系并且确保SMTP 设置正确性才能确保邮件发送
smtp服务器(cfg_smtp_server):同是否启用smtp方式发送邮件部分,默认为smtp.xinhuanet.com
smtp服务器端口(cfg_smtp_port):同是否启用smtp方式发送邮件部分,默认为25
SMTP服务器的用户邮箱(cfg_smtp_usermail):同是否启用smtp方式发送邮件部分
SMTP服务器的用户帐号(cfg_smtp_user):同是否启用smtp方式发送邮件部分
SMTP服务器的用户密码(cfg_smtp_password):同是否启用smtp方式发送邮件部分
删除文章文件同时删除相关附件文件(cfg_upload_switch):删除文档内容时候如果开启了这个选项将清除文档相关附件
网站全局搜索时间限制(cfg_allsearch_limit):如果在使用高级搜索,查询时间大于设置时间数,系统将提示“服务器忙,请稍后搜索”,默认为1,即为1秒。
是否使用伪静态(cfg_rewrite):系统文章内容及栏目使用为静态,默认是关闭这个选项,如果需要启用,如果网站使用通过虚拟主机来定义,请务必加到虚拟主机配置,即 <VirtualHost> 中去,如果加在虚拟主机配置外部将可能无法使用。
注意LoadModule rewrite_module modules/mod_rewrite.so是否禁用;

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(.*)/list-([0-9]+)-([0-9]+)-([0-9]+)/.html$ $1/list.php?tid=$2&TotalResult=$3&PageNo=$4
RewriteRule ^(.*)/view-([0-9]+)-([0-9]+)/.html$ $1/view.php?aid=$2&pageno=$3
</IfModule>
文章回收站(是/否)开启(cfg_delete):文章删除将会默认删除到回收站中,如果需要可以从回收站还原文章内容,系统默认是开启的
附件设置
缩略图默认宽度(cfg_ddimg_width):系统上传缩略图默认宽度
缩略图默认高度(cfg_ddimg_height):系统上传缩略图默认高度
图片浏览器文件类型(cfg_imgtype):图片浏览器浏览的文件类型,默认为jpg|gif|png
允许上传的软件类型(cfg_softtype):系统软件发布支持的软件发布类型,默认为zip|gz|rar|iso|doc|xsl|ppt|wps
允许的多媒体文件类型(cfg_mediatype):系统发布多媒体文件支持的多媒体文件类型,默认为swf|mpg|mp3|rm|rmvb|wmv|wma|wav|mid|mov,可以根据自己的站点需求进行设置
图集默认显示图片的大小(cfg_album_width):图集模型默认显示的图片大小,默认设置为800,可以根据自己需求进行设置
图集多行多列样式默认行数(cfg_album_row):图集显示多行显示默认行数,默认设置为3,可以根据自己需求进行设置
图集多页多图每页显示最大数(cfg_album_pagesize):多页图集显示每页最大的数目,默认设置为12,可以根据自己的需要进行设置
图集默认样式 1为多页多图,2为多页单图,3为缩略图列表(cfg_album_style):图集默认显示的样式,默认为2,多页单图,可以根据自己的需求进行设置
图集默认缩略图大小(cfg_album_ddwidth):图集发布默认缩略图大小,默认设置为200,可以根据自己的需求进行设置
会员设置
是否开启会员功能(cfg_mb_open):系统会员功能是否开启,系统默认是开启的,可以通过/member进行注册、登陆、内容发布等功能
是否开启会员图集功能(cfg_mb_album): 系统会员功能是否开启,系统默认是开启的,可以通过/member进行注册、登陆、内容发布等功能
是否允许会员上传非图片附件(cfg_mb_upload):允许会员上传非图片附件,图片附件包含的设置在图片浏览类型中已经列出,系统默认是开启这个会员上传的权限的
会员长传文件大小(K)(cfg_mb_upload_size): 会员上传文件最大限制,默认为1MB及1024Kb
是否开放会员对自定义模型投稿(cfg_mb_sendall):系统后台可以添加自定义模型,模型中可以设置会员对不同模型内容进行投稿,这里可以设置是否开启会员对自定义模型投稿,默认是开启的
是否把会员指定的远程文档下载到本地(cfg_mb_rmdown):会员发布内容,如果内容中含有图片等文件,开启这个选项将会被下载到服务器,系统默认是开启这个功能的
会员附件许可的类型(cfg_mb_addontype):会员开启上传文件,附件上传的类型,默认设置为swf|mpg|mp3|rm|rmvb|wmv|wma|wav|mid|mov|zip|rar|doc|xsl|ppt|wps,可以根据自己的需要进行设置
会员附件总大小限制(MB)(cfg_mb_max): 会员上传附件最大的空间容量,默认为300MB,可以根据自己需要进行设置
不允许注册的会员id(cfg_cfg_mb_notallow):不允许注册的会员ID,默认www,bbs,ftp,mail,user,users,admin,administrator,用“,”分开,系统注册这些id是默认无法注册的,可以根据需要进行设置
用户id最小长度(cfg_mb_idmin):对用户id进行字数限定,默认最小长度为3,可以根据自己需要进行设置
用户密码最小长度(cfg_mb_pwdmin):对用户密码进行最小长度设置,默认最小长度为3,可以根据自己需要进行设置
是否严格限定会员登入id允许会员使用二级域名必须设置此项(cfg_md_idurl):开启这个选项将对用户的id进行严格限制,系统将可能无法使用中文作为用户id,如果允许用户使用二级域名,将必须设置这个项目,改项目默认是关闭的
注册会员默认级别[会员权限管理中]查看级别代表的数字(cfg_mb_rank):注册的时候用户默认级别,默认值为10,可以通过系统后台[会员]-[会员权限管理],查看具体权限,查看到默认会员级别为注册会员,可以根据自己需要进行相应设置
是否限制Email只能注册一个账号(cfg_md_mailtest):开启后一个e-mail只允许在系统中被使用一次,系统默认是开启的
前 台密码验(cfg_mb_rand)证类型:默认32 — 32位md5,可选:116 — 前16位,r16 — 后16位,m16 — 中间16为(cfg_mb_pwdtype):会员注册登陆等默认密码的验证类型,系统默认为32位,如果早期版本中密码类型进行设置不同的需要对其重新 设置
(是/否)开启分页标题,开启会影响HTML生成速度(cfg_arcsptitle):如果开启了这个函数,将启用分页标题,我们在发布 普通文章的时候 会在编辑器看到添加“#p#副标题#e#”这个代码,开启后分页标题的功能才可以使用,不过需要在模板中加入{dede:pagetitle style=’select’/}标签
(是/否)开启长文章自动分页(cfg_arcautosp):开启后,系统自动判断内容大小进行自动分页,系统默认是关闭的
文章自动分页大小(单位:K)(cfg_arcautosp_size):开启自动分页后的内容长度,默认为5K,如果内容大于5K自动分到第二页
上级列表是否包含子类内容(cfg_list_son):列表页是否显示下级列表的内容,如果开启则显示下级列表的内容,系统默认是开启这个选项的
发布文档后自动更新网站主页(cfg_makeindex):发布内容后将自动更新网站主页,但这样比较影响系统性能,建议关闭这个选项自动进行更新
使用关键词关连文章(cfg_keyword_like):使用文档关键词来关联相应的文章,系统默认是关闭的
网站主页调用函数最大索引文档数 不适用于经常单栏目采集过多内容的网站 不启用本项此值设置为0即可(cfg_index_max):网站主页调用函数最大索引文档数 不适用于经常单栏目采集过多内容的网站,默认是10000即首页调用最大索引文档数为10000
Arclist标签调用缓存(0 不启用,大于0值为多少秒)(cfg_index_cache):arclist标签缓存,缓存将增强网站性能,但不能实时更新站点标签信息,系统默认设置为7200秒,可以根据自己需要设置,0为关闭缓存
是否启用模板缓存(cfg_tplcache):模板缓存将增强模板解析性能,但可能会影响生成速率,系统默认是开启模板缓存的,可以根据自己需要进行设置
模板缓存目录(cfg_tplcache_dir):模板缓存所保存的目录
发布、修改单个文档是否使用调用缓存(cfg_makesign_cache):发布、修改单个文档是否使用调用缓存
最大搜索检查文档数(cfg_search_max):最大搜索检查文档数,默认为50000
最大返回搜索结果数(cfg_search_maxrc):搜索后最大返回搜索结果数,默认为300
搜索间隔时间(秒、对网站所有用户)(cfg_search_time):搜索内容间隔时间,默认为3秒
是否启用副栏目(cfg_need_typeid2):开启后可以使用副栏目功能,同一文档能够在不同栏目中进行显示
Id文档ID,content 标签最终内容(修改此变量后必须更新系统缓存)(cfg_cache_type):如果用id,那么生成HTML是从缓存读取id并查询一次,如果是内容,即是指标签最终生成的html,这样就不用再查数据库

其他选项

自动摘要长度(0-250,0表示不启用)(cfg_auot_description):自动摘要长度(0-250,0表示不启用): 系统文章发布自动摘要长度,默认为240,这个选项有利于系统SEO,推荐使用默认设置,可以根据自己需要进行设置
远程图片本地化(cfg_rm_remote):远程图片本地化: 在发布HTML内容时候粘贴远程图片,开启这个选项将会把图片默认下载到服务器上,系统默认开启这个选项
删除非站内链接(cfg_arc_dellink):删除非站内链接: 在发布HTML内容时候,会去除非本站内的超链接内容,在单独的内容发布处也有这个选项
提取第一张图片作为缩略图(cfg_arc_autopic):提取第一张图片作为缩略图:将HTML内容中第一章图片作为当前内容的缩略图进行显示
自动提取关键字(cfg_arc_autokeyword):自动提取关键字:发布内容,如果没有设置关键字,开启本选项会自动根据已发布内容提取文档的关键词,系统默认开启这个项目
文档标题最大长度 改此参数后需要手工修改数据表(cfg_title_maxlen):文档标题最大长度 改此参数后需要手工修改数据表: 发布文章标题的最大长度,默认是60,如果需要修改为更多需要修改数据库相关字段
后台调试模板标记是否禁止使用函数 这个选项可以防止非权限管理利用标记调试进行非法操作(cfg_notallow_tplfunc):后台调试模板标记是否禁止使用函数 这个选项可以防止非权限管理员利用标记调试进行非法操作
发布文档时是否检测重复标题(cfg_check_title):发布文档时是否检测重复标题: 发布文档时候如果有重复标题对其进行检测,系统默认开启这个项目
百度新闻xml更新新闻数量 最大100(cfg_baidunews_limit):百度新闻xml更新新闻数量 最大100: 百度新闻xml更新新闻数量,默认为100
百度新闻xml更新时间(单位:分钟)(cfg_updateperi):百度新闻xml更新时间 (单位:分钟): 百度新闻自动更新时间,默认为15分钟
文档内容同一关键词替换次数(0为全部替换)(cfg_riplace_num):文档内容同一关键词替换次数(0为全部替换): 文档中的关键词替换的次数,默认为0,即全部替换,用户可以根据自己需要进行设定

检举回答人的补充    2009-09-06 01:49 {dede:global.cfg_webname/} 站点名称
{dede:global.cfg_basehost/} 站点url(后台设置)
{dede:global.cfg_cmsurl/} 站点实际url(奇奇推荐)
{dede:global.cfg_memberurl/} 会员中心地址
{dede:global.cfg_dataurl/} 站点data目录地址
{dede:global.cfg_templeturl/} 模板目录地址
{dede:global.cfg_powerby/} 底部版权
{dede:global.cfg_beian/} 备案信息

{dede:field.description function=’html2text(@me)’/} 站点描述
{dede:field.phpurl/} 站点plus目录站点地址
{dede:field.title/} 标题
{dede:field.keywords/} 关键字

{dede:flink row=’24’/}友情链接

{dede:field.content/} 栏目内容

{dede:field.position/} 当前位置
{dede:field.pubdate function=”MyDate(‘Y-m-d H:i’,@me)”/} 时间
{dede:field.source/} 来源
{dede:field.writer/} 作者
<script src=”{dede:field name=’phpurl’/}/count.php?view=yes&aid={dede:field name=’id’/}&mid={dede:field name=’mid’/}” type=’text/JavaScript’ language=”JavaScript”></script> 点击次数
{dede:field.body/} 文章内容
{dede:adminname/} 责任编辑
{dede:pagebreak/} 页码
{dede:prenext get=’pre’/} 上一篇
{dede:prenext get=’next’/} 下一篇

导航
{dede:channel type=’self’ currentstyle=”<span><a href=’~typelink~’ class=’thisclass’>~typename~</a></span>”}
<span><a href='[field:typeurl/]’>[field:typename/]</a></span>{/dede:channel}

{dede:include filename=”*.htm”/} 调用模板文件
{dede:memberinfos}
<a href=”[field:spaceurl /]” class=”userface”><img src=”[field:face/]” width=”52″ height=”52″ /></a> 头像
<a href='[field:spaceurl /]’ class=”username”>[field:uname/]</a> 用户名
<a href=”[field:spaceurl /]” class=”useract-vi”>查看详细资料</a>
<a href=”[field:spaceurl /]&action=guestbook” class=”useract-pm”>发送留言</a>
<a href=”[field:spaceurl /]&action=newfriend” class=”useract-af”>加为好友</a>
用户等级:</small>[field:rankname /]
注册时间:</small>[field:jointime function=”MyDate(‘Y-m-d H:m’,@me)”/]
最后登录:</small>[field:logintime function=”MyDate(‘Y-m-d H:m’,@me)”/]
{/dede:memberinfos}

<a href=”{dede:field name=’phpurl’/}/stow.php?aid={dede:field.id/}” target=”_blank”>收藏</a>
<a href=”{dede:field name=’phpurl’/}/erraddsave.php?aid={dede:field.id/}&title={dede:field.title/}” target=”_blank”>挑错</a>
<a href=”{dede:field name=’phpurl’/}/recommend.php?aid={dede:field.id/}” target=”_blank”>推荐</a>
<a href=”#” onClick=”window.print();”>打印</a>

文档列表
{dede:arclist titlelen=42 row=10}
<li><a href=”[field:arcurl/]”>[field:title/]</a>
<p>[field:description function=’cn_substr(@me,80)’/]…</p>
</li>{/dede:arclist}

转自:http://blog.csdn.net/crazypmer/article/details/5103874

[转载]简单的ASP.NET MVC实现层叠的Ajax下拉

mikel阅读(814)

[转载]简单的MVC实现层叠的Ajax下拉 – caling – 博客园.

项目已经接近尾声了,回顾下之前项目整体实现,运用到技术,总结下。

界面主要以MVC2+JQuery来实现,数据存储主要以接口wcf来进行数据传输。整体来看界面中大量运用到JQuery,看着那一堆堆js,不知有何冲动,因为之前也接触过3的一些新特性及其有了一点了解,于是写了一个ajax层叠下拉效果,代码很清晰:

1,首先先定义导入jQuery库和css,在这里我定义一个_Layout.cshtml页面

 
 

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
</head>
<body>
    @RenderBody()

</body>
</html>

 

2,再定义一个cshtml页面,用于显示,并把之前定义的页面导入该页面


 

@model MvcApplication1.Models.ProductCatalog
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<table cellpadding="0" cellspacing="4" border="0">
    <tr>
        <td>第一级&nbsp;</td>
        <td>&nbsp;:</td>
        <td>@Html.Partial("CategoriesUserControl", Model)</td>
    </tr>
    <tr>
        <td>第二级&nbsp;</td>
        <td>&nbsp;:</td>
        <td><div id="SubCategories">@Html.Partial("SubCategoriesUserControl", Model)</div></td>
    </tr>
    <tr>
        <td>第三级&nbsp;</td>
        <td>&nbsp;:</td>
        <td><div id="Products">@Html.Partial("ProductsUserControl", Model)</div></td>
    </tr>
</table>

3,接下来定义controller

  [HttpPost]
        public ActionResult SelectCategory(int? selectedCategoryId)
        {
            ProductCatalog productCatalog = new ProductCatalog();
            productCatalog.SubCategories = new List<SubCategory>();

            if (selectedCategoryId.HasValue)
            {
                productCatalog.SubCategories = (from s in ProductCatalog.GetSubCategories()
                                                where s.CategoryId == selectedCategoryId
                                                orderby s.Name
                                                select s).ToList();
            }

            return PartialView("SubCategoriesUserControl", productCatalog);

        }
  

这里是一post方式提交.最终返回一个视图页面:第一个下拉返回SubCategoriesUserControl.cshtml页面,然后再SubCategoriesUserControl页面上定义

@model MvcApplication1.Models.ProductCatalog
@if (Model.SubCategories != null && Model.SubCategories.Count() > 0)
{
    using (Ajax.BeginForm("SelectSubCategory", "CascadingDropDown", new AjaxOptions { UpdateTargetId = "Products" }))
    { 
    @Html.HiddenFor(m => m.SelectedCategoryId)
    @Html.DropDownListFor(
            m => m.SelectedSubCategoryId,
            new SelectList(Model.SubCategories, "Id", "Name"),
            string.Empty
            )
    }
}
<script type="text/javascript">
    $('#SelectedSubCategoryId').change(function () {
        $(this).parents('form').submit();
    });   
</script>

这里用change事件触发下拉,以post方式提交页面数据。这种方式很清楚,也是当成了自定义控件方式来进行调用。第二级的层叠下拉和第一级一样。

代码就不贴上了,

[转载].NET中序列化和持久化(二)

mikel阅读(974)

[转载].NET中序列化和持久化(二) – 人道编程 – 博客园.

导航:

.NET中序列化和持久化(一)

—————————————————————————————————————————-

上节说到序列化和反序列化类中的值成员,我们也知道,类中的成员不当当只是值成员还有引用类型,现在我们就介如何序列化引用类型、不可序列、序列化成SOAP格式的文件

序列化引用类型

序列化类默认的情况下是要求他的所有的成员都是要可序列化的(除事件、委托、显式定义不可序列化)

现在我对之前的例子进行改造,例子如下:

[Serializable]
public class MyClass
{
public string Name
{
get;
set;
}
public int Age
{
get;
set;
}
public Work MyWork
{
get;
set;
}
}

[Serializable]
public class Work
{
public string Name
{
set;
get;
}
public string Address
{
set;
get;
}
}

其实很简单的,就是把MyClass类中有的类成员都加上为[Serializable]属性即可,.NET会去MyClass中遍历所有的成员, 智能的跳过类的循环引用。如果MyClass中的Work类型不加[Serializable]属性,那就是说Work不可序列化,那.NET就会报出错 误。

不可序列化成员

如果你在MyClass中有个SQLConnection类型成 员,大家都知道SQLConnection中管理的是数据库的连接,不好被序列化,所以我们在设计的时候不能把SqlConnection序列化了,我们 要在SqlConnection的成员中把它加上 [NonSerialized]属性告诉.NET这个类不要被序列化,当反序列化的时候SqlConnection就为null,例子如下:

[Serializable]
public class MyClass
{
public string Name
{
get;
set;
}
public int Age
{
get;
set;
}
[NonSerialized]
Work myWork;

public Work MyWork
{
get
{
return myWork;
}
set
{
myWork = value;
}
}
}

public class Work
{
public string Name
{
set;
get;
}
public string Address
{
set;
get;
}
}

这样Work对像就不会被序列化到文件流中,当被反序列化时就MyWork属性就为null了。

序列化SOAP文件

要序列化成SOAP就要先用引用System.Runtime.Serialization.Formatters.Soap命名空间中的SoapFormatter类了。SoapFormatter是一个Soap的格式器

例子如下:

    [Serializable]
    public class MyClass
    {
        public string Name
        {
            get;
            set;
        }
        public int Age
        {
            get;
            set;
        }
        public Work MyWork
        {
            get;
            set;
        }
    }

    [Serializable]
    public class Work
    {
        public string Name
        {
            set;
            get;
        }
        public string Address
        {
            set;
            get;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyClass my = new MyClass();
            my.Name = "凤姐";
            my.Age = int.MaxValue;

            Work work = new Work();
            work.Address = "你家隔壁";
            work.Name = "不知道";
            my.MyWork = work;

            //这里new 的是Soap格式的了
            System.Runtime.Serialization.IFormatter formatter = new SoapFormatter();

            //创建一个文件流
            Stream stream = new FileStream(@"c:\MyClass.xml", FileMode.Create, FileAccess.Write);

            using (stream)
            {
                //这里就是进行序列化了
                formatter.Serialize(stream, my);
            }
        }
    }

这样子就把”凤姐”这个对像序列成SOAP格式,生成到你的C盘里了(你可以郁闷下哇哈哈哈),文件内容如下

<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<a1:MyClass id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/ConsoleApplication1/ConsoleApplication1%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull">
<_x003C_Name_x003E_k__BackingField id="ref-3">凤姐</_x003C_Name_x003E_k__BackingField>
<_x003C_Age_x003E_k__BackingField>2147483647</_x003C_Age_x003E_k__BackingField>
<_x003C_MyWork_x003E_k__BackingField href="#ref-4"/>
</a1:MyClass>
<a1:Work id="ref-4" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/ConsoleApplication1/ConsoleApplication1%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull">
<_x003C_Name_x003E_k__BackingField id="ref-5">不知道</_x003C_Name_x003E_k__BackingField>
<_x003C_Address_x003E_k__BackingField id="ref-6">你家隔壁</_x003C_Address_x003E_k__BackingField>
</a1:Work>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

SOAP格式的序列化文件就有一定的可读性了,这样就可以更好的跨平台的反序列化对像了。不过从速度上来说,当然还是二进制文件更快,可是二进制文件不好进行跨平台的反序列化,各有各的优点吧。

这节说完了,下节我们我该讲该如何用泛型格式器序列化对像。

[转载]发一个关于新浪微博“微笑天使包燕娜"事件的Code Review,希望对大家有用。

mikel阅读(1226)

[转载]发一个关于“微笑天使包燕娜”事件的Code Review,希望对大家有用。 – 摇滚诗人 – 博客园.

以下是对“微笑天使包燕娜”事件的Code Review:
1.    问题现象
新用户在iPhone客户端在用新浪微博登录时,用户的名称自动变为“微笑天使包燕娜”。
2.    现象分析
先说明咱们的新用户登录流程,
A.    新用户登录时首先向第三方平台,请求用户的用户id(uid)
B.    客户端将此uid发送到咱们自己的服务器,服务器返回此用户的uid与数据库对比返回,此用户是一个新用户
C.    客户端收到服务器发送的此用户为新用户的信息,再次利用用户的uid向第三方平台发送请求用户具体信息的消息。
D.    第三方服务器返回用户的具体信息后,客户端再将此信息发送到咱们自己的服务器上保存。
E.    服务器返回修改过新的用户数据,客户端保存,登录过程完毕。

通过对登录过程的log信息进行分析发现,在A和B阶段得到的uid,与C阶段发送的uid不相同。
改变后的uid一直为2147483647。此uid对应新浪微博的用户”微笑天使包燕娜”,因此返回给咱们自己服务器的用户数据一直是这个名称。
继续定位发现在新浪SDK中,向新浪服务器发送获得用户详细信息(C过程)请求之前,代码进行了一次将uid字符串转换为int,再转换为字符串的过程。 而当用户uid非常大,大于int的最大值(2147483647)时,此时uid被转换为int的最大值2147483647。
因此,发送到新浪的uid会一直是“2147483647”。

3.    解决问题
在新浪的SDK的WeiboClient类中,将转换int的代码去掉并修改接口直接将字符串传入发送请求的函数中,问题解决。
修改后的代码如下:
– (void)getUser:(NSString *)userId
{
needAuth = YES;
NSString *path = [NSString stringWithFormat:@”users/show.%@”, API_FORMAT];
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:0];
[params setObject: userId forKey:@”user_id”];
[super get:[self getURL:path queryParameters:params]];
}