FAQ —— C#

问:什么是OCP,什么是DIP,什么是IoC/DI模式?

答:OCP是Open-Close Principle开放关闭原则,对扩展开放,对修改关闭;DIP是Dependence Inversion Principle依赖倒置原则,任何变量都不能拥有一个具体类的指针或者引用、任何类都不应该从具体类派生、任何方法都不应该覆写基类中已经实现的方法,它解决了层间耦合的问题。IoC是Inversion of Control控制反转,传统模式中是类和类之间直接调用,所以有很强的耦合度,程序之间的依赖关系比较强,后期维护时牵扯的比较多。用配置文件(XML)来描述类与类之间的关系,由容器来管理,降低了程序间的耦合度,程序的修改可以通过简单的配置文件修改来实现,它也可以叫做DI,意思是Dependency Injection依赖注入,也就是先将依赖剥离,再在适当时候注入。例如:
 
  A.java:调用类  
  IB.java:接口类,有一个printHello()的抽象方法。  
  BImpl.java:IB接口的实现类,实现了printHello()这个方法,打印出一些信息。 
 
  比如我要在A.java中调用IB.java接口的printHello()方法来打印信息。 
 
  以前的做法是在A中:  
  private IB b = new BImpl();  
  public void doPrint()
  {  
     b.printHello();  
  }
  这个b变量就指向了一个具体类BImpl。  
   
  使用控制反转后:  
  private IB b;  
  public void setB(IB b)
  {  
     this.b= b;
  }  
  public void doPrint()
  {
     b.printHello();  
  }

  现在b就不指向具体的实现类BImpl了。现在的问题是A怎么调用实现类的真正方法来打印信息呢,那就是IoC容器的工作了,比如Spring,通过一个配置文件来告诉A应该使用哪一个具体的实现类。A中的这个setB方法的作用就像一个注射器,把BImpl注射到A中。所以这种方式又有另外一个名字:依赖注射,这里的依赖已经被剥离了,就等IoC容器的容器注入类IB的对象。IOC有一句精典的话:“你呆着别动,到时我会找你”,如果你理解了这句话,我相信你已经会用IOC了。在IoC的众多容器中,轻量级的有Pico Container、Avalon、Spring、HiveMind等,超重量级的有EJB,而半轻半重的有容器有JBoss,Jdon等

===========================================================================================
问:try, catch的使用原则?

答:举一个NHibernate的例子
ISession session;
ITransaction tx;

try
{
session = factory.OpenSession();
tx = session.BeginTransaction();
// do database work
tx.Commit();
session.Close();
}
catch (Exception ex)
{
tx.Rollback();
session.Close();
// further exception handling
}

I can’t claim to know the inner workings of OpenSession but if there’s a chance it throws and surfaces an exception, the catch is going to access a null reference, tx. General advice:

Acquire Resource;
Try
Do Something with Resource
Catch
Do something
Finally
Release Resource

Actually there’s a semantic implication of OpenSession. To me it should either return a valid ISession reference to an open reference or it should throw an exception. The same goes for BeginTransaction. So, IMHO this is how to write it (my 2c):

ISession session = factory.OpenSession();
try
{
  ITransaction tx = session.BeginTransaction();
  try
  {
    // do db work
    tx.Commit();
  }
  catch
  {
    tx.Rollback();
  }
}
finally
{
  session.Close();
}

Both session in finally and tx in catch will be valid references provided that OpenSession and BeginTransaction returns what they atomically should return, i.e. an open session in the former case and a started transaction in the latter case.

 

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

Sql Server + ADO + C#
NHibernate: 持久化数据库对象.提供数据库表与对象的相互映射.XML建立规则
Web Service:  网站不提供HTML页面而提供接口供其他网站和终端应用程序访问.XML作为数据媒介.
Web Services: 整个架构Web服务的技术框架.它包括XML/SOAP/WSDL/UDDI等.Web Service是它的实例

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

问:访问数据库的方式?

答:使用VS.NET平台访问数据库是采用ADO.NET(ActiveX Data Object .NET)方式,它提供很多种访问数据库的接口,但总的来说分为两类,一类通用接口,一类专用接口,专用接口效率很好,例如访问Oracle,MySql的专用接口。这些接口都包含共有的方法。ADO.NET访问数据库的各种模式:OLEDB, ODBC, SqlClicen(Sql Server), Oracle, MySql等

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

问:为什么大家都用Response.Redirect("abc.aspx?id="+id.toString()+"&pw="+pw.toString(), false)?为什么一定要用false参数呢?

答:因为如果不用false参数去EndResponse的话,很容易出现“正在中止进程”,“线程终止异常”的问题。

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

问:如何给控件如删除按钮添加一个确认对话框?

答:如果是普通按钮,只需要在页面load的时候加入“this.btTest.Attributes.Add("onclick", "return confirm(/"确定要删除这(些)记录吗/");");”,如果是在DataGrid或者DataList里的按钮,则需要触发它们的时间ItemDataBind,然后在事件处理里写入“if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem){ImageButton button = (ImageButton)e.Item.FindControl("Imagebutton2");button.Attributes.Add("onclick", "return confirm(/"确定要删除此项记录吗/");");}”就行了

============================================================================================
问:如何禁止用户返回上一页,由于上一页提交了表单,我进入该页后返回上一页则又要提交一遍,郁闷

答:禁用浏览器后退之方法比较

    浏览器的后退按钮使得我们能够方便地返回以前访问过的页面,它无疑非常有用。但有时候我们不得不关闭这个功能,以防止用户打乱预定的页面访问次序。本文介绍网络上可找到的各种禁用浏览器后退按钮方案,分析它们各自的优缺点和适用场合。

    一、概述

  曾经有许多人问起,“怎样才能‘禁用’浏览器的后退按钮?”,或者“怎样才能防止用户点击后退按钮返回以前浏览过的页面?”在ASP论坛上,这个问题也是问得最多的问题之一。遗憾的是,答案非常简单:我们无法禁用浏览器的后退按钮。起先我对于居然有人想要禁用浏览器的后退按钮感到不可思议。后来,看到竟然有那么多的人想要禁用这个后退按钮,我也就释然(想要禁用的只有后退按钮,不包括浏览器的前进按钮)。因为在默认情况下,用户提交表单之后可以通过后退按钮返回表单页面(而不是使用“编辑”按钮!),然后再次编辑并提交表单向数据库插入新的记录。这是我们不愿看到的。因此我就决定要找出避免出现这种情况的方法。我访问了许多网站,参考了这些网站所介绍的各种实现方法。如果你经常访问ASP编程网站,本文所介绍的部分内容你可能已经见到过。本文的任务是把各种可能的方法都介绍给大家,然后找出最好的方法!

    二、禁止缓存

  在我找到的许多方案中,其中有一种建议禁止页面缓存。具体是使用服务器端脚本,如下所示(已测试通过):
<%
Response.Buffer=true;
Response.ExpiresAbsolute=System.DateTime.Now.AddDays(-1);
Response.Expires=0;
Response.CacheControl="no-cache";
%>
    这种方法非常有效!它强制浏览器重新访问服务器下载页面,而不是从缓存读取页面。使用这种方法时,编程者的主要任务是创建一个会话级的变量,通过这个变量确定用户是否仍旧可以查看那个不适合通过后退按钮访问的页面。由于浏览器不再缓存这个页面,当用户点击后退按钮时浏览器将重新下载该页面,此时程序就可以检查那个会话变量,看看是否应该允许用户打开这个页面。例如,假设我们有如下表单(未测试):
<%
Response.Buffer=true;
Response.ExpiresAbsolute=System.DateTime.Now.AddDays(-1);
Response.Expires=0;
Response.CacheControl="no-cache";
If  Len(Session(  "FirstTimeToPage  "))    >  0  then
&single;  用户已经访问过当前页面,现在是再次返回访问。
&single;  清除会话变量,将用户重定向到登录页面。
Session(  "FirstTimeToPage  ")  =    "  "
Response.Redirect    "/Bar.asp  "
Response.End
End  If
&single;  如果程序运行到这里,说明用户能够查看当前页面
&single;  以下开始创建表单
%>
<form  method=post  action=  "SomePage.asp  "  >
<  input  type=submit  >
<  /form  >
    我们借助会话变量FirstTimeToPage检查用户是否是第一次访问当前页面。如果不是第一次(即Session(  "FirstTimeToPage  ")包含某个值),那么我们就清除会话变量的值,然后把用户重新定向到一个开始页面。这样,当表单提交时(此时SompePage.asp被打开),我们必须赋予FirstTimeToPage一个值。即,在SomePage.asp中我们需要加上下面的代码:
Session(  "FirstTimeToPage  ")="NO  "
    这样,已经打开SomePage.asp的用户如果点击后退按钮,浏览器将重新请求服务器下载页面,服务器检查到Session("FirstTimeToPage  ")包含了一个值,于是就清除Session(  "FirstTimeToPage  "),并把用户重定向到其他页面。当然,所有这一切都需要用户启用了Cookie,否则会话变量将是无效的。(有关该问题的更多说明,请参见For  session  variables  to  work,  must  the  Web  visitor  have  cookies  enabled?)
    另外,我们也可以用客户端代码使浏览器不再缓存Web页面:
 <  html  >
 <  head  >
 <  meta  http-equiv=  "Expires  "  CONTENT=  "0  "  >
 <  meta  http-equiv=  "Cache-Control  "  CONTENT=  "no-cache  "  >
 <  meta  http-equiv=  "Pragma  "  CONTENT=  "no-cache  "  >
 <  /head  >
    如果使用上面的方法强制浏览器不再缓存Web页面,必须注意以下几点:
    只有在使用安全连接时“Pragma:  no-cache”才防止浏览器缓存页面。对于不受安全保护的页面,“Pragma:  no-cache”被视为与“Expires:  -1”相同,此时浏览器仍旧缓存页面,但把页面标记为立即过期。
    在IE  4或5中,“Cache-Control”META  HTTP-EQUIV标记将被忽略,不起作用。
  在实际应用中我们可以加上所有这些代码。然而,由于这种方法不能适用于所有的浏览器,所以是不推荐使用的。但如果是在Intranet环境下,管理员可以控制用户使用哪种浏览器,我想还是有人会使用这种方法。

    三、其他方法

  接下来我们要讨论的方法以后退按钮本身为中心,而不是浏览器缓存。这儿有一篇文章Rewiring  the  Back  Button很值得参考。不过我注意到,如果使用这种方法,虽然用户点击一下后退按钮时他不会看到以前输入数据的页面,但只要点击两次就可以,这可不是我们希望的效果,因为很多时候,固执的用户总是能够找到绕过预防措施的办法。
  另外一种禁用后退按钮的办法是用客户端JavaScript打开一个没有工具条的窗口,这使得用户很难返回前一页面,但不是不可能。一种更安全但相当恼人的方法是,当表单提交时打开一个新的窗口,与此同时关闭表单所在的窗口。但我觉得这种方法不值得认真考虑,因为我们总不能让用户每提交一个表单就打开一个新窗口。
  那么,在那个我们不想让用户返回的页面是否也可以加入JavaScript代码呢?在这个页面中加入的JavaScript代码可用来产生点击前进按钮的效果,这样也就抵消了用户点击后退按钮所产生的动作。用于实现该功能的JavaScript代码如下所示:
<  script  language=  "JavaScript  "  >
<  !--
javascript:window.history.forward(1);
//--  >
<  /script  >
    同样地,这种方法虽然有效,但距离“最好的方法”还差得很远。后来我又看到有人建议用location.replace从一个页面转到另一个页面。这种方法的原理是,用新页面的URL替换当前的历史纪录,这样浏览历史记录中就只有一个页面,后退按钮永远不会变为可用。我想这可能正是许多人所寻求的方法,但这种方法仍旧不是任何情况下的最好方法。使用这种方法的实例如下所示:
<A  HREF=  "PageName.htm  "  οnclick=  "javascript:location.replace(this.href);
event.returnValue=false;    "  >
禁止后退到本页面的链接  <  /A  >
    试试下面这个链接:
    禁止后退到本页面的链接!
    这种方法的缺点在于:简单地运用Response.Redirect将不再有效,这是因为每次用户从一个页面转到另一个页面,我们都必须用客户端代码清除location.history。另外还要注意,这种方法清除的是最后一个访问历史记录,而不是全部的访问记录。
    点击上面的链接,你将打开一个简单的HTML页面。再点击后退按钮,你可以看到这时打开的不是本页面,而是本页面之前的页面!(当然,你必须在浏览器中启用了客户端JavaScript代码。)
    经过一番仔细的寻寻觅觅之后,我发现仍旧无法找出真正能够完全禁用浏览器后退按钮的办法。所有这里介绍的方法都能够在不同程度上、以不同的方式禁止用户返回前一页面,但它们都有各自的局限。由于不存在能够完全禁用后退按钮的方法,所以最好的方案应该是:混合运用客户端脚本和服务器端脚本。
    别人的东西,看看如何

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

问:如何设定存储过程的返回值呢?

答:select一般返回dataset,datatable,sqldatareader等,Insert,Update一般返回void,delete就麻烦些,如果删除的表里存在外键约束,那么就要返回bool,要求其删除与该表相关的字段再删除该表字段,如果是一个单表,则可返回void

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

问:类型转换,Convert.ToInt32和Int32.Parse有什么区别?

答:Convert.ToInt32(abc),可将任意类型的abc转换成int32型,而Int32.Parse(abc)中,abc只能是字符串,其实Convert.ToInt32 会把最终的解析工作代理给 Int32.Parse;Int32.Parse 会把最终的解析工作代理给Number.ParseInt32;Int32.TryParse 会把最终的解析工作代理给Number.TryParseInt32。

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

问:我知道前一页Session["abc"] = "def",下一页使用也是Session["abc"],而怎么用Request获取值呢?进入这一页为nextpage?id=1?

答:在该页一般使用Request.QueryString["id"],但因其太烦琐,我们可直接使用Request.Params["id"],因为Params是这些数据的集合体,VS2005新出的哦。

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

问:如何添加确认对话框?

答:在Page_Load里写button.Attributes.Add("onclick", "return confirm(/"确定要删除此项记录吗/");");,如果写在button自己的事件里,第一次执行是没有此提示的。但是,如果是绑定列等隐式控键则需要这样做,例如DataList类型的dl,在它的ItemDataBind事件里初始化该功能就行了,在里面写if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem){ImageButton button = (ImageButton)e.Item.FindControl("ImageButton2");button.Attributes.Add("onclick", "return confirm(/"确定要删除此项记录吗/");");}就可以添加上去了。

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

问:如何响应DataList, DataGrid里的CheckBox, EditButton, DeleteButton?

答:CheckBox写在DataList, DataGrid里的模板列里<asp:TemplateColumn><ItemTemplate><asp:CheckBox id="CheckBox1" runat="server"></ItemTemplate></TemplateColumn>,而其他数据库的列则在<asp:BoundColumn></BoundColum>里,点了它不会自己触发,需要其他按钮触发,在按钮事件里判断foreach(DataGridItem thisItem in dg.Items){if(((CheckBox)thisItem.FindControl("CheckBox1")).Check == true) ...};而EditButton和DeleteButton则是点击则触发事件ItemCommand,在页面里同数据一样,写在<ItemTemplate><asp:Button CommandName='编辑'></Button><asp:ImageButton CommandName='删除'></ImageBotton><Label Test = '<%# DataBinder.Eval(Container.DataItem, "字段名"') %></Label></ItemTemplate>里,我们在ItemCommand事件里判断e.CommandName是等于'编辑'还是'删除'就可以作出操作了,对了,记得把DataGrid和DataList里的DataKeyField里的字段填上,为绑定的表的主键,经常用了,例如事件ItemCommand里就要用,判断哪一行编辑, int index = (int)dl.DataDeys[e.Item.ItemIndex];CheckBox则要每行都要判断是否Check了,Checked为true才进行操作。

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

问:DataGrid的DataSource可以是哪些对象?

答:ArrayList,Collection,DataSet,DataTable,DataView,SqlDataReader等Object都可以的。dg.DataSource=xxx;dg.DataBind();

问:为什么无法在Web服务器上启动调试,它说您不具备调试此应用程序的权限?

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

答:出现这个错误的原因不详,但可能是因为安装了IE7.0,在VS2003.net中来调试C#写的ASP.net程序,启动时会出现这个错误,不能调试。一般用下面的方法1项或者多项就可以解决:
1:确认在“配置属性”中的“启用ASP.NET调试"为"True"
2:确认你的"web.config"中的"debug=true"
3:若你安装过Win2000 SP4后,则要在命令行执行"regsvr32 i aspnet_isap.dll"
4:在IIS里查看站点信息,选中"目录安全性",里面有"匿名访问和身份验证控制",再点击"编辑..",确认"集成Windows身份验证"选项被选中
5:在IE选项->"安全设置"->"自定义级别"里有"用户验证",确认选中"自动使用当前用户名和密码登录"
6:运行C:/WINDOWS/Microsoft.NET/Framework/v1.1.4322/aspnet_regiis.exe -i
7:控制面板--管理工具--计算机管理--本地用户和组--用户,双击ASPNET用户,为其隶属于添加Administrators用户

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

问:为什么局域网内的其他用户看不到我的IIS里的网站呢?它提示SQL Server 不存在或访问被拒绝处理方法。

答:ping 127.0.0.1 1433 失败则查看Sql Server Configuration Management里,打开tcpip连接

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

问:在WebPage页里使用DataGrid的时候,在里面加入了模板列,里面放了一个CheckBox控件,但在前台页面,无论我怎么选,提交的时候都是false?

答:要解决这个问题这需要在第一次绑定该DataGrid数据的时候添加这样一行:
if(!this.Page.IsPostBack)
{
 dgTest.DataDource = ...;
 dgTest.DataDind();
}
特别是对于上一页传递过来的数据我们需要首次显示的时候,都写如这个函数体之内,不然会出问题

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

问:如何选择模板列里面CheckBox的值?

答:((CheckBox)dgTest.Items.FindControl("CheckBox1")).Checked = ...;

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

问:页面上有哪些可以存储当前页面的参数状态?

答:Request, Response, Session, ViewState(可关闭,保存的是上一页的参数,用于返回上一页用)

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值