【问题标题】:WebMethod failure网络方法失败
【发布时间】:2016-01-03 16:47:57
【问题描述】:

我在 asmx 页面上有以下 webmethod,但无法连接到我的数据库。任何人都可以阐明我哪里出错了。

[WebMethod]
    public int[] getEmployeeIDs()
    {
        Connection conn = new Connection();
        Recordset rs = new Recordset();
        conn.ConnectionString = "Data Source=MyWebBasedServer;Initial Catalog=MyDatabase;Persist Security Info=False;User ID=MyLogin;Password=MyPassword";
        rs.Open("SELECT ID from MyTable", conn, CursorTypeEnum.adOpenStatic);

        int[] ID = new int[rs.RecordCount];
        int i = 0;
        while (!rs.EOF)
        {
            ID[i++] = rs.Fields["ID"].Value;
            rs.MoveNext();
        }
        rs.Close();
        conn.Close();
        return ID;
    }

我得到的错误信息是

连接不能用于执行此操作。它是 在这种情况下关闭或无效。 (指向“int[] ID = new int[rs.RecordCount];")

谢谢。

【问题讨论】:

  • 看起来您需要在连接上调用 .open()。另外:你连接到什么数据库? Recordset 在我看来就像旧的 DAO 类。我已经很多年没见过这种语法了。
  • 不是rs.Open在使用“conn”连接时打开的连接。我正在连接到 smarterasp.net 托管的数据库,它是一个 mssql 数据库。我已经从 youtube 视频中删除了这个。也许你可以帮助我。我要做的就是从我的数据库中将 MyTable 中的 ID 列表带入 Android 应用程序。有什么建议吗?
  • 连接字符串看起来很可疑,因为您正在使用 ADO 连接类连接字符串应该具有如下格式:"Provider=MySQLProv;server=MyWebBasedServer;uid=MyUserName;pwd=MyPassword;database=MyDatabase"
  • 这是一个 MS Sql 不是 MY Sql。这对连接字符串有影响吗?
  • 为什么不使用 DataReader 或 DataSet 呢?旧的 Recordset 对象是很久以前 ADODB 是当前技术时代码的保留。您应该将连接字符串移动到配置文件中,以便可以从一个位置访问它。

标签: c# sql-server adodb webmethod


【解决方案1】:

下面的代码显示了从 ADO.Net 中的 SELECT 语句中检索结果集的两种常用方法。

有一个名为 ConnectionStrings.com 的网站展示了连接到 SQL Server 的所有各种方式以及许多其他类型的数据库。

如果您是 C# 编程新手,using statement 是在处理实现 IDisposable 的对象时避免资源泄漏的好方法。

WebMethod 返回复杂类型可能会导致错误。该方法的底层 XML 序列化程序可能不知道如何处理某些类型。在这种情况下,XmlIncludeAttribute 可用于提供显式类型信息。这是一个 MSDN thread 讨论如何去做。

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web.Services;

namespace ConsoleApplication19
{
  public class Program
  {
    public static void Main(String[] args)
    {
      var connectionString = "Data Source=MyWebBasedServer;Initial Catalog=MyDatabase;Persist Security Info=False;User ID=MyLogin;Password=MyPassword;";
      var a = GetEmployeeIDs_Version1(connectionString);
      var b = GetEmployeeIDs_Version2(connectionString);
    }

    /* Version 1

       Use a "while" loop to fill a WebData list and return it as an array. */

    [WebMethod]
    private static WebData[] GetEmployeeIDs_Version1(String connectionString)
    {
      using (var connection = new SqlConnection(connectionString))
      {
        connection.Open();

        var commandText = "SELECT ID, SurName from MyTable";

        using (var command = new SqlCommand() { Connection = connection, CommandType = CommandType.Text, CommandText = commandText })
        {
          using (var reader = command.ExecuteReader(CommandBehavior.CloseConnection))
          {
            var result = new List<WebData>();

            while (reader.Read())
              result.Add(new WebData() { ID = Convert.ToInt32(reader["ID"]), Surname = reader["Surname"].ToString() });

            return result.ToArray();
          }
        }
      }
    }

    /* Version 2

       Fill a DataSet with the result set.

       Because there's only one SELECT statement, ADO.Net will
       populate a DataTable with that result set and put the
       DataTable in the dataset's Tables collection.

       Use LINQ to convert that table into a WebData array. */

    [WebMethod]
    private static WebData[] GetEmployeeIDs_Version2(String connectionString)
    {
      using (var connection = new SqlConnection(connectionString))
      {
        connection.Open();

        var commandText = "SELECT ID, SurName from MyTable";

        using (var command = new SqlCommand() { Connection = connection, CommandType = CommandType.Text, CommandText = commandText })
        {
          using (var adapter = new SqlDataAdapter())
          {
            var dataSet = new DataSet();
            adapter.SelectCommand = command;
            adapter.Fill(dataSet);

            return
              dataSet
              // There should only be one table in the dataSet's Table's collection.
              .Tables[0]
              .Rows
              // DataTable isn't LINQ-aware.  An explicit cast is needed
              // to allow the use of LINQ methods on the DataTable.Rows collection.
              .Cast<DataRow>()
              // The rows in a DataTable filled by an SqlDataAdapter
              // aren't strongly typed.  All of a row's columns are
              // just plain old System.Object.  Explicit casts are necessary.
              .Select(row => new WebData() { ID = Convert.ToInt32(row["ID"]), Surname = row["Surname"].ToString() })
              // Use LINQ to convert the IEnumerable<WebData> returned by
              // the .Select() method to an WebData[].
              .ToArray();
          }
        }
      }
    }
  }

  public class WebData
  {
    public Int32 ID { get; set; }
    public String Surname { get; set; }
  }
}

【讨论】:

  • 感谢您的建议。当我将这些数据带入 Android 应用程序时,有人告诉我应该使用 webmethod,因为这样可以保持连接字符串的私密性。我已经把你的建议都放进去了,而且都做了我需要的,我能不能再麻烦你,问我如何将多列带入数组,例如身份证和姓氏
  • 克里斯,我更新了示例代码,并添加了几个关于 XmlIncludeAttribute 的链接,如果 [WebMethod] 在序列化像 WebData 类这样的复合类型时遇到问题。
猜你喜欢
  • 1970-01-01
  • 2011-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-09
  • 1970-01-01
  • 1970-01-01
  • 2018-06-21
相关资源
最近更新 更多