如题,愿我们珍惜每一天;

如果你未恋爱,请看看吧,他们是多么可爱!勇敢去追求!

如果你已经恋爱,请珍惜她(他),你们还在一起!

如果你已经结婚,请把时间多分配给她(他)!

如果你已经有一个完满的家庭...幸福!珍惜!

如果你快要退休了...或许可以写写日志!

为生者祈福! 

posted @ 2010-04-21 09:51 Yibu 阅读(1253) 评论(5) 编辑

在命名空间SharpArch.Data.NHibernate底下,我们可以看到NHibernateSession类,这个类,就是NHibernate在Sharp的栖息地! NHibernateSession是一个静态类,所以它是全局的,就像是一个工厂,在这里,你可以配置NHibernate,创建Session的实例...

 

下面显示的是NHibernateSession给我们的接口

namespace SharpArch.Data.NHibernate
{
    
public static class NHibernateSession
    {
        
public static readonly string DefaultFactoryKey;

        
public static ISession Current { get; }
        
public static ISessionStorage Storage { getset; }
        
public static ValidatorEngine ValidatorEngine { getset; }

        [CLSCompliant(
false)]
        
public static Configuration AddConfiguration(string factoryKey, string[] mappingAssemblies, AutoPersistenceModel autoPersistenceModel, string cfgFile, IDictionary<stringstring> cfgProperties, string validatorCfgFile, IPersistenceConfigurer persistenceConfigurer);
        
public static void CloseAllSessions();
        
public static ISession CurrentFor(string factoryKey);
        
public static ISessionFactory GetDefaultSessionFactory();
        
public static ISessionFactory GetSessionFactoryFor(string factoryKey);
        
public static Configuration Init(ISessionStorage storage, string[] mappingAssemblies);
        [CLSCompliant(
false)]
        
public static Configuration Init(ISessionStorage storage, string[] mappingAssemblies, AutoPersistenceModel autoPersistenceModel);
        
public static Configuration Init(ISessionStorage storage, string[] mappingAssemblies, IDictionary<stringstring> cfgProperties);
        
public static Configuration Init(ISessionStorage storage, string[] mappingAssemblies, string cfgFile);
        [CLSCompliant(
false)]
        
public static Configuration Init(ISessionStorage storage, string[] mappingAssemblies, AutoPersistenceModel autoPersistenceModel, IDictionary<stringstring> cfgProperties);
        [CLSCompliant(
false)]
        
public static Configuration Init(ISessionStorage storage, string[] mappingAssemblies, AutoPersistenceModel autoPersistenceModel, string cfgFile);
        
public static Configuration Init(ISessionStorage storage, string[] mappingAssemblies, string cfgFile, string validatorCfgFile);
        [CLSCompliant(
false)]
        
public static Configuration Init(ISessionStorage storage, string[] mappingAssemblies, AutoPersistenceModel autoPersistenceModel, string cfgFile, string validatorCfgFile);
        [CLSCompliant(
false)]
        
public static Configuration Init(ISessionStorage storage, string[] mappingAssemblies, AutoPersistenceModel autoPersistenceModel, string cfgFile, IDictionary<stringstring> cfgProperties, string validatorCfgFile);
        [CLSCompliant(
false)]
        
public static Configuration Init(ISessionStorage storage, string[] mappingAssemblies, AutoPersistenceModel autoPersistenceModel, string cfgFile, IDictionary<stringstring> cfgProperties, string validatorCfgFile, IPersistenceConfigurer persistenceConfigurer);
        
public static void InitStorage(ISessionStorage storage);
        
public static bool IsConfiguredForMultipleDatabases();
        
public static void RegisterInterceptor(IInterceptor interceptor);
        
public static void RemoveSessionFactoryFor(string factoryKey);
        
public static void Reset();
    }
}

我们很容易发现,这里面有多达9个的Init()方法的重载,这些方法都是用于实例化NHibernate Session(为什么要这么多重载,我像是因为C#当时没有还没有默认参数这一机制)。首先看看这些方法有两个共同的参数:

ISessionStorage storage, string[] mappingAssemblies

第一个参数storage,顾名思义,是一个存储器,存储什么?Session。为什么要存储Session?这里原因有二,一是从配置开始到实例化一个Session是需要很大的代价的,这里把已经实例化的Session做一缓存,可以提高效率;二是存储Session可以方便同时操作多个Session(我们知道,实例化Session是不能改变数据库配置的)。通过这个参数,我们可以自由存储Session,用什么来储存完全由我们决定,只要我们定义的储存符合接口ISessionStorage即可。

代码
namespace SharpArch.Data.NHibernate
{
    
public interface ISessionStorage
    {
        ISession GetSessionForKey(
string factoryKey);
        
void SetSessionForKey(string factoryKey, ISession session);
        IEnumerable
<ISession> GetAllSessions();
    }
}

第二个参数mappingAssemblies,这是一些程序集的名称数组。这个数组很重要,他是指向你的实体映射的程序集,这个程序集可以包含FluentNHibernate映射,也可以包含NHibernate映射。同时,Sharp也提供给我们FluentNHibernate的一部分常规映射,例如,实体对应的数据表名被映射为实体类名的复数形式等。如果想改变某个实体的映射,则需要重新写实体映射关系类,下的代码是一个User实体类的映射:

    public class UserMap : IAutoMappingOverride<User>
    {

        
#region IAutoMappingOverride<User> 成员

        
public void Override(FluentNHibernate.Automapping.AutoMapping<User> mapping)
        {
            mapping.Map(c 
=> c.UserType).CustomType<UserType>();
        }

        
#endregion
    }

映射类需要实现IAutoMappingOverride<T>接口(关于更多的映射请参考FluentNHibernate Wiki)。
再看看另外两个重要的参数

AutoPersistenceModel autoPersistenceModel, string cfgFile


 autoPersistenceModel是告诉Sharp,在mappingAssemblies程序集中有做怎样的映射处理,cfgFile是告诉Sharp,NHibernate的配置文件。


 在用Sharp模板生产的项目里,找到Global.asax.cs文件,我们可以看到

        private void InitializeNHibernateSession()
        {
            NHibernateSession.Init(
                webSessionStorage,
                
new string[] { Server.MapPath("~/bin/SomeProject.Data.dll") },
                
new AutoPersistenceModelGenerator().Generate(),
                Server.MapPath(
"~/NHibernate.config"));
        }

这么一段代码,这就是在初始化Session。

 关于Session部分就介绍到这里。

 

 

 

posted @ 2010-04-20 10:49 Yibu 阅读(336) 评论(0) 编辑

 SharpArchitecture,这是一个基础框架,它方便于快速地搭建一个基于ASP.NET MVCNHibernate框架的可维护的Web应用程序。主要优点是搭建框架时降低个人代码量,同时提高了最终产品的质量。框架使得开发人员能够花一点时间在基础设施的详情下,同时允许他们把重点放在领域和用户体验上。因此,SARP协议架构坚持以下原则:

    * 领域驱动设计

    * 松耦合

    * 快速搭建框架

    * 开源

SharpArchitecture提供的项目模板文件的使用,首先把VisualStudioTemplate文件夹下的 SharpArchApplicationWizard.dll拷贝到:“你安装的盘符” \Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE目录下;然后把VisualStudioTemplate文件夹下的 SharpArchApplicationTemplate.zip压缩文件拷贝到 C:\Users\[UserName]\Documents\Visual Studio 2010\Templates\ProjectTemplates\Visual Web Developer目录下.

打开VS2010,新建项目:

 

 

建立Sharp Architecture Application项目。

 

 

 第一个项目完成!

 喜欢修改的Sharp的朋友,可以下载源码。

VisualStudioTemplate

src

posted @ 2010-04-18 13:54 Yibu 阅读(299) 评论(1) 编辑

SharpArchitecture有了解的朋友都知道,它可以说是开发asp.net mvc + NHibernate的快速模板。NHibernateasp.net mvc都在更新,SharpArch也在更新,我的系列文章就是在这个更新的时代里诞生了。

SharpArchitecture是开源作品,在这里,我根据自己的开发需要,更新了程序集NHibernate2.2.1.4Web应用MVC2.0,尊重原著,源代码方面我仅在添加了需要的功能(如果需要原版的朋友可以在下载),同时,VS2010刚刚发布,我将项目发布成VS2010的项目模板。

 

作者的修改是结合自身的需要而加以修改,喜欢原作的朋友可以在官方网站下载源码。

官网地址:http://www.sharparchitecture.net/

 

开始做主!

文章假设你已经了解NHibernateMVC框架。

 

我的SharpArchitecture,我做主之一:我的第一个SharpArchitecture Web应用工程

我的SharpArchitecture,我做主之二:NHibernate在哪里?

我的SharpArchitecture,我做主之三:我的线程安全

我的SharpArchitecture,我做主之四:我想在一个工程中访问两个数据库,怎么办?

我的SharpArchitecture,我做主之五:SharpArchWeb应用特性

我的SharpArchitecture,我做主之六:WinForm可以用SharpArch吗?

我的SharpArchitecture,我做主之七:祝你成功

posted @ 2010-04-18 13:39 Yibu 阅读(289) 评论(0) 编辑

多文件断点续传组件(MFC ActiveX)是一个用于Web上传文件的ActiveX控件,他应该支持断点和多文件异步上传。

针对断点续传组件,我需要解决下面5个问题:

 

1、 文件状态问题

2、 文件传输效率与安全问题

3、 编码问题

4、 系统设计问题

5、 交互问题

 

 

一、文件状态问题

一个文件从被打开到关闭,它需要经过4种状态:初始化、就绪、上传中、完成,而且他们仅有一种转化关系(初始化→就绪→上传中→完成)。实际上,为了实现断点续传,我还需要引进两种状态:等待和暂停。

 


1

考虑到组件的健壮性,还需要一个“出错”状态来容错(见图1),如上传超时的时候。

状态结构

 

enum FileStates{

         State_Init = 0,

         State_Pending = 1,

         State_Uploading = 2,

         State_Waiting = 3,

         State_Paused = 4,

         State_Finished = 5,

         State_Error = 6       

};

 

 

二、文件传输效率与安全问题

我们知道,大多数Web服务器出于安全考虑,会限制一次请求上传数据量,比如ASP.NET,默认的文件大小上限为4MB,是为了避免潜在DOS攻击危险。若是攻击者提交了一个或多个大文件,往往会让服务器不堪重负。若是用户上传的文件大于4MB,将会得到“Maximum request length exceeded.”异常信息。当然,我们可以更改默认设置,但是,这样将是以安全为代价去换回文件的上限。我们可以考虑将一个文件分割成多次请求发送,这样做的后果是出现了新的问题——传输效率问题。

假设有一个fKB的文件需要上传,当前网络传输速率vKB/s,每次请求响应时间ts

文件大小没有上限情况:


表示完成上传所需要的时间。

文件大小上限为MKB的情况:





分析可知,当f<M时,由于每次请求都要消耗(n+1)t时间,所以大文件分次传输要比一次传输多耗时,一个常量级的增长是可以接受的。

 

三、编码问题

 

从组件向服务器发送的数据要符合规范URL的标准,但是服务器对于规范URL的标准德解释是没有规定的,这样我们向服务器发送数据还存在编码不一致性的问题。通常浏览器会用两种编码方式发送URL到服务器,分别是UTF-8和ANSI(当前系统语言设置,在Windows系统中可以理解为当前代码页)。

3.1、直接在地址栏输入URL的情况

中文Windows环境下,假如直接在浏览器的地址栏输入URL:

http://www.charset.cn/中国.html?kw=中国

  1. IE浏览器特性

 

PATH部分

参数部分

UTF-8模式(默认)

%E4%B8%AD%E5%9B%BD.html

kw=中国

 

UTF-8编码、urlencode

GBK编码、无urlencode

ANSI模式

中国.html

kw=中国

 

GBK编码、无urlencode

GBK编码、无urlencode

  1. 中文Windows环境下,IE中默认发送的URL的PATH部分是UTF-8编码,参数部分是GBK编码。IE的设置选项中有一项是“总是以 UTF-8 发送URL”可以改变发送URL的编码为ANSI。
  2. FireFox浏览器特性

 

PATH部分

参数部分

UTF-8模式

%E4%B8%AD%E5%9B%BD.html

kw=%E4%B8%AD%E5%9B%BD

 

UTF-8编码、urlencode

UTF-8编码、urlencode

ANSI模式(默认)

%D6%D0%B9%FA.html

kw=%D6%D0%B9%FA

 

GBK编码、urlencode

GBK编码、urlencode

  1. 中文Windows环境下FireFox中默认发送的URL的PATH和参数都是GBK编码,在FireFox地址栏输入“about:config”,找到选项“network.standard-url.encode-utf8”,即可改变发送URL的编码方式。
  2. Opera浏览器特性

 

PATH部分

参数部分

UTF-8模式(默认)

%E4%B8%AD%E5%9B%BD.html

kw=%E4%B8%AD%E5%9B%BD

 

UTF-8编码、urlencode

UTF-8编码、urlencode

3.2、来自网页中的链接

在不同的浏览器中打开不同编码的网页中的链接,特性也不相同。在不改变浏览器默认选项情况下访问不同编码的网页中以下链接:

http://www.charset.cn/中国.html?kw=中国

  1. IE浏览器特性

 

PATH部分

参数部分

UTF-8网页

%E4%B8%AD%E5%9B%BD.html

kw=中国

 

UTF-8编码、urlencode

UTF-8编码、无urlencode

GBK网页

%E4%B8%AD%E5%9B%BD.html

kw=中国

 

UTF-8编码、urlencode

GBK编码、无urlencode

  1. FireFox浏览器特性

 

PATH部分

参数部分

UTF-8网页

%E4%B8%AD%E5%9B%BD.html

kw=%E4%B8%AD%E5%9B%BD

 

UTF-8编码、urlencode

UTF-8编码、urlencode

GBK网页

%D6%D0%B9%FA.html

kw=%D6%D0%B9%FA

 

GBK编码、urlencode

GBK编码、urlencode

对此,我们需要在组件中实现URL编码。

 

编码实现

CString CURLEncode::UrlEncodeUtf(CString strUnicode)

{

         USES_CONVERSION;

         LPCWSTR unicode = T2CW(strUnicode);

         int len = WideCharToMultiByte(CP_UTF8, 0, unicode, -1, 0, 0, 0, 0);

         if (!len)

                   return strUnicode;

         char *utf8 = new char[len + 1];

         char *utf8temp = utf8;

         WideCharToMultiByte(CP_UTF8, 0, unicode, -1, utf8, len + 1, 0, 0);

         utf8[len] = NULL;  

         CString strTemp, strEncodeData;

         while (*utf8 != '\0')

         {

                   strTemp.Format(_T("%%%2x"), (BYTE)*utf8);

                   strEncodeData += strTemp;

                   ++utf8;

         }

 

         delete []utf8temp;

 

         return CString(strEncodeData);

 

}

 

 

CString CURLEncode::Utf8ToStringT(LPSTR str)

{

         _ASSERT(str);

         USES_CONVERSION;

         WCHAR *buf;

         int length = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);

         buf = new WCHAR[length+1];

         ZeroMemory(buf, (length+1) * sizeof(WCHAR));

         MultiByteToWideChar(CP_UTF8, 0, str, -1, buf, length);

        

         return (CString(W2T(buf)));

}

 

CString CURLEncode::UrlDecodeUtf(CString UtfUrl)

{

         _ASSERT(UtfUrl);

         USES_CONVERSION;

         LPSTR _url = T2A(const_cast<LPTSTR>(UtfUrl.GetBuffer(UtfUrl.GetLength())));

         int i = 0;

         int length = (int)strlen(_url);

         CHAR *buf = new CHAR[length];

         ZeroMemory(buf, length);

         LPSTR p = buf;

         while(i < length)

         {

                   if(i <= length -3 && _url[i] == '%' && IsHexNum(_url[i+1]) && IsHexNum(_url[i+2]))

                   {

                            sscanf(_url + i + 1, "%x", p++);

                            i += 3;

                   }

                   else

                   {

                            *(p++) = _url[i++];

                   }

         }

         return Utf8ToStringT(buf);

}

posted @ 2010-01-09 16:08 Yibu 阅读(708) 评论(0) 编辑

在COM组件中调用JavaScript函数

注(转):http://blog.csdn.net/cheungmine/archive/2006/12/21/1451489.aspx

要求是很简单的,即有COM组件A在IE中运行,使用JavaScript(JS)调用A的方法longCalc(),该方法是一个耗时的操作,要求通知IE当前的进度。这就要求使用回调函数,设其名称为scriptCallbackFunc。实现这个技术很简单:

1 组件方(C++)

组件A 的方法在IDL中定义:
[id(2)] HRESULT longCalc([in] DOUBLE v1, [in] DOUBLE v2, [in, optional] VARIANT scriptCallback);

组件A的方法实现:
// 假设回调原型为: 
// scriptCallbackFunc(LONG nCurrentProgress, LONG nTotalProgress, BSTR bstrProgressName);
// 此方法由JS脚本来实现
STDMETHODIMP CA:: longCalc (DOUBLE v1, DOUBLE v2, VARIANT scriptCallback)
{
    CComPtr<IDispatch> spCallback;
    if (scriptCallback.vt == VT_DISPATCH)
         spCallback = scriptCallback.pdispVal;
    

    // 参数准备
    CComVariant varResult;
    CComVariant avarParams[3];
    avarParams[0] = “开始计算股票”;        // bstrProgressName
    avarParams[0].vt = VT_BSTR;
    avarParams[1] = 100;                              // nTotalProgress
    avarParams[1].vt = VT_I4;
    avarParams[2] = 0;                                 // nCurrentProgress
    avarParams[2].vt = VT_I4;
    DISPPARAMS params = { avarParams, NULL, 3, 0 };


    if(spCallback)
          spCallback->Invoke(0,
                IID_NULL,
                LOCALE_USER_DEFAULT,
                DISPATCH_METHOD,
                &params, &varResult, NULL, NULL);

    BOOL  bFinished = false;
   

    while(!bFinished)
    {
         // 计算工作…
         Sleep(1000);
         v1 = v1+v2;
  
        // 回调客户
        if(spCallback)
        {
            avarParams[0] = “正在计算股票…”;
            avarParams[2] = 0;
            spCallback->Invoke(0,
                         IID_NULL, 
                         LOCALE_USER_DEFAULT,
                         DISPATCH_METHOD, 
                         &params, &varResult, NULL, NULL);
          }

          if(…)
                 bFinished = TRUE;
     }  // while OK!

      return S_OK;
}


2 客户方(JS)

<script language="javascript">
<!--
      // 符合回调原型:scriptCallbackFunc
      function scfDisplayProgress(nCurrentProgress, nTotalProgress, bstrProgressName)
      {
             window.status = bstrProgressName + “:”+(nCurrentProgress *100/TotalProgress);
      }
 
      // 创建组件并执行longCalc
      var objA = new ActiveXObject(“MyCom.A”);

       // 使用回调: 执行时在IE状态栏显示进度
       objA. longCalc (100, 200, scfDisplayProgress); 

       // 不使用回调
       objA. longCalc (100, 200); 
//-->
</script>

3 说明

该技术仅适用于脚本。不适合于VB、C++客户。
该技术和连接点、事件无关。
微软的XML DOM对象广泛使用这个方法。

posted @ 2010-01-06 12:47 Yibu 阅读(329) 评论(0) 编辑
摘要: 因为是.Net的Web应用程序,所以想用Advanced Installer 调用Dll实现安装部署。因为我需要自己定制参数,包括数据库服务器和数据库名称等,我需要建立一个企业版的项目工程。建立完毕,产品参数设置好了之后,就转到【用户界面】-》【对话框】。在【首次安装】目录下新建一个对话框:                            【图1.1】编辑对话框,如【图1.1】,我在这里将数...阅读全文
posted @ 2009-11-18 11:30 Yibu 阅读(1303) 评论(9) 编辑
摘要: 最近一直用NHibernate做开发,想写写心得。留驻!  例子是在MVC,NHibernate框架下实现的。 现在数据库中有一表Pictures存在字段ImageOriginal存储图片数据,我定义类 public class Picture { ... public virtual byte[] ImageOriginal{get;set;} } 这样,PictureRepository.Ge...阅读全文
posted @ 2009-11-06 09:21 Yibu 阅读(1193) 评论(5) 编辑
摘要: 1. 实现传统的网络文件上传解决方案 首先,我先实现一个传统的网络文件上传方案,建立一个web页面,我还需要一个<form>和两个<input>元素就能解决问题,如在Index.aspx文件中有如下元素: <form id="filePost" action="/Shared/Upload"method="post" enctype="multipart/form-d...阅读全文
posted @ 2009-11-03 14:32 Yibu 阅读(988) 评论(2) 编辑