贝网博客

我的分类
流水记事
源码下载
Asp.net
其它
数据库
Javascript
.Net技术
我的相册
友情链接
博客园
CSDN博客
Start0
最新回复
嗷嗷的cCC
fasdfasdf
[:..
lz这个东西好厉害,我..
哈哈,好照片
不错,以前一直用黄色..
终于找到支持ff的修正..
终于找到支持ff的修正..
新鲜性
看看,试试,好不好使。
.Net技术 日志列表    
本站一共有博客83条,当前显示26条
 发表于:2012-01-31 10:31:34

以前在实例化SqlParameter时,通常都是用下面的语句,没有设置size属性:
new SqlParameter("@name", SqlDbType.Varchar) { Value = name };
根据MSDN解释:如果未在 size 参数中显式设置 Size,则从 dbType 参数的值推断出该大小。
我一直以为是从SqlDbType类型推断,实际上是从参数的值推断,比如"ab",则size值为2,"abcd",则size值为4,且经测试发现,size的值不同时,会导致执行计划不会重用,下面的代码:
string sql = "select top 1 * from tb where name = @o";
var para = new SqlParameter("@o", SqlDbType.VarChar) {Value = "ab"};
SqlHelper.ExecuteReader(ReadConnectionString, CommandType.Text, sql, para);
通过SqlProfiler捕获到的sql如下:
exec sp_executesql N'select top 1 * from tb where name = @o',N'@o nvarchar(2)',@o=N'ab'
如果把参数的值改成abcd,则通过SqlProfiler捕获到的sql如下:
exec sp_executesql N'select top 1 * from tb where name = @o',N'@o nvarchar(4)',@o=N'abcd'
通过下面的sql,可以看出执行计划是否有重用:
--先清空执行计划缓存
DBCC FREESYSTEMCACHE ('ALL')
DBCC FREEPROCCACHE
GO
SELECT * FROM sys.dm_exec_cached_plans WHERE cacheobjtype = 'Compiled Plan'
GO
exec sp_executesql N'select top 1 * from tb where name = @o',N'@o nvarchar(2)',@o=N'ab'
GO
SELECT * FROM sys.dm_exec_cached_plans WHERE cacheobjtype = 'Compiled Plan'
GO
exec sp_executesql N'select top 1 * from tb where name = @o',N'@o nvarchar(4)',@o=N'abcd'
GO
SELECT * FROM sys.dm_exec_cached_plans WHERE cacheobjtype = 'Compiled Plan'
GO

最后的说明,实例化SqlParameter时,如果是字符型,一定要指定size属性,如:
new SqlParameter("@name", SqlDbType.Varchar, 4000) { Value = name };
如果是Int、Float、Bigint之类的参数,可以不用指定size属性

 发表于:2011-07-29 11:23:05
更新于:2011-12-12 15:35:26

本文简单介绍如何使用XmlSerializer或BinaryFormatter来把对象序列化成xml文件或二进制文件

在应用中,有些数据库查询非常耗时,而且变化又不是非常大,一开始我的处理是把数据取出来后,放入到Cache中,后来发现由于内在消耗比较大,应用程序池经常回收,导致缓存丢失,于是决定改用序列化到文件的方式,序列化到文件有2种方案,一种是二进制文件,一种是xml文件,后者可以随意编辑,适合配置文件或需要修改数据的场合,通用方法如下:
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;

/// <summary>
/// 序列化辅助类
/// </summary>
public class SerializeHelper
{
    /// <summary>
    /// 序列化对象为二进制文件
    /// </summary>
    /// <typeparam name="T">需要序列化的对象类型,必须声明[Serializable]特征,且必须是public类</typeparam>
    /// <param name="obj">需要序列化的对象</param>
    /// <param name="serializeFilePath">序列化后的物理文件路径</param>
    public static void BinarySerialize<T>(T obj, string serializeFilePath)
    {
        using (var fs = new FileStream(serializeFilePath, FileMode.Create))
        {
            var formatter = new BinaryFormatter();
            formatter.Serialize(fs, obj);
        }
    }
    /// <summary>
    /// 反序列化二进制文件为对象
    /// </summary>
    /// <typeparam name="T">需要序列化的对象类型,必须声明[Serializable]特征</typeparam>
    /// <param name="serializeFilePath">反序列化对象的物理文件路径</param>
    public static T BinaryDeserialize<T>(string serializeFilePath) where T : class
    {
        using (var fs = new FileStream(serializeFilePath, FileMode.Open))
        {
            var formatter = new BinaryFormatter();
            return formatter.Deserialize(fs) as T;
        }
    }

    /// <summary>
    /// 序列化对象为XML文件
    /// </summary>
    /// <typeparam name="T">
    /// 需要序列化的对象类型,必须声明[Serializable]特征,且属性类也必须声明[Serializable]特征。
    /// 如果属性是抽象类或接口,必须声明[System.Xml.Serialization.XmlInclude(typeof(子类))]特征
    /// </typeparam>
    /// <param name="obj">需要序列化的对象</param>
    /// <param name="serializeFilePath">序列化后的物理文件路径</param>
    public static void XmlSerialize<T>(T obj, string serializeFilePath)
    {
        using (var sw = new StreamWriter(serializeFilePath, false))
        {
            var formatter = new XmlSerializer(typeof(T));
            formatter.Serialize(sw, obj);
        }
    }
    /// <summary>
    /// 反序列化XML文件为对象
    /// </summary>
    /// <typeparam name="T">
    /// 需要序列化的对象类型,必须声明[Serializable]特征,且属性类也必须声明[Serializable]特征。
    /// 如果属性是抽象类或接口,必须声明[System.Xml.Serialization.XmlInclude(typeof(子类))]特征
    /// </typeparam>
    /// <param name="serializeFilePath">反序列化对象的物理文件路径</param>
    public static T XmlDeserialize<T>(string serializeFilePath) where T : class
    {
        using (var sr = new StreamReader(serializeFilePath))
        {
            var formatter = new XmlSerializer(typeof(T));
            return formatter.Deserialize(sr) as T;
        }
    }
}
 

调用简单说明:
    void Main(){
        s q = new s();
        q.a1 = new b(){c=2222};
        q.a1.b = "q.a1.b";
        q.a3=new List<string>();
        q.a3.Add("aaa");
        q.a3.Add(DateTime.Now.ToString());
        SerializeHelper.XmlSerialize(q, "e:\\a.bc");
        var b = SerializeHelper.XmlDeserialize<s>("e:\\a.bc");
    }
    [Serializable]
    public class s
    {
        public a a1;
        public List<string> a3;
    }
    [Serializable]
    [System.Xml.Serialization.XmlInclude(typeof(b))]
    public abstract class a
    {
        public string b;
    }
    [Serializable]
    public class b : a
    {
        public int c;
    }
 

回复:4  发表于:2011-04-12 20:18:10
更新于:2011-11-18 10:34:18

在DataTable里如果有一列数字,类型是字符型时,Select里的order排序,会按字符排序,而不是数值排序
比如:111, 99,  88
排序后会是:111, 88, 99
如果希望按数值排序,可以添加一列转换为数值后的列,如字符列名为bb,则:
dt.Columns.Add("aa", typeof(int), "Convert(bb, 'System.Int32')");
然后按aa列进行排序就ok了,下面是测试代码:
DataTable dt = new DataTable();
dt.Columns.Add("bb", typeof (string));

DataRow row = dt.NewRow();
row[0] = "101";
dt.Rows.Add(row);
row = dt.NewRow();
row[0] = "99";
dt.Rows.Add(row);
row = dt.NewRow();
row[0] = "88";
dt.Rows.Add(row);

dt.Columns.Add("aa", typeof(int), "Convert(bb, 'System.Int32')");
DataRow[] rows = dt.Select("", "aa");
foreach (DataRow dataRow in rows)
    Console.WriteLine(dataRow[0]);

 发表于:2011-06-09 21:07:11
更新于:2011-11-18 10:33:57

这2天做静态页,生成的html是utf8的格式,发现会被ie认成gb2312的,显示为乱码了,于是在aspx页面加了meta,格式如下:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>首页</title>

结果用ie访问aspx页面时,出现.net的编译错误: CS1010:常量中有换行符
经过实验发现把title里的“首页”这2个汉字删除就不会出现编译错误了,nnd,这是啥问题?搜了一下,没找到答案

不管了,先完成工作,再刷新aspx页面,完了又出现别的问题了,aspx页面的有的汉字正常显示,有的汉字是乱码,我%&**$%*%&*&*(@#@
研究了半天,什么CodePage=936的都测试过了,就是不行,但是只要删除meta声明为utf8的那行html,肯定正常,我再次@$%@$%@!%#

最后灵机一动,检查一下aspx的保存编码格式,发现用的是:Unicode(UTF-8 无签名)-代码页65001
而aspx里用到的一些ascx控件,保存编码格式用的是:Unicode(UTF-8 带签名)-代码页65001

于是统一修改为Unicode(UTF-8 带签名)-代码页65001,问题解决了,这是啥问题,我!@#$$%^^&*

教训是以后保存文件统一使用:Unicode(UTF-8 带签名)-代码页65001

btw:
带签名即文件头含BOM信息,不带则没有。
带了的好处是,只要支持多编码的编辑器都能正确识别出文件编码,而不带,就很可能出现乱码。
总之呢,这个BOM信息也就那么三字节,没必要省这么一点点空间

 发表于:2010-11-30 09:42:05
更新于:2011-11-18 10:31:34

由于公司网站使用了负载均衡,然后每天的错误日志都会有:System.Web.UI.ViewStateException: 无效的视图状态。

而由于公司原因,修改MachineKey比较麻烦,采用了修改Web.config的pages节配置来解决这个问题:
<pages validateRequest="false" enableEventValidation="false" viewStateEncryptionMode="Never" enableViewStateMac="false">

这里比较奇怪的是enableViewStateMac这个属性,按msdn说明,这个属性默认为false,但是我没加这个属性时,错误依旧,加入这个属性后才不会出错,而项目的其它地方都没有处理enableViewStateMac属性,奇怪啊奇怪

 发表于:2010-11-05 10:04:24
更新于:2011-11-18 10:30:40

 接手了一个项目,一直存在一个历史遗留问题,就是在使用统一登录的过程中,不定期出现登录不成功,反复弹出登录窗口的问题,因为是用的公司自己开发的IE内核的浏览器,所以下载了一个Http抓包工具Fiddler2,经过一个下午的排查,终于发现了问题所在,记录下来留念

首先是在统一平台登录的时候,会设置一个Cookie:
HttpCookie cookie = new HttpCookie(iemi);
cookie.Values.Add("credential", credential);
cookie.Domain = "beinet.cn";
cookie.Expires = DateTime.Now.AddHours(6.0);
HttpContext.Current.Response.Cookies.Add(cookie);

然后在项目页面退出的代码如下:
HttpContext.Current.Response.Cookies[IMEI].Value = ""; // 这里没有设置Domain

这样就造成了客户端有2个同名不同域的Cookie,而IE提交时,又每次都会提交2个Cookie上去,
在再一次登录的时候,这2个Cookie,一个是登录成功的Cookie,一个是退出的Cookie,
偏偏非常奇怪的是,有时在服务器上用:Request.Cookies[IMEI]读取到的是登录成功的Cookie(此时程序工作正常),
有时读取到的是退出的那个Cookie,导致程序认为没有登录,又弹出登录窗口

解决方法,就是在退出的代码里,也设置这个域,即:
HttpContext.Current.Response.Cookies[IMEI].Value = ""; 
HttpContext.Current.Response.Cookies[IMEI].Domain = "beinet.cn"; 

 发表于:2010-10-25 15:11:25
更新于:2011-11-18 10:29:18

今天打开一个同事交接的项目,结果发现,按F5,或者选择菜单上的“进入调试”,都只是弹出IE窗口,而无法进入到调试状态
而别的项目打开,调试都正常

经过比对,发现是Web.config里多了一行location声明:
<location path="." allowOverride="false" inheritInChildApplications="false">
  <system.web>
...........
</system.web>
</location>

把这个location删除,项目就能正常进入调试状态了,记录一下
Btw:
allowOverride属性为false时,表示location内的设置不允许子目录里的web.config覆盖(就是子目录的配置将无效)
inheritInChildApplications属性为false时,表示location内的设置,不应由子应用程序继承(实际上Web.config里不支持这个属性)

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

再记录一个以前碰到的不能调试的问题:
今天要用域名访问来测试程序,于是在C:\WINDOWS\system32\drivers\etc\hosts里添加了静态域名
并在IIS里新增了一下网站,为了让2个网站都能使用80端口,在新增的这个网站上配置了主机头为刚刚那个静态域名,
结果打开vs 2008 sp1,调试提示“无法在web服务器上启动调试。与web服务器通信时出现身份验证错误”。
先检查iis的网站属性配置的目录安全性里,已经勾选上了:集成身份验证

然后去网上搜索解决方案,先搜索百度,结果出现一堆无关答案,再搜索google,相关的答案全出来了,
看来还是google好啊,我的关键词是:无法在web服务器上启动调试。与web服务器通信时出现身份验证错误
你也可以搜索试试

下面是解决方案,我用的是第一个方案搞定的:
下面2个方法都试一下总有一个适合你。
方法 1: 禁用环回检查
请遵循以下步骤:1. 单击 开始 , 单击 运行 , 类型 regedit然后单击 确定 。
2. 中注册表编辑器, 找到并单击以下注册表项:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
3. 右击 Lsa , 指向 新建 , 然后单击 DWORD 值 。
4. 类型 DisableLoopbackCheck然后按 Enter。
5. 右击 DisableLoopbackCheck , 然后单击 修改 。
6. 在 数值数据 框中, 键入 1然后单击 确定 。
7. 退出注册表编辑器即可。

方法 2: 指定主机名
要指定主机名, 映射到环回地址并可连接到 Web 站点上, 请按照下列步骤:1. 单击 开始 , 单击 运行 , 类型 regedit然后单击 确定 。
2. 中注册表编辑器, 找到并单击以下注册表项:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0
3. 右击 MSV1_0 , 指向 新建 , 然后再单击 多字符串值 。
4. 类型 BackConnectionHostNames然后按 Enter。
5. 右击 BackConnectionHostNames , 然后单击 修改 。
6. 在 数值数据 框中, 键入主机名(如:127.0.0.1)或主机名为站点位于本地计算机, 然后单击 确定 。
7. 退出注册表编辑器, 并重新启动 IISAdmin 服务。

 发表于:2011-07-11 11:51:59
更新于:2011-11-18 10:25:25

今天接手新项目,为了调试方便,要把几个通用类库的源代码添加到当前解决方案来,为了省事,直接通过记事本打开sln解决方案文件,在Project里添加了我要添加的几个项目,然后保存,然后Visual Studio2010打开解决方案,问题来了,调试时,在进入到那几个通用类库时,一直报错:
源文件与模块生成时的文件不同。是否希望调试器使用它?

看了下输出,是报MD5不匹配,按网上搜索到的方案,把“要求源文件和版本匹配”的勾勾去掉,结果是不出错了,但是进入到源文件的行号完全错误,根本不是我要调试的那一行代码,又是删除站点生成的bin目录,又是清理解决方案,又是重启电脑的,都没能搞定

最后,尝试着删除通用类库的bin目录,这回生成站点时新问题出现了,对通用类库的引用文件找不到,赶紧看了下解决方案的属性,发现新添加的那几个项目,生成都没勾上,把它勾上,问题解决…… 偷懒都不能随便偷懒的


©2008 Beinet.cn 版权所有