RSS
 

Archive for 九月, 2008

实习第八周

28

本周基本是国庆的预备周,期待着整整一周的休息。
不知不觉其实‘上班’已经两个月,上班的日子比起学习的日子来是不舒服的,至少作息时间上不是自己掌握的,比朝九晚五还夸张,天天7点起床。
慢慢习惯了手头的工作:项目+一些杂事,基本上来说算是能够handle的比较随心所欲。由于下周要花比较多时间休息和复习保研,所以本周就得完成较多的工作。
帮手同学开始帮忙了,沉静了很长时间,当然对作品本身是有怀疑的,至少自己不能接受这样的产品。好在总比没有好,算是一个开端吧。
慢慢学会用标准ASP.net进行开发,而不是自己写很多代码:其实Detail View和Grid View两个工具非常高级,几乎可以搞定全部的增删改查。可惜知道的晚了一些,代码浪费的多了一些,而且为了整体统一还得继续浪费代码。
在新的模块中准备尝试使用这种开发方式,这才是ASP.net的魅力所在吧。
即便开发完这个系统,希望能够花更多的时间对这个Framework的架构和ASP.net的各个设计能够好好理解掌握。第一次发现掌握一门技术其实比略懂很多技术要有意义有兴趣的多。这看来又是一个很好的开端。
其实这段时间有点不是很confident,直到被人教育。虽然我一直崇尚的哲学史人人品等,或者说大家其实实力类似,这似乎成了我没有自信的理由。希望这种日子早点过去,人生的闪光早点到来!
再次期待国庆。

 
 

在ASP.NET中使用ObjectDataSource数据控件和GridView操作数据

25

通过前两次的内容我们已经实现了带有分页和排序的显示数据,那么我们如何用ObjectDataSource来帮助我们实现删改

还是老办法我们先实现DAL层和BLL层当中的操作数据的方法

        [DataObjectMethod(DataObjectMethodType.Insert)]
        public static void InserUserInfo(UserInfo info)
        {
            DAL.UserInfoDAL.InsertUserInfo(info);
        }

        [DataObjectMethod(DataObjectMethodType.Update)]
        public static void UpdateUserInfo(UserInfo info)
        {
            DAL.UserInfoDAL.UpdateUserInfo(info);
        }

        [DataObjectMethod(DataObjectMethodType.Delete)]
        public static void DeleteUserInfo(UserInfo info)
        {
            DAL.UserInfoDAL.DeleteUserInfo(info);
        }

这里我们可以发现我这里传递的都是UserInfo对象了.至于好处嘛,我认为你在赋值的时候通过属性对其处理安全性更好一些.反正我总觉得比传一大堆的变量过来要好.所以这里采用这个方式.

如果你要采用我这种方式那么就需要注意你的ObjectDataSource中的一个属性是否正确设置了

image

这里我设置为我查询出的对象UserInfo

image

这样你就可以来实现删除和修改了.有些人就问呀!我没有像以前那样设置传递的参数啊.^_^

这里当你设置了ObjectDataSource的DataObjectTypeName,当你执行相关操作的时候 ObjectDataSource就会自动生成一个你设置的对象并且将行内的值一一对应的传入到你的这个对象.然后直接将这个对象传入到你的BLL中的方 法.但是要注意,这里还是有很多陷阱的

第一个陷阱 由数据冲突引起的问题image
在ObjectDataSource中有个属性↑

这里属性来设置如何处理是否新旧值一起处理

MSDN上的描述为:获取或设置一个值,该值确定是仅将新值传递给 Update 方法,还是将旧值和新值都传递给 Update 方法。

当这里使用默认的OverwriteChanges的时候传递的值内容为你更改后值.这里传递是我们修改后的对象值.所以默认状态下你的更新是没有问题的.

但如果你要处理新旧值的时候就需要设置到CompareAllValues.但是这时你再更新数据的时候就会报错了.

为什么会这样呢?原来当你设置为CompareAllValues的时候他需要给你BLL层传递过两个对象,一个是原来的UserInfo一个是你修改后的Userinfo.

所以你的方法需要改成这样

        [DataObjectMethod(DataObjectMethodType.Update)]
        public static void UpdateUserInfo(UserInfo info,UserInfo original_info)
        {
            ......
        }

这里发现我们的更新方法多了后面的一个参数叫original_info,这样才能将我们的修改后的内容正确更新回数据库,而且这里的original_这个前缀可以通过修改image来实现.

陷阱二,键字段的问题.

那当我们ConflicDetection使用默认的OverwriteChanges值的时候我们进行删除操作.发现没有删除了我们想要操作的那条记录.然后通过监视可以发现传递到BLL中的UserInfo对象虽不为空.但是里面属性的值都为默认值

image

那为什么会出现这个问题呢?我认为是,删除操作并没有修改我GridView中的记录所以在ConflicDetection使用默认的 OverwriteChanges值的时候传递过的对象里要是有值只能是修改后的值.所以这里你要通过id来删除则只能删除记录为0的了.^_^

所以通常来说删除不了你想要的内容,但是不出错.

那怎么办呢?这里因为我们使用的是集合所以在编写GridView的时候少设置了一个属性,那就是image

这里我们添加上键字段id.再来看看效果

image

这次发现,虽然这里没有吧UserInfo对象完整的传递过来.但是我们想要的id值过来了.^_^

 
 

ASP.net页面和控件生命期

25

1. 点击按钮postback或页面第一次载入都会导致页面信息失效,任何private变量都会重新构造,但postback的数据会恢复。
2. 数据构造好后进入页面的page_load,然后进入控件的page_load,如果在页面load中对控件进行调用,则该调用在控件page_load之前执行。
3. 如果点击按钮,则按钮的函数会在page_load都结束后执行,如果在这里对控件进行调用,则该调用在控件page_load之后执行。
4. 因此无法保证控件的page_load一定是控件第一次被执行的函数,所以如果对于消息类的控件,需要初始化,则需要显示构造初始化函数,由页面的page_load显示调用,该调用可以保证永远在任何函数前执行。

 
 

Asp.net中访问Excel权限问题

21

正确的做法:

1:在服务器上安装office的Excel软件.

2:在”开始”->”运行”中输入dcomcnfg.exe启动”组件服务”

3:依次双击”组件服务”->”计算机”->”我的电脑”->”DCOM配置”

4:在”DCOM配置”中找到”Microsoft Excel 应用程序”,在它上面点击右键,然后点击”属性”,弹出”Microsoft Excel 应用程序属性”对话框

5:点击”标识”标签,选择”启动用户”//默认访问,不要选交互式用户

6:点击”安全”标签,在”启动和激活权限”上点击”自定义”,然后点击对应的”编辑”按钮,在弹出的”安全性”对话框中填加一个”NETWORK SERVICE”用户(注意要选择本计算机名),并给它赋予”本地启动”和”本地激活”权限.

7:依然是”安全”标签,在”访问权限”上点击”自定义”,然后点击”编辑”,在弹出的”安全性”对话框中也填加一个”NETWORK SERVICE”用户,然后赋予”本地访问”权限.

如果是8000401a错误

右键打开属性对话框,点击”标识”选项卡,

点”下列用户”,把管理员的用户密码正确填写进去…

点击”安全”选项卡,

依次把”启动和激活权限”,”访问权限”,”配置权限”,都选择为自定义,

然后依次点击它们的编辑,把everyone添加进去,并加入所有的权限…

这样,我们便配置好了相应的Excel的DCOM权限.

 
 

实习第七周

21

本周主要做的是遗留的学生信息管理功能以及新闻发布功能。其中也学到了很多知识。
比如Page的生命期问题,private变量的值是不保持的,每次页面load都会重新计算,当然如果在定义时设定了一个初始值,则每次还是会按照那个值进行初始化。一种避免的办法是和一个Hidden变量绑定,从而只要在页面第一次载入的时候初始化即可。
在FCKEditor集成的方面应该说也做了很多工作,但比想象的来的简单。下载最新版的控件以及C#的dll类以后,简单设置即可完成强大的功能。甚至这个控件也可以完成附件上传等功能。唯一遗憾的是,粘帖本地附件不能自动上传(比如word中的图片)
对于一些控件的参数传递也有了更好的了解,如果绑定了参数则不需要进一步的工作,否则需要截获datasource的selecting消息,在这里添加param信息。

 
 

ASP.net page private对象生命期

19

private 变量每次post都会初始化,但是如果在静态变量的地方有默认定义,则按照此定义初始化,否则为空或其它默认值。不重要的数据可以通过绑定 hiddenfield的方式避免每次load界面初始化,而只在第一次进入页面的时候初始化。重要的数据还是只能每次赋值。

 
 

FCKEditor配置

18

一、准备工作
首先下载最新版的FCKeditor V2.3,下载地址:http://prdownloads.sourceforge.net/fckeditor /FCKeditor_2.3.zip?download;这个压缩包里并不包含ASP.NET要用到的DLL控件,所以还要下载另外一个压缩包,下载地 址:http://sourceforge.net/project/showfiles.php?group_id=75348& package_id=137125。把第一个文件解压到WEB根目录,默认文件夹名为:FCKeditor;再把第二个包解压,里面包含了源代码,如果 你想自己再次开发,可以双击 FredCK.FCKeditorV2.csproj文件,打开VS.NET进行修改,所用的语言是C#;不想修改的话,直接把bin\Release下 面的FredCK.FCKeditorV2.DLL文件拷到WEB目录的bin下面。
二、精简文件
因为只用到ASP.NET,所以有必要精简一下文件。
进入FCKeditor文件夹,把所有“_”开头的文件和文件夹删掉,这些都是一些范例,只保留editor文件夹、fckconfig.js、fckeditor.js、fckstyles.xml、fcktemplates.xml就可以了;
进入editor文件夹,删掉“_source”文件夹,里面放的同样是源文件;
退回上一级目录进入filemanager文件夹,有browser和upload两个文件夹。进入browser\default\connectors,只保留aspx文件夹,其余的删掉;mcpuk目录亦可删除;upload也一样,只保留aspx文件夹;
退到editor再进入images文件夹,smiley里面放的是表情图标,有msn和fun两个系列,如果你想用自己的表情图标,可以把它们都删除;如果你想用这里的表情图标那就不要删了;
lang里面放的是语言包,如果只是用简体中文,那么只保留fcklanguagemanager.js、zh-cn.js两个文件就行了,建议也保留 en.js(英文)、zh.js(繁体中文)两个文件,fcklanguagemanager.js是语言配置文件,有了它才能和 fckconfig.js里的设置成对,对应上相应的语言文件,一定要保留!
再退出lang文件夹,进入skins文件夹,如果你想使用FCKeditor默认的奶黄色,那就把除了default文件夹外的另两个文件夹直接删除,如果想用别的,那就看你自己的喜好了,不要上传文件的话把filemanager也删除算了。
至此,文件精简完毕,由原来的2.55M变成现在的689K了。接着修改设置。
三、修改设置
打开位于根目录的fckconfig.js文件。
FCKConfig.SkinPath = FCKConfig.BasePath + ’skins/default/’ ;这行是设置皮肤的,如果精简时保留了silver,就把路径改成skins/silver,默认就不用管它了;
FCKConfig.DefaultLanguage = ‘en’ ;设置默认语言,把en改成zh-cn,即简体中文;
FCKConfig.TabSpaces = 0;如果在编辑过程中要用到TAB键,就把0改成1;
因为FCKeditor默认是ASP的,所以要把它换成ASP.NET。把ASP跟其它被注释掉的代码删掉,用ASP.NET来代替。例如:
var _FileBrowserLanguage    = ‘aspx’
var _QuickUploadLanguage    = ‘aspx’
余下的代码都按照以上操作,删掉其它WEB语言,只保留ASP.NET。也可以点这里下载我精简过的文件,注意:只适用于ASP.NET,其他语言勿下!建议先解压到别的目录,再复制到WEB目录相对应的位置,以免造成文件丢失。
改完后保存,FCKeditor已经完全支持ASP.NET了。当然还有一些安全问题,只要修改相应的toolbar,鼠标右键菜单等等,因为我的后台 不面对前台用户的,即没有留言本和日记回复,所以略过这些步骤。下一步是打开VS.NET,在ASP.NET页面中加入FCKeditor。
四、ASP.NET中的应用
打开项目的“资源管理器”,添加“FredCK.FCKeditorV2”引用。
打开添加文章、管理文章相对应的文件以修改其中的内容。下面以“添加文章”为例。切换到“HTML”界面,添加FCK的引用,代码如下:
<%@ Register TagPrefix=”FCKeditorV2″ Namespace=”FredCK.FCKeditorV2″ Assembly=”FredCK.FCKeditorV2″ %>
并 确保@ Page中的“AutoEventWireup”“validateRequest”两个值都为false,不然当你发表的文章中含有链接或是其他 HTML语句时,.NET会警告你有安全隐患而出错。在form的适当位置加入FCKeditor控件,当然form一定要有“runat= “server””,代码如下:
<FCKeditorV2:FCKeditor id=”content” runat=”server”></FCKeditorV2:FCKeditor>
id可以自己命名,自己喜欢易记就行。如果程序中有检测输入是否为空的话,那么就不再是content.Text了,而是content.Value。
五、文件上传的配置
找到文件fckeditor\editor\filemanager\connectors\aspx\config.ascx
需要配置文件上传权限,文件上传目录,文件上传类型等。
六、相关问题处理
上传图片正常,上传文件:Invalid Request
FCKConfig.LinkBrowserURL = FCKConfig.BasePath + ‘filemanager/browser/default/browser.html?Type=File&Connector=../../../../connector.’ + _FileBrowserExtension;
And the quick upload looks like this (added + ‘?Type=File’ ):
FCKConfig.LinkUploadURL = FCKConfig.BasePath + ‘../upload.’ + _QuickUploadExtension + ‘?Type=File’ ;

 
 

编程设置ObjectDataSource参数

17

图 7: 选择GetEmployeesByHiredDateMonth(month)方法
单击显示全图,Ctrl+滚轮缩放图片
最后一屏要求我们给month参数提供参数源。既然我们将编码设置这个值,就让参数源维持它的默认选项None,点击“完成”。
图 8: 让参数源设置为None
单击显示全图,Ctrl+滚轮缩放图片
这将在ObjectDataSource的SelectParameters集合里创建一个未指定参数值的Parameter对象。

阅读 编辑 运行 复制 保存

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" OldValuesParameterFormatString="original_{0}"

    SelectMethod="GetEmployeesByHiredDateMonth" TypeName="EmployeesBLL">

    <SelectParameters>

        <asp:Parameter Name="month" Type="Int32" />

    </SelectParameters>

</asp:ObjectDataSource>

<asp:ObjectDataSource ID=”ObjectDataSource1″ runat=”server” OldValuesParameterFormatString=”original_{0}” SelectMethod=”GetEmployeesByHiredDateMonth” TypeName=”EmployeesBLL”> <SelectParameters> <asp:Parameter Name=”month” Type=”Int32″ /> </SelectParameters> </asp:ObjectDataSource>

要编码设置这个参数值,我们需要给ObjectDataSource的Selecting事件添加一个事件委托。为了实现这一点,到设 计视图里在 ObjectDataSource上双击。另一种方式是选中ObjectDataSource在属性窗口里点击黄色闪电小图标,然后,直接在 Selecting这一栏里双击或者输入一个你要使用的事件委托的名称。
图 9:点击属性窗口里的闪电图标列出Web控件的所有事件
单击显示全图,Ctrl+滚轮缩放图片
两 种途径都可以在页面的代码隐藏类里增加一个对ObjectDataSource的Selecting事件的事件委托。在这个事件委托里,我们可以通过使用 e.InputParameters[parameterName]读取参数的值,其中parameterName的值 是<asp:Parameter>标签里的属性Name的值(InputParameters也可以按照索引访问,用 e.InputParameters[index])。为了把month参数设置为当前月份,需要在Selecting事件委托里加入如下代码:

复制 保存

protected void ObjectDataSource1_Selecting(object sender, ObjectDataSourceSelectingEventArgs e)
{
    e.InputParameters["month"] = DateTime.Now.Month;
}
 
 

有关ASP.net

17

控件的值可以postback;不是控件的值刷新后会消失(比如private变量或者Page.Title之类属性)
GridView在页面post的时候压根不重复取数据,而是在页面的代码中自动重新绑定才去获取数据,即数据的重新获取是手动的,肯定在button事件之后。

 
 

ObjectDataSource强类型源对象示例

17

注意:由于GridView的参数解析可能有问题,如果自定义函数的参数中有除了sortColumns的参数,即page的参数,必须在grid和objectdatasource都定义page为true
ASP.NET

ObjectDataSource 强类型源对象示例

阐释可以和 ObjectDataSource 控件一起使用的自定义中间层业务对象。

示例

下面的代码示例阐释可以和 ObjectDataSource 控件一起使用的自定义中间层业务对象,该控件使用 DataObjectTypeName 属性来指定一个强类型源对象。本主题还阐释了一个将业务对象用作 ObjectDataSource 控件的源的示例 ASP.NET 页。该页包含与 ObjectDataSource 控件绑定的 GridView 控件和 DetailsView 控件。

若要使用该代码,您可以在 Web 应用程序的 App_Code 子目录中创建一个代码文件,然后将代码复制到该文件。然后,业务对象将被动态编译并作为 Web 应用程序的一部分包含在应用程序中。或者,您可以编译业务对象,然后将它放入 ASP.NET 应用程序的 Bin 目录中或全局程序集缓存 (GAC) 中。有关 App_Code 和 Bin 目录的更多信息,请参见 ASP.NET 网站中的共享代码文件夹

using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Samples.AspNet.ObjectDataSource
{
  public class NorthwindEmployee
  {
    private int _employeeID;
    private string _lastName;
    private string _firstName;
    private string _address;
    private string _city;
    private string _region;
    private string _postalCode;

    public NorthwindEmployee()
    {
    }

    public int EmployeeID
    {
      get { return _employeeID; }
      set { _employeeID = value; }
    }

    public string LastName
    {
      get { return _lastName; }
      set { _lastName = value; }
    }

    public string FirstName
    {
      get { return _firstName; }
      set { _firstName = value; }
    }

    public string Address
    {
      get { return _address; }
      set { _address = value; }
    }

    public string City
    {
      get { return _city; }
      set { _city = value; }
    }

    public string Region
    {
      get { return _region; }
      set { _region = value; }
    }

    public string PostalCode
    {
      get { return _postalCode; }
      set { _postalCode = value; }
    }
  }

  //
  //  Northwind Employee Data Factory
  //

  public class NorthwindEmployeeData
  {

    private string _connectionString;

    public NorthwindEmployeeData()
    {
      Initialize();
    }

    public void Initialize()
    {
      // Initialize data source. Use "Northwind" connection string from configuration.

      if (ConfigurationManager.ConnectionStrings["Northwind"] == null ||
          ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString.Trim() == "")
      {
        throw new Exception("A connection string named 'Northwind' with a valid connection string " +
                            "must exist in the <connectionStrings> configuration section for the application.");
      }

      _connectionString =
        ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString;
    }

    // Select all employees.

    public List<NorthwindEmployee> GetAllEmployees(string sortColumns, int startRecord, int maxRecords)
    {
      VerifySortColumns(sortColumns);

      string sqlCmd = "SELECT EmployeeID, LastName, FirstName, Address, City, Region, PostalCode FROM Employees ";

      if (sortColumns.Trim() == "")
        sqlCmd += "ORDER BY EmployeeID";
      else
        sqlCmd += "ORDER BY " + sortColumns;

      SqlConnection conn = new SqlConnection(_connectionString);
      SqlCommand    cmd  = new SqlCommand(sqlCmd, conn);

      SqlDataReader reader = null;
      List<NorthwindEmployee> employees = new List<NorthwindEmployee>();
      int count = 0;

      try
      {
        conn.Open();

        reader = cmd.ExecuteReader();

        while (reader.Read())
        {
          if (count >= startRecord)
          {
            if (employees.Count < maxRecords)
              employees.Add(GetNorthwindEmployeeFromReader(reader));
            else
              cmd.Cancel();
          }          

          count++;
        }

      }
      catch (SqlException e)
      {
        // Handle exception.
      }
      finally
      {
        if (reader != null) { reader.Close(); }
        conn.Close();
      }

      return employees;
    }

    //////////
    // Verify that only valid columns are specified in the sort expression to avoid a SQL Injection attack.

    private void VerifySortColumns(string sortColumns)
    {
      if (sortColumns.ToLowerInvariant().EndsWith(" desc"))
        sortColumns = sortColumns.Substring(0, sortColumns.Length - 5);

      string[] columnNames = sortColumns.Split(',');

      foreach (string columnName in columnNames)
      {
        switch (columnName.Trim().ToLowerInvariant())
        {
          case "employeeid":
            break;
          case "lastname":
            break;
          case "firstname":
            break;
          case "":
            break;
          default:
            throw new ArgumentException("SortColumns contains an invalid column name.");
            break;
        }
      }
    }

    private NorthwindEmployee GetNorthwindEmployeeFromReader(SqlDataReader reader)
    {
      NorthwindEmployee employee = new NorthwindEmployee();

      employee.EmployeeID = reader.GetInt32(0);
      employee.LastName   = reader.GetString(1);
      employee.FirstName  = reader.GetString(2);

      if (reader.GetValue(3) != DBNull.Value)
        employee.Address = reader.GetString(3);

      if (reader.GetValue(4) != DBNull.Value)
        employee.City = reader.GetString(4);

      if (reader.GetValue(5) != DBNull.Value)
        employee.Region = reader.GetString(5);

      if (reader.GetValue(6) != DBNull.Value)
        employee.PostalCode = reader.GetString(6);

      return employee;
    }

    // Select an employee.

    public List<NorthwindEmployee> GetEmployee(int EmployeeID)
    {
      SqlConnection conn = new SqlConnection(_connectionString);
      SqlCommand    cmd  =
        new SqlCommand("SELECT EmployeeID, LastName, FirstName, Address, City, Region, PostalCode " +
                       "  FROM Employees WHERE EmployeeID = @EmployeeID", conn);
      cmd.Parameters.Add("@EmployeeID", SqlDbType.Int).Value = EmployeeID;

      SqlDataReader reader = null;
      List<NorthwindEmployee> employees = new List<NorthwindEmployee>();

      try
      {
        conn.Open();

        reader = cmd.ExecuteReader(CommandBehavior.SingleRow);

        while (reader.Read())
          employees.Add(GetNorthwindEmployeeFromReader(reader));
      }
      catch (SqlException e)
      {
        // Handle exception.
      }
      finally
      {
        if (reader != null) { reader.Close(); }

        conn.Close();
      }

      return employees;
    }

    //
    // Update the Employee by ID.
    //   This method assumes that ConflictDetection is set to OverwriteValues.

    public int UpdateEmployee(NorthwindEmployee employee)
    {
      if (String.IsNullOrEmpty(employee.FirstName))
        throw new ArgumentException("FirstName cannot be null or an empty string.");
      if (String.IsNullOrEmpty(employee.LastName))
        throw new ArgumentException("LastName cannot be null or an empty string.");

      if (employee.Address    == null) { employee.Address    = String.Empty; }
      if (employee.City       == null) { employee.City       = String.Empty; }
      if (employee.Region     == null) { employee.Region     = String.Empty; }
      if (employee.PostalCode == null) { employee.PostalCode = String.Empty; }

      SqlConnection conn = new SqlConnection(_connectionString);
      SqlCommand    cmd  = new SqlCommand("UPDATE Employees " +
                                          "  SET FirstName=@FirstName, LastName=@LastName, " +
                                          "  Address=@Address, City=@City, Region=@Region, " +
                                          "  PostalCode=@PostalCode " +
                                          "  WHERE EmployeeID=@EmployeeID", conn);  

      cmd.Parameters.Add("@FirstName",  SqlDbType.VarChar, 10).Value = employee.FirstName;
      cmd.Parameters.Add("@LastName",   SqlDbType.VarChar, 20).Value = employee.LastName;
      cmd.Parameters.Add("@Address",    SqlDbType.VarChar, 60).Value = employee.Address;
      cmd.Parameters.Add("@City",       SqlDbType.VarChar, 15).Value = employee.City;
      cmd.Parameters.Add("@Region",     SqlDbType.VarChar, 15).Value = employee.Region;
      cmd.Parameters.Add("@PostalCode", SqlDbType.VarChar, 10).Value = employee.PostalCode;
      cmd.Parameters.Add("@EmployeeID", SqlDbType.Int).Value = employee.EmployeeID;

      int result = 0;

      try
      {
        conn.Open();

        result = cmd.ExecuteNonQuery();
      }
      catch (SqlException e)
      {
        // Handle exception.
      }
      finally
      {
        conn.Close();
      }

      return result;
    }

    // Insert an Employee.

    public int InsertEmployee(NorthwindEmployee employee)
    {
      if (String.IsNullOrEmpty(employee.FirstName))
        throw new ArgumentException("FirstName cannot be null or an empty string.");
      if (String.IsNullOrEmpty(employee.LastName))
        throw new ArgumentException("LastName cannot be null or an empty string.");

      if (employee.Address    == null) { employee.Address    = String.Empty; }
      if (employee.City       == null) { employee.City       = String.Empty; }
      if (employee.Region     == null) { employee.Region     = String.Empty; }
      if (employee.PostalCode == null) { employee.PostalCode = String.Empty; }

      SqlConnection conn = new SqlConnection(_connectionString);
      SqlCommand    cmd  = new SqlCommand("INSERT INTO Employees " +
                                          "  (FirstName, LastName, Address, City, Region, PostalCode) " +
                                          "  Values(@FirstName, @LastName, @Address, @City, @Region, @PostalCode); " +
                                          "SELECT @EmployeeID = SCOPE_IDENTITY()", conn);  

      cmd.Parameters.Add("@FirstName",  SqlDbType.VarChar, 10).Value = employee.FirstName;
      cmd.Parameters.Add("@LastName",   SqlDbType.VarChar, 20).Value = employee.LastName;
      cmd.Parameters.Add("@Address",    SqlDbType.VarChar, 60).Value = employee.Address;
      cmd.Parameters.Add("@City",       SqlDbType.VarChar, 15).Value = employee.City;
      cmd.Parameters.Add("@Region",     SqlDbType.VarChar, 15).Value = employee.Region;
      cmd.Parameters.Add("@PostalCode", SqlDbType.VarChar, 10).Value = employee.PostalCode;
      SqlParameter p = cmd.Parameters.Add("@EmployeeID", SqlDbType.Int);
      p.Direction = ParameterDirection.Output;

      int newEmployeeID = 0;

      try
      {
        conn.Open();

        cmd.ExecuteNonQuery();

        newEmployeeID = (int)p.Value;
      }
      catch (SqlException e)
      {
        // Handle exception.
      }
      finally
      {
        conn.Close();
      }

      return newEmployeeID;
    }

    //
    // Delete the Employee by ID.
    //   This method assumes that ConflictDetection is set to OverwriteValues.

    public int DeleteEmployee(NorthwindEmployee employee)
    {
      string sqlCmd = "DELETE FROM Employees WHERE EmployeeID = @EmployeeID";

      SqlConnection conn = new SqlConnection(_connectionString);
      SqlCommand cmd = new SqlCommand(sqlCmd, conn);
      cmd.Parameters.Add("@EmployeeID", SqlDbType.Int).Value = employee.EmployeeID;

      int result = 0;

      try
      {
        conn.Open();

        result = cmd.ExecuteNonQuery();
      }
      catch (SqlException e)
      {
        // Handle exception.
      }
      finally
      {
        conn.Close();
      }

      return result;
    }

  }
}
<%@ Page language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">

  void EmployeesDetailsView_ItemInserted(Object sender, DetailsViewInsertedEventArgs e)
  {
    EmployeesGridView.DataBind();
  }

  void EmployeesDetailsView_ItemUpdated(Object sender, DetailsViewUpdatedEventArgs e)
  {
    EmployeesGridView.DataBind();
  }

  void EmployeesDetailsView_ItemDeleted(Object sender, DetailsViewDeletedEventArgs e)
  {
    EmployeesGridView.DataBind();
  }

  void EmployeesGridView_OnSelectedIndexChanged(object sender, EventArgs e)
  {
    EmployeeDetailsObjectDataSource.SelectParameters["EmployeeID"].DefaultValue =
      EmployeesGridView.SelectedDataKey.Value.ToString();
    EmployeesDetailsView.DataBind();
  }

  void EmployeeDetailsObjectDataSource_OnInserted(object sender, ObjectDataSourceStatusEventArgs e)
  {
    EmployeeDetailsObjectDataSource.SelectParameters["EmployeeID"].DefaultValue =
      e.ReturnValue.ToString();
    EmployeesDetailsView.DataBind();
  }

  void EmployeeDetailsObjectDataSource_OnUpdated(object sender, ObjectDataSourceStatusEventArgs e)
  {
    if ((int)e.ReturnValue == 0)
      Msg.Text = "Employee was not updated. Please try again.";
  }

  void EmployeeDetailsObjectDataSource_OnDeleted(object sender, ObjectDataSourceStatusEventArgs e)
  {
    if ((int)e.ReturnValue == 0)
      Msg.Text = "Employee was not deleted. Please try again.";
  }

  void Page_Load()
  {
    Msg.Text = "";
  }

</script>
<html  >
  <head runat="server">
    <title>ObjectDataSource Example</title>
</head>
<body>
    <form id="form1" runat="server">

      <h3>ObjectDataSource Example</h3>
      <asp:Label id="Msg" runat="server" ForeColor="Red" />

      <asp:ObjectDataSource
        ID="EmployeesObjectDataSource"
        runat="server"
        TypeName="Samples.AspNet.ObjectDataSource.NorthwindEmployeeData"
        DataObjectTypeName="Samples.AspNet.ObjectDataSource.NorthwindEmployee"
        SortParameterName="SortColumns"
        EnablePaging="true"
        StartRowIndexParameterName="StartRecord"
        MaximumRowsParameterName="MaxRecords"
        SelectMethod="GetAllEmployees" >
      </asp:ObjectDataSource>

      <asp:ObjectDataSource
        ID="EmployeeDetailsObjectDataSource"
        runat="server"
        TypeName="Samples.AspNet.ObjectDataSource.NorthwindEmployeeData"
        DataObjectTypeName="Samples.AspNet.ObjectDataSource.NorthwindEmployee"
        SelectMethod="GetEmployee"
        InsertMethod="InsertEmployee"
        UpdateMethod="UpdateEmployee"
        DeleteMethod="DeleteEmployee"
        OnInserted="EmployeeDetailsObjectDataSource_OnInserted"
        OnUpdated="EmployeeDetailsObjectDataSource_OnUpdated"
        OnDeleted="EmployeeDetailsObjectDataSource_OnDeleted">
        <SelectParameters>
          <asp:Parameter Name="EmployeeID" Type="Int32" />
        </SelectParameters>
      </asp:ObjectDataSource>

      <table cellspacing="10">
        <tr>
          <td valign="top">
            <asp:GridView ID="EmployeesGridView"
              DataSourceID="EmployeesObjectDataSource"
              AutoGenerateColumns="false"
              AllowSorting="true"
              AllowPaging="true"
              PageSize="5"
              DataKeyNames="EmployeeID"
              OnSelectedIndexChanged="EmployeesGridView_OnSelectedIndexChanged"
              RunAt="server">

              <HeaderStyle backcolor="lightblue" forecolor="black"/>

              <Columns>
                <asp:ButtonField Text="Details..."
                                 HeaderText="Show Details"
                                 CommandName="Select"/>  

                <asp:BoundField DataField="EmployeeID" HeaderText="Employee ID" SortExpression="EmployeeID" />
                <asp:BoundField DataField="FirstName"  HeaderText="First Name" SortExpression="FirstName" />
                <asp:BoundField DataField="LastName"   HeaderText="Last Name" SortExpression="LastName, FirstName" />
              </Columns>
            </asp:GridView>
          </td>
          <td valign="top">
            <asp:DetailsView ID="EmployeesDetailsView"
              DataSourceID="EmployeeDetailsObjectDataSource"
              AutoGenerateRows="false"
              EmptyDataText="No records."
              DataKeyNames="EmployeeID"
              Gridlines="Both"
              AutoGenerateInsertButton="true"
              AutoGenerateEditButton="true"
              AutoGenerateDeleteButton="true"
              OnItemInserted="EmployeesDetailsView_ItemInserted"
              OnItemUpdated="EmployeesDetailsView_ItemUpdated"
              OnItemDeleted="EmployeesDetailsView_ItemDeleted"
              RunAt="server">

              <HeaderStyle backcolor="Navy" forecolor="White"/>

              <RowStyle backcolor="White"/>

              <AlternatingRowStyle backcolor="LightGray"/>

              <EditRowStyle backcolor="LightCyan"/>

              <Fields>
                <asp:BoundField DataField="EmployeeID" HeaderText="Employee ID" InsertVisible="False" ReadOnly="true"/>
                <asp:BoundField DataField="FirstName"  HeaderText="First Name"/>
                <asp:BoundField DataField="LastName"   HeaderText="Last Name"/>
                <asp:BoundField DataField="Address"    HeaderText="Address"/>
                <asp:BoundField DataField="City"       HeaderText="City"/>
                <asp:BoundField DataField="Region"     HeaderText="Region"/>
                <asp:BoundField DataField="PostalCode" HeaderText="Postal Code"/>
              </Fields>
            </asp:DetailsView>
          </td>
        </tr>
      </table>
    </form>
  </body>
</html>

该示例需要 SQL Server 上的示例 Northwind 数据库的连接字符串。该连接字符串必须在应用程序的配置文件的 <connectionStrings> 元素中定义。connectionStrings 节可能看起来类似于下面的示例:

复制代码

<configuration>
  <system.web>
    <connectionStrings>
      <add
        name="Northwind"
        connectionString="Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;" />
    </connectionStrings>

  </system.web>
</configuration>