努力读书不如论坛看贴
2009年4月16日 #
MSCRM提供了记录的共享功能,其中可共享的有:Read,Write,Delete,Append,Assign,Share六种权限。我们可以将一条或多条记录共享给某些User或Team。
假设我们要共享Account的多条记录给某些User或Team。
选择要共享的记录 -> "More Actions" -> "Sharing..."
点击"Add User/Team",在弹出的Lookup Records对话框中选择User或Team:
点击“OK”后,我们就可以对选择的User或Team设置要共享的权限:
点击“OK” 我们就完成了将选择的记录共享给设定的User或Team。
由上面的操作我们可以看到,我们必须每次手动的对要共享的记录进行设置。这样做非常的麻烦,因为我们在很多业务逻辑中要求对满足条件的记录系统自动地共享给某些User或某些Team。
我们可以扩展自定义工作流来实现这个目的。
下面是我写的一个可以实现自动共享的自定义Workflow。(同时我也提供了安装程序和卸载程序,文后提供下载)
安装完成后我们可以看到在Add Step处多了个菜单项 “Automatic Sharing”,其中包括两个子菜单“Share To User” 和 “Share To Team”:
点击“Share To User” ->“Set Properties” ,
在弹出的“Set Custom Step Input Properties” 对话框中可以设置要共享给的User,以及共享哪些权限。
当此工作流Publish后,引发工作流的记录就会自动地被共享。
本文安装及卸载程序下载:点击下载
2008年12月14日 #
2008年7月19日 #
刚看了一下自己的博客,最近的一次写文章还是去年六月,到现在也一年多了。这一年来也时常打开看看,有的时候也真的把平时工作的点滴积累记录一下,一来可以在以后用到的时候翻翻作为参考,二来也可以给一些新入门的朋友一些帮助吧。
这一年来其实自己在技术上也没有很长足的长进。期间换了份工作,也想了很多以后的路怎么走。所以在换工作的时候也就特别慎重。挑了很多公司,有做网络的,有网站的,有行业应用的。有做服务的。有做外包的等等,这也一度让我很迷惘。
现在是在做Microsoft Dynamics CRM的开发工作。Dynamics CRM目前在中国国内应用还比较少。所以开发过程中也遇到不少问题国内的论坛及搜索引擎也极少有介绍。于是看了不少国外的技术性网站。结合微软给的不太健全的SDK帮助文档到现在总算对部分扩展开发应用还有点了解。只是还不够深入,这需要继续努力。正由于经常看老外的技术性文章对自己的英文阅读能力也有所提高。虽然接触Dynamics CRM时间还不是很长但我真的被它强大的可配置功能及扩展应用功能所深深吸引,也因为国内搞这方面开发的人还真的很少。所以目前也有一点意向决定以后就顺着这条路走下去了。国外公司应用的还比较多,不知道未来微软CRM在中国国内市场的营销计划和他们对这款产品的支持力度如何了,可真的不能让我失望啊。呵呵。
之前做过网站,做过外包。做过自己的产品...,感觉都比较迷惘,或许也是国内整个软件行业都这么让人迷惘的原因吧。放眼招聘网,搜索一下职位,什么 中软,海辉,微创,软通,文思创新,惠普...这些人才外包的公司招聘职位占了七成。最后的命运也就是被卖来卖去。这些公司从中赚取血汗钱。美其名曰:人才外包。这也就是中国廉价人力资本吸引国外一些公司的最大原因吧。软件行业更也不是例外。所以我们这些从业人员也就难免经常会感到迷惘而不清楚今后的路怎么走。而且中国有个怪现状。那就是招聘要求里明明白白的表明必须35岁以下。虽然自己还要若干年后才达到这一个无聊的门槛,但也非常抱怨及难过的想问问那些公司,难道超过35岁就一文不值了吗?那些新入行的小弟们真的能挑得起大梁比那些走过接近十年的前辈们更有能力些吗?还是从人力资本上考虑继续压榨而获取更多的利润?
哎,不说了,说多了让人感觉我像个愤青, 做好当前自己要做的事,努力提高自己,充实自己才是最重要。有时间我会陆续发一些关于自己在Microsoft Dynamics CRM开发方面的经验。也希望和同行们一道共同提高。大家共同探讨! 明知道被剥削也不能忘记提高自己的脚步啊 :)不然连被剥削的机会都没有:(
2007年6月19日 #
限定符的概念:
非显式限定符(3 个): *:出现0或多次 +:出现1或多次 ?:出现0或1次
显式限定符: 使用显式限定符则可准确指定数字、范围或数字集, 显式限定符使用花括号 {} 及其中的数字值表示模式出现次数的上下限
a{5} : 准确匹配5个字符"a" a{,5}: 0到5个字符"a" a{5,} 5到任意个字符"a" a{2,3} 2到3个字符"a"
元字符的概念:
在正则表达式中,有一种意义特殊的构造,即元字符 。如:* ? + { } $ ^ . [ ( | ) ] \
.: 它可匹配任何单字符 ^ : 可指定字符串(或行)的开始 $ : 可指定字符串(或行)的结束 \ (反斜杠): 如果要匹配元字符,必须使用反斜杠进行"转义"。 | (管道): a|b 将匹配包含"a"或"b"的任何输入内容 括号(): 用于给模式分组,它允许使用限定符让一个完整模式出现多次,如:(ab){2,3}模式匹配abab,ababab
字符类的概念: 在方括号 [ ] 中定义, 格式如:[字符表],它仅匹配字符表中的一个字符 指定任何数值数字: [0123456789] 使用连字符(-) 来定义字符的范围 [0-9],[a-z],[A-Z] 仅在连字符不是第一个字符时,连字符才在字符类中有特殊含义,如果需要在范围中包括连字符,将它指定为第一个字符
注意, 1.正则表达式元字符在字符类中不做特殊处理,所以这些元字符不需要转义
字符类是与其他正则表达式语言分开的一种语言,字符类有自己的规则和语法:字符 ^ : 表示否定此类, 如:[^123456]匹配除123456以外的字符.注: 1. ^ 在字符类中的作用与它在正则表达式模式中的作用完全不同。 2. 如果要否定连字符(-),应将连字符作为字符类的第二个字符,如 ^[^-][0-9]$ 匹配 0、1、2、... (不匹配 -0、-1、 -2 等)
正则表达式库 http://www.regexlib.com/
正则表达式讨论列表 http://aspadvice.com/login.aspx?ReturnUrl=%2fSignUp%2flist.aspx%3fl%3d68%26c%3d16&l=68&c=16
正则表达式论坛 http://forums.regexadvice.com/
正则表达式 Web 日志 http://blogs.regexadvice.com/
Mastering Regular Expressions (O'Reilly),作者 Jeffrey Friedl http://www.regex.info/
.NET 正则表达式参考 http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemTextRegularExpressions.asp
Jscript 正则表达式语法 http://www.msdn.microsoft.com/library/en-us/script56/html/js56jsgrpRegExpSyntax.asp
正则表达式信息 http://www.regular-expressions.info/
2007年3月31日 #
A:请写一个文件拷贝函数。
Q:你说的"拷贝"是什么意思?
A:嗯。。。。就是把一个文件的内容拷贝到新的文件
Q:考不考虑日期/时间?
A:不用,那些不用被拷贝。
Q:目标文件可以和源文件同名么?
A:嗯。。。不行
Q:那我不用担心假名攻击(name spoofing)?比如说土耳其语的I。(注意哈,土耳其语的I有四种写法,和英语的I相似而不同)。
A:不用担心。
Q:文件属性呢?
A:新文件和老文件的属性一样
Q:那我应该修改老文件的属性么?如果这个拷贝操作时备份或者存档操作的一部分,那可能不应该保留'Archive'这个属性。
A:不用,保持原样就行了。
Q:那万一源文件的'Archive'属性被关掉了呢?如果新文件的这个属性也被我关掉,可能会搞坏用户的备份软件。
A:就让它们一样。我不在乎用户的备份软件。
Q:这样为用户设计软件好像不好吧?
A:。。。
Q:文件压缩怎么办?这是个文件属性,但拷贝目的地不一定支持压缩。
A:不用管文件压缩。
Q:哪怕源文件被压缩了,而拷贝目的地不支持压缩?
A:对头!
Q:那加密呢?如果源文件被加了密,而拷贝目的地不支持加密?
A:如果目的地不支持加密就不要加密。
Q:哎呀不好意思,我不是想岔开话题。不过。。。这样不是很大的安全隐患么?特别当这个文件拷贝函数支持任意多个参数的时候(直接或者间接)。
A:靠!他妈的把文件拷贝过去就行了!
Q:创建文件的用户呢?
A:不用管。
Q:那文件的所有人呢?
Q:那文件权限呢?有没有啥么方法来处理继承的权限和赋予的权限?
A:不要管权限了。
Q:那这个函数会在什么系统上运行?
A:Windows XP
Q:Home, Pro, Media Center,或者多于一个版本?
A:Pro
Q:哪一个Service Pack?
A:SP2
Q:也就是说我们不用支持其它的Service Pack?
A:对阿
Q:咋个提供源文件名?
A:用参数传进去。
Q:那则个参数十一个以null结尾的字符串,一个计数的字符串(学Pascal的都知道哈),还是一个对象?
A:以Null计数的字符串。
Q:Null指针可能被传进去么?
A:不可能。
Q:那文件名的编码呢?
A:Unicode。
Q:不好意思,这个这个。。。Unicode不能算编码。如果我们用Unicode数据,我们必须知道具体的编码,比如UTF-8, UCS-2, UTF-16,等等。
A:你够狠!UTF-8。
Q:好嘛。我只是想说把UTF-8转换成UTF-16,好让Windows API调用工作,还是有点痛苦的。
A:射!UTF-8!
Q:Big-endian还是small-endian?
A:啊―――随便你丫的!
Q:那我们接受相对路径还是绝对路径?
A:就绝对路径。
Q:那些路径有没有什么需要过滤的特征?
A:没有。用户自己搞定。
Q:怎么生成目标文件名?或者用户提供?
Q:要不要(或者允不允许)我提供异步拷贝操作?
A:不。
Q:我该怎么报错?Exception?Error code?
A:随便。
Q:我是该在被调用的函数内部处理错误呢,还是把错误传给调用者?
A:嗯。。。传出去。
Q:如果目标文件已经存在怎么办?
A:不会的。
Q:也就是调用人确保这点?
A:对。
Q:也就是说如果目标文件的确存在,我可以立刻终结程序运行?但这个明显违背了前置条件,而且鬼才知道会出什么问题。
A:射。随你丫的。
Q:那轮换数据流呢?
A:随便你!!
Q:老大,我真地不好意思,如果你觉得被我挑衅了。不要生气哈。我只是想在动手前得到一个清晰完整的规格。很明显如果我要写一个文件拷贝函数,而不是用各种库里现成的文件函数,这个新的函数需要满足某套特殊需求,所以我需要知道那些问题的确切答案。如果你无所谓,我可以在一分钟内整出一个函数来,但肯定有很多问题都没有解决。
A:啊!!!!!!!!!!!!!!!!!!!!!!!!
2006年12月1日 #
2006年11月29日 #
1.匿名方法
在C#1.0中典型的给一个委托添加一个方法调用代码如下:private void ctrl_Click (object sender,EventArgs e)txt.Click += new MyDelegate(ctrl_Click);private ctrl_Click(object sender,EventArgs e){ Message.Show(...);}哪怕只有这么一条语句也必须得按上面的形式给事件的调用列表添加方法,还得创建一个委托的实例
在C#2.0中引入了匿名方法,大大简化了上述操作可以改写为txt.Click += delegate {Message.Show();}或是这样:txt.Click += ctrl_Click也是允许的.
C#编译器对上述的定义自动隐式转化,只要匿名方法和委托的定义兼容.符合下列条件可以兼容1.参数兼容如果匿名方法没有参数,委托中没有out参数如果匿名方法和委托的参数在数量,类型,顺序上都一致2.返回值兼容如果委托没有返回值,匿名方法中也没有返回值或匿名方法中只有return不带返回值如果两者都有返回值,并且匿名方法的返回值可以隐式转化为委托定义的类型
符合参数和返回值兼容的就可以使用匿名方法
匿名方法的捕获变量(capture variable)
如果局部变量或参数的作用范围内包含匿名方法声明,则该局部变量或参数称为该匿名方法的外部变量或捕获变量
public void method1(bool enabled){ string b; this.txt.Click += delegate { this.txt.enabled = enabled; this.txt.Text = b; }}
对于这个匿名方法来说:参数enabled和变量a是它的捕获变量或叫外部变量.捕获变量的生命周期直到此匿名方法的资源被回收而结束
2.泛型关于泛型的定义及如何使用网上资料已经很多,请参见MSDN
3.迭代器(iterators)
在C#1.0中若想要使得类型成为可枚举的类型(即象使用数组一样用foreach一样枚举数组中的成员),那么这个类中必须实现IEnumerable接口的GetEnumerator()方法返回IEnumeratorpublic IEnumerator GetEnumerator(){..}一般来说实现GetEnumerator是不容易的.
在C#2.0中引入了的新的语法扩充:迭代器,它能够很好的简单方便的让我们实现GetEnumerator()方法如:public IEnumerator GetEnumerator(){ for ( int i = 0; i < 10; i ++) { yield return i; }}
假设类Class1中实现了上述的GetEnumertor方法那我们就可以用foreach对类Class1进行枚举Class1 c = new Class1;foreach ( int i in c){ Console.WriteLine(i);}
yield return产生迭代的下一个值,yield break说明迭代完成,用迭代器实现就是这么简单.
定义和使用命名迭代器
class Class1 { public IEnumerator GetEnumerator() { for (int i = 0; i < 10; i++) { yield return i; } }
// 定义一个命名的迭代器,并可以提供参数 public IEnumerable MaxToMin(int min, int max) { for (int i = max; i >= min; i--) { yield return i; } }
// 定义一个迭代器类型的属性, public IEnumerable MinToMax { // this表示该类实例,因为该类实现了GetEnumerator(),它是可枚举的 get { yield return this; } }
public IEnumerable GetDescriptions() { yield return "this is my test"; yield return "class name is class1"; yield return "ktgu"; } }
static void Main(string[] args) { Class1 c = new Class1();
foreach (int i in c) { Console.WriteLine(i); }
foreach (int i in c.MaxToMin(1, 10)) { Console.WriteLine(i); }
foreach (int i in c.MinToMax) { Console.WriteLine(i); }
foreach (string s in c.GetDescriptions()) { Console.WriteLine(s); } }
4.不完整代码C#2.0中引入了一个"不全代码"的概念,即你可以将一个类的定义放在别的文件中.这样给大项目,大文件的维护带来方便.声明:[modifiers] partial typemodifier: [public/private/protected/internal] abstract new override static virtual extern type:类/结构/接口
以上主要是偏向于介绍如何快速的应用这些新的语法点,详细概念及要领请参见MSDN
2006年11月28日 #
委托的声明
public delegate void MyDelegate(string str);注1.委托的定义和方法的定义类似,只是在前面加了一个delegate,但委托不是方法,它是一种类型。是一种特殊的类型,看成是一种新的对象类型比较好理解。用于对与该委托有相
同签名的方法调用。2.委托相当于C++中的函数指针,但它是类型安全的。3.委托是从System.Delegate派生,但不能象定义常规类型一样直接从System.Delegate派生,对委托的声明只能通过上面的声明格式进行定义。关键字delegate通知编译器这是一
个委托类型,从而在编译的时候对该类进行封装,对这一过程C#定义了专门的语法来处理这一过程。4.不能从一个委托类型进行派生,因为它也是默认sealed的5.委托即可以对静态方法进行调用也可以对实例方法进行调用。6.每个委托类型包含一个自己的调用列表,当组合一个委托或从一个委托中删除一个委托时都将产生个新的调用列表。7.两个不同类型的委托即使它们有相同的签名和返回值,但还是两个不同类型的委托。但其实在使用中可看作是相同的。
委托的比较
C#中对委托定义了两个操作符 == 和 !=在以下情况下两个委托是相等的:1.当两个委托都同时为null的时候2.当两个委托都不为null时,下列情况下是相等的。a.当两个委托的各自的调用列表只含有一个入口点的时候 在下列情况下是相等的 (1) 调用同一对象的同一静态方法 (2) 调用同一对象的同一实例方法b.当两个委托具有多个入口点时 在下列情况下是相等的 (1)只有当它们调用列表中的调用的方法按顺序都一一对应相同的对象及对象的同一方法的时候
如上所述的两个不同类型的委托但是它们具有相同的签名和返回值时,只要满足上述条件的,即使它们类型不同,但比较的结果也是相同的。
委托的异常处理
当调用该委托的方法中发生了异常时,首先在调用该委托的方法中搜寻catch语句块。如果没有,则去该委托调用的方法中去寻找有没有catch语句块,这和调用方法发生异常的处
理是一样的。
当调用一个为null的委托即委托中列表中不存在调用方法时,将发生NullRefrenceException
委托的注意点:当一个委托有多个入口点的时候,调用委托将依该委托的调用列表中的方法的顺序依次调用.这些方法共享一个参数集合,所以当委托有返回值的时候调用完这个委托后的返回值是最
后一个方法的返回值或是有out参数.如果该委托的参数为ref(引用类型),那么在招待第一个方法的时候如果对这个参数的值有所改变,那么这个改变将会影响到后面的方法调用.
委托的一个例子
using System;using System.Collections.Generic;using System.Text;
namespace ConsoleApplication1{ class Program { static void Main(string[] args) { // 创建一个委托实例,封装C类的静态方法M1 MyDelegate d1 = new MyDelegate(C.M1); d1("D1"); // M1
// 创建一个委托实例,封装C类的静态方法M2 MyDelegate d2 = new MyDelegate(C.M2); d2("D2"); // M2
// 创建一个委托实例,封装C类的实例方法M3 MyDelegate d3 = new MyDelegate(new C().M3); d3("D3"); // M3
// 从一个委托d3创建一个委托实例 MyDelegate d4 = new MyDelegate(d3); d4("D4"); // M3
// 组合两个委托 MyDelegate d5 = d1 + d2; d5 += d3; d5("D5"); // M1,M2,M3
// 从组合委托中删除d3 MyDelegate d6 = d5 - d3; d6("D6"); // M1,M2 d6 -= d3; // 虽然d6调用列表中已经没有d3了,但这样只是不可能的移除没有错误发生 d6("D6"); // M1,M2 d6 -= d6; //d6("D6"); 此时d6的调用列表为空,d6为null,所以引发System.NullReferenceException
MyDelegate d7 = new MyDelegate(C1.P1); d7("D7"); // C1.P1
MyDelegate d8 = new MyDelegate(new C2().P1); d8("D8"); // C2.P1
} }
// 声明一个委托MyDelegate public delegate void MyDelegate(string str);
public class C { public static void M1(string str) { Console.WriteLine("From:C.M1: {0}", str); }
public static void M2(string str) { Console.WriteLine("From:C.M2: {0}", str); }
public void M3(string str) { Console.WriteLine("From:C.M3: {0}", str); } }
public class C1 { public static void P1(string str) { Console.WriteLine("From:C1.P1: {0}", str); } }
public class C2 { public void P1(string str) { Console.WriteLine("From:C2.P1: {0}", str); } } }
事件委托
事件概述
事件就是当对象或类状态发生改变时,对象或类发出的信息或通知。发出信息的对象或类称为"事件源",对事件进行处理的方法称为"接收者",通常事件源在发出状态改变信息时,它
并不知道由哪个事件接收者来处理.这就需要一种管理机制来协调事件源和接收者,C++中通过函数指针来完成的.在C#中事件使用委托来为触发时将调用的方法提供类型安全的封装
事件的声明
1.声明一个委托public delegate void EventHandler(object sender, System.EventArgs e);
2.声明一个事件public event EventHandler Changed;
3.引发一个事件public OnChanged(EnventArgs e){ if ( Changed != null) { Changed(this,e); }}
4.定义事件处理程序public MyText_OnChanged(Object sender,EventArgs e){ ...}
5.订阅事件(将事件处理程序添加到事件的调用列表中)
myText.Changed += EventHandler(MyText_OnChanged);
下面的一个小例子说明了怎样定义一个完整的事件机制:
namespace ConsoleApplication1{ class Program { static void Main(string[] args) { MyText myText = new MyText();
// 将事件处理程序添加到事件的调用列表中(即事件布线) myText.Changed += new MyText.ChangedEventHandler(myText_Changed); string str = ""; while (str != "quit") { Console.WriteLine("please enter a string:"); str = Console.ReadLine(); myText.Text = str; } }
// 对Change事件处理的程序 private static void myText_Changed(object sender, EventArgs e) { Console.WriteLine("text has been changed :{0}\n" ,((MyText)sender).Text); } }
public class MyText { private string _text = "";
// 定义事件的委托 public delegate void ChangedEventHandler(object sender, EventArgs e);
// 定义一个事件 public event ChangedEventHandler Changed;
// 用以触发Change事件 protected virtual void OnChanged(EventArgs e) { if (this.Changed != null) this.Changed(this, e); }
// Text属性 public string Text { get { return this._text; } set { this._text = value; // 文本改变时触发Change事件 this.OnChanged(new EventArgs()); } } }}
不足之处,还请大家多多指正!
2006年11月20日 #
大家喝的是啤酒。这时你入座了。
你给自己倒了杯可乐,这叫低配置。 你给自已倒了杯啤酒,这叫标准配置。
你给自己倒了杯茶水,这茶的颜色还跟啤酒一样,这叫木马。 你给自己倒了杯可乐,还滴了几滴醋,不仅颜色跟啤酒一样,而且不冒热气还有泡泡,这叫超级木马。
你的同事给你倒了杯白酒,这叫推荐配置。
人到齐了,酒席开始了。
你先一个人喝了一小口,这叫单元测试。 你跟旁边的人说哥们咱们随意,这叫交叉测试。但是他说不行,这杯要干了,这叫压力测试。 于是你说那就大家一起来吧,这叫内部测试。 这个时候boss向全场举杯了,这叫集成测试。
菜过三巡,你就不跟他们客气了。 你向对面的人敬酒,这叫p2p. 你向对面的人敬酒,他回敬你,你又再敬他……,这叫tcp. 你向一桌人挨个敬酒,这叫令牌环。 你说只要是兄弟就干了这杯,这叫广播。
可是你的女上司听了不高兴了:只有兄弟么,罚酒三杯。这叫BoB!!!。 可是你的女下属听了不高兴了:我喝一口,你喝一杯,这叫恶意攻击。
有一个人过来向这桌敬酒,你说不行你先过了我这关,这叫防火墙。 你的小弟们过来敬你酒,这叫一对多。 你是boss,所有人过来敬你酒,这叫服务器。
酒是一样的,可是喝法是不同的。 你喝了一杯,boss喝了一口,这叫c#。 你喝了一杯,mm喝了一口,这叫vb。 你喝了一杯,你大哥喝了半杯,这叫c++。 你喝了半杯,你小弟喝了一杯,这叫汇编。 你喝了一杯,你的搭档也喝了一杯,这叫c。
酒是一样的,可是喝酒的人是不同的。 你越喝脸越红,这叫资源释放。 你越喝脸越白,这叫资源独占。 你已经醉了,却说我还能喝,叫做虚拟内存。 你明明能喝,却说我已经醉了,叫做资源保留。 你喝一段时间就上厕所,这叫cache。
酒过三巡,你也该活动活动了。 你一桌一桌的走,这叫轮巡。 你突然看到某一桌的漂亮mm,走了过去,这叫激活事件。 你去了坐下来就不打算走了,这叫死循环。 你的老大举杯邀你过去,你只好过去,这叫优先级。 你向一桌敬酒,他们说不行不行我们都喝白的,于是你也喝白的,这叫本地化。
你向boss敬酒,可是boss被围了起来,你只能站在外圈,这叫队列。 你终于到了内圈,小心翼翼的向前一步,这叫访问临界区。 你拍着boss的肩膀说哥们咱们喝一杯,这叫越界。
你不知喝了几圈了,只会说两个字,干了,这叫udp。 可是还有人拿着酒瓶跑过来说,刚才都没跟你喝,这叫丢包。
喝酒喝到最后的结果都一样 你突然跑向厕所,这叫捕获异常错误。 你在厕所吐了,反而觉得状态不错,这叫释放内存。 你在台面上吐了,觉得很惭愧,这叫实时错误。 你在boss面前吐了,觉得很害怕,这叫灾难性错误。 你吐到了boss身上,只能索性晕倒了,这叫ShutDown。
你找boss喝酒,boss说我喝不下了,这叫超过最大连接数。你继续劝boss喝酒,这叫刷新。boss说喝不了了,不喝了,这叫访问拒绝。然后boss说:小伙子,我们换个话题,这叫页面重定向。boss问你:小伙子,你叫什么?这叫登录验证。boss说:你等等,我去下wc。结果左等右等就是等不回来,这叫连接超时。你到处找boss,结果就是找不到,这叫该页无法显示。
一个人拿着啤酒到你们部门那桌,对你们经理说:我敬你们部门一杯。然后你们部门一个喝啤酒的人和他干了这杯。另一个人拿着白酒也到你们那,对你们经理说:我也敬你们部门一杯。然后你们部门一个喝白酒的人和他干了这杯。这叫多态。
一个人拿着两杯酒到你们部门那桌,把其中一杯酒放到经理面前,说:我敬你们部门一杯你们谁喝我不管,只要把这杯喝了就行了。这叫封装。
一个人拿着酒到你们部门那桌,对你们经理说:我敬你一杯。然后经理点名:xxx,帮我喝这杯,你喝就等于我喝了。这叫继承。
你拿个空杯子喝酒,这叫虚函数。
别人向你敬酒,你拿个小杯准备喝,他说:“不行,我们要大杯”,这叫需求变更。
你拿个大杯敬酒,他说:“我们换小杯的”,这叫简化版本。
没事的时候总喜欢泡技术社区,记得在2005年的时候社区里突然冒出个AJAX的新名词,开始还以为又出来什么新语言了.是不是又要掀起技术革命,感叹程序员的命真的是苦啊,一项技术还没有学好,新的技术又随之出现,于是时常会想起老了以后学不动了怎么办?开始见到AJAX并没有引起我对它的注意,后来经过时间不是很长好像这东西发展还真的挺快的。各论坛讨论的呼声越来越大,很多人把它说的神乎其神,在众多人高呼WEB2.0时代到来之时,AJAX也似乎有取代传统WEB开发的趋势,于是不得不在闲下来的时候对AJAX进行必要得了解。 很早就知道AJAX其实就是html + javascript + xml + dom + Dhtml 说白了就是对老技术得灵活运用,偏偏老技术还没有学精谈何灵活运用呢,为了使技术能够得到提高也为了能够灵活运用AJAX跟随技术潮流,计划在闲着的时候学习一下ajax。 有空的时候将学习的笔记发布并整理成BLOG文章,希望得到大家的帮助!共同提高!
Ajax 应用程序所用到的基本技术1.html 组成web页面所用到的基本元素2.javascript javascript代码是AJAX应用程序核心的代码,帮助ajax程序改进与服务器通讯以实现不一样的用户体验3.Dynamic HTML 用于动态更新web页面4.DOM(文档对象模型) 用于通过javascrip代码处理HTML或服务器返回的XML
javascript与服务器端通信的最核心的对象xmlHttp对象:传送XML格式数据的超文本传输协议实际上XMLHTTP传输的数据可以是XML格式数据,也可以是字符串,流,或者一个无符号整数数组。还可以是URL的参数,它下达的结果可以是XML格式数据,也可以是字符串,流,或者一个无符号整数数组。
调用步骤1、创建XMLHTTP对象2、打开与服务端的连接,同时定义指令发送方式,服务网页(URL)和请求权限等。 3、发送指令。 4、等待并接收服务端返回的处理结果。 5、释放XMLHTTP对象方法open(数据传送方式(GET/POST/HEAD),服务器URL,是否异步执行,[用户名],[口令])如:open("GET","http://www.sohu.com",true)send(content)可以是XML格式数据,也可以是字符串,流,或者一个无符号整数数组。也可以省略,让指令通过Open方法的URL参数代入。如:send(null);
setRequestHeader(HTTP 头,HTTP 头值)如:xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
abort()取消当前 HTTP 请求
getAllResponseHeaders ()从响应信息中检索所有的HTTP 头字段
getResponseHeader(HTTP 头)从响应信息正文中获得一个 HTTP 标头值
属性onreadystatechange:用以状态改变后所要作的处理的事件句柄。 readyState 异步操作的状态:未初始化(0),正在加载(1),已加载(2),交互(3),已完成(4) responseBody:返回为无符号整数数组。 responseStream:返回为IStream流。 responseText :返回字符串。 responseXML:返回为XML格式数据。 status:服务器返回的HTTP状态码 statusText :服务器HTTP响应行状态
说明1.同步和异步 同步状态下发送http请求后,只有当客户端接收到来自服务端的全部应答数据或协议栈超时返回!反之异步状态下,直接返回。在异步方式下数据包一旦发送完毕就结束send进程客户端执行其他的操作,而在同步方式下客户端要等到服务器返回确认消息后才结束send进程。实际运用中我们根据实际情况使用同步或异步,注意了如果设为同步状态可能因为服务器返回数据量大或响应慢而导致不必要的长时间等待!
2.POST和GET 用"POST"方式发送数据.可以大到4MB "GET"只能256KB
创建一个XMLHTTP对象Microsoft Internet Explorer浏览器使用MSXML解析器处理XML,MSXML实际上有两种不同的版本xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");对于非 Microsoft 浏览器(Mozilla、Firefox、Safari、Opera):xmlHttp = new XMLHttpRequest();function getXmlHttp(){ var xmlHttp = null; if ( window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); if (xmlHttp.overrideMimeType) xmlHttp.overrideMimeType("text/xml"); } else if ( window.ActiveXObject) { try { xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } }
if ( !xmlHttp) { window.alert("XmlHttp not be Supported!"); } return xmlHttp; }下面的代码说明了如何从创建到初始化XMLHTTP到发送数据的过程,并指定处理返回数据的事件句柄
var xmlHttp = null; function callServer(url){ xmlHttp = getXmlHttp(); xmlHttp.onReadyStateChange = setPage; xmlHttp.open("GET",url,true); xmlHttp.send(); document.getElementById("loading").innerHTML = "正在加载...";}
得到返回数据并更新页面function setPage(){ switch(xmlHttp.readyState) { case 0: document.getElementById("loading").innerHTML = "正在初始化..."; break; case 1: document.getElementById("loading").innerHTML = "正在加载..."; break; case 2: document.getElementById("loading").innerHTML = "已加载完成..."; break; case 3: document.getElementById("loading").innerHTML = "正在接收数据..."; break; case 4: document.getElementById("loading").innerHTML = "已完成!"; break; } if ( xmlHttp.readyState == 4) { if ( xmlHttp.status == 200) { document.getElementById("content").innerText = xmlHttp.responseText; } xmlHttp.abort(); } }
HTML :
<input name="url" id="url" type="text" value="http://www.sohu.com"><input type="button" onclick="callServer(document.getElementById('url').value)" value="get data"> <BR><div id="loading" style="color:red; font-size:12px;"></div> <span id="content"></span>
2006年5月30日 #
最近一个项目中遇到一个转换FileTime的问题.时间是在C#中用DateTime.ToFileTime写入数据库中,这在存储过程中判断年和季度成了问题,怎么样才能把时间转换为正常的时间格式呢?Sql server中又没有FromFileTime对应的方法?其实很简单用C#写一个转换时间的Dll然后在存储过程中调用就可以了.转换时间的类如下:[Guid("729ba6af-3eff-4b75-b43b-d951a190dbe6")] public class FileTimeConvert { public FileTimeConvert() { } public string ConvertTime(long fileTime) { string retVal = string.Empty; if (fileTime > 0) { DateTime dt = DateTime.FromFileTime(fileTime); retVal = dt.ToString(); } return retVal; } }注意这个Guid我们在存储过程中引用要用到这个Guid.为方便可能在多处需要调用,我们专门写一个存储过程如下:CREATE PROCEDURE spu_ConvertFileTimeToNormal @ticks BIGINT, @returnval varchar(40) output AS
DECLARE @src varchar(255)DECLARE @desc varchar(255)
DECLARE @object intDECLARE @hr intEXEC @hr = sp_OACreate '{729ba6af-3eff-4b75-b43b-d951a190dbe6}',@object OUT
IF @hr = 0 --如果创建对象成功 BEGIN EXEC @hr = sp_OAMethod @object,'ConvertTime',@returnval OUT,@ticks print @returnval print @hr if(@hr <> 0) BEGIN EXEC sp_OAGetErrorInfo @object, @src OUT, @desc OUT SELECT hr=convert(varbinary(4),@hr), Source=@src, Description=@desc END END
ELSE BEGIN --print @hr print 'Create Object ConvertTime failed' EXEC sp_OAGetErrorInfo @object, @src OUT, @desc OUT SELECT hr=convert(varbinary(4),@hr), Source=@src, Description=@desc RETURN END
EXEC @hr = sp_OADestroy @object
IF @hr <> 0 BEGIN EXEC sp_OAGetErrorInfo @object RETURN ENDGO这个时候我们还差最后一步注册DLL了在.net 命令行下输入 regasm -codebase path好了,现在我们就可以在其他存储过程中调用这个存储过程返回正常的时间了.给个小例子:EXEC spu_ConvertFileTimeToNormal @CreateTime,@NormalTime OUT @CreateTime:FileTime格式@NormalTime :正常的时间格式字符串(spu_ConvertFileTimeToNormal 存储过程返回值)这个简单的小例子说明了我们怎么样在存储过程中调用DLL是不是你解决问题又多了一个选择了呢?
2006年4月14日 #
灵活的运用数据绑定操作 绑定到简单属性:<%#UserName%> 绑定到集合:<asp:ListBox id="ListBox1" datasource='<%# myArray%>' runat="server"> 绑定到表达式:<%#(class1.property1.ToString() + "," + class1.property2.ToString())%> 绑定到方法返回值:<%# GetSafestring(str) %> 绑定到Hashtable:<%# ((DictionaryEntry)Container.DataItem).Key%> 绑定到ArrayList:<%#Container.DataItem %>
若数组里里放的是对象则可能要进行必要的转换后再绑定如: <%#((对象类型)Container.DataItem).属性%>
绑定到DataView,DataTable,DataSet: <%#((DataRowView)Container.DataItem)["字段名"]%>或 <%#((DataRowView)Container.DataItem).Rows[0]["字段名"]%> 要格式化则: <%#string.Format("格式",((DataRowView)Container.DataItem)["字段名"])%> <%#DataBinder.Eval(Container.DataItem,"字段名","格式")%>
绑定到DataReader: <%#((IDataReader)Container.DataItem).字段名%>
当然为了方便一般使用最多的就是DataBinder类的Eval方法了.不过这样对于同时要绑定大量的数据效率要低一些
Sql Server中DateTime值的范围 1753-01-01 至 9999-12-31 在做Access程序导入数据到Sql Server 时要注意ACCESS中的日期可能不在此范围内而出现错误.(如日期为207-01-01)
检测到有潜在危险的 Request.Form 值 solution1:<%@Page ValidateRequest="false" %> solution2: <configuration> <system.web> <pages validateRequest="false" /> </system.web> </configuration> 其实这样做的确有点不安全,我们还应该自己定义一个专门处理这类危险字符的方法来对其进行预处理
ViewState,Session,Cookie作用域 ViewState值保存在浏览器的html代码中,当浏览器关闭或跳到别的页面,则值消失 Session采用键值对的形式,键存放客户端而值放在服务器端,是通过用户的ID去找服务器上对应的值,这种方式值放置在服务器端,有个时间限制,时间到则服务器自动释放 Cookies则有两种方法,一种方法是把值保存在浏览器的变量中,当浏览器关闭时结束,另一种方法是保存在硬盘中,只要时间不过期,下次还可使用
Access中的通配符注意了 DAO: *, ADO: % (是不是有时候在SQL SERVER里能查而用VB在操作ACCESS时有查不出数据来啊?)(添加中...)
2006年3月28日 #
1.DataGrid动态绑定字段 有时候我们会遇到在DataGrid中动态绑定某个字段的情况,比如:当显示中文时我们绑定cname,显示英文时我们要绑定ename,此时我们可以这样:ButtonColumn:if (language == "cn") ((ButtonColumn)this.DataGrid1.Columns[3]).DataTextField = "cname";else ((ButtonColumn)this.DataGrid1.Columns[3]).DataTextField = "ename";BoundColumn:((BoundColumn)this.DataGrid1.Columns[3]).DataField = "cname";HyperLinkColumn同ButtonColumn的写法,不同的是当我们要动态改变TemplateColumn的显示应该怎么办呢?这样就行了 先新建一个模板:public class Template1 :ITemplate { public void InstantiateIn(Control container) { TextBox txt = new TextBox(); txt.Text = "this is a added template column"; container.Controls.Add(txt); } }再这样写:((TemplateColumn)this.DataGrid1.Columns[1]).ItemTemplate = new Template1();2.动态转换DataGrid中某个Cell中的值BoundColumn:if (e.Item.Cells[3].Text == "Ann") e.Item.Cells[3].Text = "<b>这一行本来应该显示Ann,现在被转换成这样了!</b>";ButtonColumn :LinkButton link = (LinkButton)e.Item.Cells[3].Controls[0];if (link.Text == "Ann") link.Text = "<b>这一行本来应该显示Ann,现在被转换成这样了!</b>";这段代码写在:OnItemDataBound事件的方法体中就可以了.HyperLinkColumn:强类型转换成HyperLink,Template Column:通过FindControl方法3.动态创建DataGrid及添加列DataGrid dg = new DataGrid(); // BoundColumn BoundColumn col1 = new BoundColumn(); col1.DataField = "au_id"; col1.HeaderText = "au_id"; dg.Columns.Add(col1);
// ButtonColumn ButtonColumn col2 = new ButtonColumn(); col2.DataTextField = "au_fname"; col2.HeaderText = "au_fname"; dg.Columns.Add(col2);
// TemplateColumn TemplateColumn col3 = new TemplateColumn(); col3.ItemTemplate = new Templates.Template1(); col3.HeaderText = "My Template Column"; dg.Columns.Add(col3);
// LinkButtonColumn HyperLinkColumn col4 = new HyperLinkColumn(); col4.HeaderText = "au_lname"; col4.DataTextField = "au_lname"; col4.DataNavigateUrlField = "au_lname"; dg.Columns.AddAt(0,col4); SqlConnection conn = new SqlConnection("server=localhost;uid=sa;pwd=;database=pubs"); SqlDataAdapter da = new SqlDataAdapter("select * from authors",conn); DataSet ds = new DataSet(); da.Fill(ds); dg.DataSource = ds; dg.DataBind(); Page.Controls[1].Controls.Add(dg);4.关于.Net中将DataGrid内容导出到Excel乱码的问题一般常用的方法为:DataGrid1.DataSource = this.GetDataSource(); DataGrid1.DataBind();Response.Clear();Response.Buffer = true;Response.ContentType = "application/vnd.ms-excel";Response.Charset = "gb2312";EnableViewState = false;System.IO.StringWriter tw = new System.IO.StringWriter();System.Web.UI.HtmlTextWriter hw = new System.Web.UI.HtmlTextWriter(tw);DataGrid1.RenderControl(hw );Response.Write(tw.ToString());Response.End();但是有时导出会出现乱码,有时则不会出现乱码.真是百思不得其解.我们可以这样解决将Response.ContentType = "application/vnd.ms-excel";Response.Charset = "gb2312";换成:Response.Write("<meta http-equiv=Content-Type content=text/html;charset=gb2312>");Response.AppendHeader("content-disposition","attachment;filename=\"" + HttpUtility.UrlEncode("全部销售记录["+DateTime.Now.ToString("yyyy-MM-dd")+"]",System.Text.Encoding.UTF8) + ".xls\"");为什么直接输出到Excel会出现乱码,而用Excel打开这段Html不会出现乱码呢?暂时能解决问题但还是不明白,希望高手能给予释疑!
2006年1月19日 #
Powered by: 博客园 Copyright © ktgu