‘ .NET开发 ’ category archive

VS2010中添加WCF引用的问题

53 views 四月 15, 12 by Timothy

最近在公司的项目中,遇到WCF相关的各种问题,不得不说,WCF这东东虽好,不过还是有很多不足的地方,希望微软能够持续改进。前一段时间遇到的问题,就是其中的一个,问题具体情况如下:

当你在使用Add service reference欲添加一个WCF服务的时候,在Add service reference窗口会遇到如下的错误:

The maximum nametable character count quota (16384) has been exceeded while reading XML data. The nametable is a data structure used to store strings encountered during XML processing – long XML documents with non-repeating element names, attribute names and attribute values may trigger this quota. This quota may be increased by changing the MaxNameTableCharCount property on the XmlDictionaryReaderQuotas object used when creating the XML reader. Read More

.NET程序与FIPS兼容性问题

46 views 二月 17, 12 by Timothy

开始之前,先介绍一下术语:

FIPS,全称是Federal Information Processing Standard,中文名叫联邦信息处理标准,FIPS 是由两个政府主体开发的标准。一个是美国国家标准和在美国境内的技术。另一种是通信安全机构,在加拿大。FIPS 是建议或要求使用 (美国或加拿大) 的联邦政府操作 IT 系统中的标准。

FIPS 140-2,主要用来定义安全级别,整个FIPS 140-2分为四个安全级别,它主要定义了一些和安全相关的策略,包括指定哪些加密算法和可使用的哈希算法和加密密钥的生成和管理的方式。

故事从这里开始,最近在做公司项目的时候,遇到一个很怪异的问题。我们的一个模块在普通的操作系统上,能正常运行,但是在启用了FIPS策略的机器上,就挂了。刚开始,还以为是其他原因,后来终于真相大白,这个bug和FIPS的安全策略有关。后来才知道,这个bug和US gov定义的这个安全策略那是相当的有基情! Read More

解决Ado.NET Entity Framework错误: DefiningQuery and no InsertFunction Error

102 views 二月 16, 12 by Timothy

最近用Ado.NET Entity Framework做项目,采用了POCO的模式来访问与存取数据库。所谓POCO,是Ado.NET Enity Framework (简称Ado.NET EF) 推出的一种新的模式,即Plain Old CLR Object。Ado.NET EF通过对POCO的支持,允许用户定义自己的Entity对象,比通过Ado.NET EF自动生成的对象更为简洁。

在程序的运行中,你也许会发现如下的错误:

Unable to update the EntitySet XXXXXX because it has a DefiningQuery and no element exists in the element to support the current operation.

这错误有点让人摸不着头脑,在Google上搜了半天,终于发现了原因。原来,如果你的数据库中的表,如果没有定义Primary Key,在Ado.NET EF中会被认为这是个View,而不是个Table。如果你用XML编辑器,打开生成的EDMX文件,就会发现,store type不是Table。除此之外,你还会发现如下的警告信息:

”Warning 6002: The table/view ‘TABLENAME’ does not have a primary key defined. The key has been inferred and the definition was created as a read-only table/view.“

解决方法很简单,去数据库里面,给你的表加上主键,然后更新整个EDMX就可以了。

WCF service host 崩溃退出的异常

128 views 十一月 08, 11 by Timothy

最近在公司项目中,遇到莫名其妙的异常,就是当使用Windows Service作为WCF服务端宿主程序,并且使用netTcpBinding的时候,Windows服务会时不时的Crash掉。通过分析处理UnHandledException记录下的日志,异常信息大致如下:

[10/26/11 10:10:16.011],[35],ERROR,”Encountered an unhandled thread exception: System.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was ’10675199.02:48:05.4775807′. —> System.IO.IOException: The read operation failed, see inner exception. —> System.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was ’10675199.02:48:05.4775807′. —> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host  Read More

WCF进行大数据传输时的相关配置

321 views 七月 14, 11 by Timothy

最近一直在公司用WCF做server端,后来在做性能测试时,发现一个问题,当客户端从服务端取回一个实体对象列表时,触发了channel is faulted status的异常。

仔细分析了下这个异常,应该是传递大数据造成的,因为在回传一个包含有100多个实体对象的列表时,客户端表现正常,而当回传的实体对象列表数目达到500+时,异常就出现了。

其实WCF还是做得比较灵活的,基本所有的配置项都放在程序的app.config文件里面,改动相应参数时,不需要重新编译程序。而WCF设计的初衷,为了避免DOS一类的攻击,默认在生成配置文件时,对传输的buffer数值有一定的限制,默认是65535,也就是64KB。然而在一些特定的应用场景中,区区64KB的buffer是不能满足我们需要的。这就需要我们手动在配置文件中调整buffer的size。 Read More

小试Emit

70 views 十一月 25, 10 by Timothy

.NET中的Emit,其实是个很强大的东东,它允许你在你的程序运行时,动态的生成代码。看到这里,也许大家会联想到Reflection,的确,Reflection也是我们平时用得比较多的一种技术,通过Reflection,我们能通过程序集中的元数据,动态的生成目标程序集的Instance,并执行它。而Emit的功能,恰恰和Reflection遥相呼应,前者允许我们动态的生成代码,后者允许我们动态的“查看”和运行代码。Emit和Reflection合在一起,简直就是双剑合璧,简直就是幸福的一家……难怪,微软也很邪恶的把Emit放在了System.Reflection.Emit。

其实哥平时的开发中,用得比较多的,还是Reflection(反射)了,不过早已久仰Emit的大名,又没闲暇时间来窥探一把,最近总算比较闲了,决心研究研究强大的Emit。

话不多说,代码是最有力的说明,先献上一个通过Emit动态创建并生成程序集的例子:

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System;
using System.Reflection;
using System.Reflection.Emit;
 
namespace Emit_Learn
{
    class Program
    {
        static void Main(string[] args)
        {
            var name = new AssemblyName("HelloEmit");
            var assemblyBuilder =
            AppDomain.CurrentDomain.DefineDynamicAssembly(name,
            AssemblyBuilderAccess.RunAndSave); //创建程序集
              var modelBuilder = assemblyBuilder.DefineDynamicModule("HelloEmit",             "HelloEmit.dll"); //创建模块
              var typeBuilder = modelBuilder.DefineType("HelloEmit"); //定义类型
              var methodBuilder = typeBuilder.DefineMethod("Execute",                                 MethodAttributes.Public,                                 null,                                 null); //创建MethodBuilder
            var il = methodBuilder.GetILGenerator(); //获取ILGenerator,用于生成方法的IL
            il.Emit(OpCodes.Ldstr, "Hello, Emit");
            il.Emit(OpCodes.Call,                     typeof(Console).GetMethod("WriteLine",                     new Type[] { typeof(string) }));
            il.Emit(OpCodes.Ret);
            typeBuilder.CreateType();
            assemblyBuilder.Save("HelloEmit.dll"); //保存动态生成的程序集到磁盘文件
 
        }
    }
}

在IDE中输入以上代码,F5运行,你会发现,在你的程序的Debug目录,会生成一个HelloEmit.dll。没错,这就是我们的程序动态生成的程序集,并且它是可执行的。以上的代码,动态生成的程序集,包含一个叫HelloEmit的类,类中有一个public属性的Execute方法。方法中调用Console输出字符串:Hello,Emit

这个类,等价于如下的C#代码:

?View Code CSHARP
1
2
3
4
5
6
7
8
internal class HelloEmit
{
    // Methods
    public void Execute()
    {
        Console.WriteLine("Hello, Emit");
    }
}

我们也可以使用.NET Reflector一类的工具,打开生成的Dll查看,顺便验证一下。

Emit适用的场景:适用于对业务灵活性要求很高的系统,可以在运行时动态更改业务逻辑,并动态生成代码。

Visual Studio 2010 尝鲜

928 views 四月 13, 10 by Timothy

昨晚在群里看到同事的讨论,MSDN终于放出Visual Studio 2010 RTM下载了(下文简称VS2010)。早上上班看到这个消息很是激动,迫不及待的去MSDN把期待已久的VS2010给拖了下来。VS2010和以往发布的版本不一样,这次划分为三个版本:Professional、Premium、Ultimate。
俺比较贪心,要用就用最高版本,拖了个Ultimate旗舰版,ISO镜像总共2.2GB,其实跟以往的VS2008相比,也不算大。

下面是VS2010中的新增特性(网上copy过来的):
·对多显示器的支持
·支持调用继承树
·新特性支持TDD
·新特性支持Office开发
·全新的Quick Search功能
·Call hierarchy高亮对象的引用
·直接使用一个未定义的对象
·提供更方便的javascript脚本编写
·HTML snippets超越智能提示
·可以进行自定义开始页
·C# 4.0的语言新特性
·提升了SharePoint开发功能
·特性聚焦:分析和调试并行应用程序
·正式包含F#函数式语言

下载完后,迫不及待开始安装:
1
2 和期望比较不一样的是,安完需要的组件,供占5个多GB的硬盘空间,还是比较苗条了。选完需要安装的组件,俺很慎重的按下了Install按钮……
3
漫长的安装过程,中途机器重启了两次,一次是在.NET Framework 4.0安装过后,一次是在整体安装完毕过后。

4安装完毕,俺怀着激动的心情,启动了VS2010,跳出不规则的Splash Window.6

整体使用感觉相当不错,此前还担心WPF实现的IDE界面会拖慢运行速度,看来这样的担心是多余的。跟VS2008相比,感觉VS2010的反应速度会快很多。看来这方面的优化还是做足了功夫的。另外,令人满意的是VS2010的扩展功能,内置的Extention Manager能够看到很多的在线扩展,选择你想要的,可以在线安装和卸载。这种方式让VS2010的扩展更加丰富和强大,值得表扬!

image另外,还有很多的关于.NET Framework 4.0 以及 VS2010的新特性还没来得及体验,比如dynamic,并行编程,新版的ADO.NET Entity Framework,新引入的F#语言,等等……
无意中也发现,ReSharper 5.0 也随着VS2010的发布而发布了,看来步调相当一致啊~这款功能强大的工具,自从VS2005开始,俺就一直用,现在不装反而不习惯了。于是卸掉之前的ReSharper 4.5,升级到5.0版。ReSharper 5.0本身也支持VS2008和VS2010,这样机器上的两个IDE可以和谐共存,并同时使用ReSharpter 5.0,简直太完美了。

总体感觉:VS2010和VS2008相比,确实是一大进步,或者说,确实是个飞跃…… 打算用段时间就把VS2008从机器中清理掉,嘿嘿……

扩展方法收集–实体验证

345 views 一月 17, 10 by Timothy

关于实体验证,是早期在博客园看到一个同学的文章,里面利用扩展方法对实体进行验证的思路比较有创意。大家可以先跳过去先看一下:http://www.cnblogs.com/tristanguo/archive/2009/05/15/1457197.html
这个实体验证的扩展方法,设计比较巧妙,充分利用了链式编程的特点,让代码更加简洁和美观,唯一不足的地方是后来作者在改进的时候感觉不是很到位。于是偶的同事Rex同学,对这实体验证的扩展方法进行了改进,在我看来,应该算是比较完美的解决方法了,因此在我们的实际项目中,也比较大量的应用到了此扩展方法。在这里贴出来,给大家分享一下。
贴代码:

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace CommonLib
{
    public static class EntityValidator
    {
        public static ValidateResult Validate(this T target,
                                              Predicate predicate,
                                              string errorMessage)
        {
            var result = new ValidateResult(target);
 
            if (!predicate(target))
            {
                result.Errors.Add(errorMessage);
            }
 
            return result;
        }
 
        public static ValidateResult Validate(this ValidateResult target,
                                              Predicate predicate,
                                              string errorMessage)
        {
 
            if (!predicate(target.Entity))
            {
                target.Errors.Add(errorMessage);
            }
 
            return target;
        }
    }
 
    public class ValidateResult
    {
        internal List Errors { get; set; }
        internal T Entity { get; private set; }
        public bool HasErrors
        {
            get { return Errors.Count > 0; }
        }
 
        internal ValidateResult(T entity)
        {
            Errors = new List();
 
            Entity = entity;
        }
 
        public string[] ErrorMessages { get { return Errors.ToArray(); } }
    }
}

有了这个实体验证的方法,代码可以简洁多了,并且再也不用在业务逻辑判断中,写入复杂的if…else语句块,取而代之的代码,示例如下:

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
ValidateResult validateResult =
                        content.Validate(c => !string.IsNullOrEmpty(c.Name), "Name为空")
                               .Validate(c => c.MobilePhone.Length == 11 , "MobilePhone长度不正确")
                               .Validate(c => c.Age >= 10), "年龄不在规定范围")
                               .Validate(c => c.Height <= 200 && c.Height >= 180, "身高不符合标准");
 
                    if (validateResult.HasErrors)
                    {
                        log.Info("实体验证失败:");
                        validateResult.ErrorMessages.ForEach(p => log.Info(p));
                        return null;
                    }

怎么样?这样的链式编程的代码,比起一大串的if…else组合语句,简洁、明了多了,并且还可以提高代码阅读的效率,强烈推荐各位同学使用。

Page: 1 of 4 1 2 3 4