【问题标题】:Retrieve Multiple fields from SQL Server in a web service?从 Web 服务中的 SQL Server 检索多个字段?
【发布时间】:2012-07-12 19:54:58
【问题描述】:

我正在测试如何在 Web 服务中从 SQL Server 检索数据。我在VS 2010中使用SQL Server 2008 R2,asp.net web服务应用项目模板。

假设我有一个有 4 列且没有任何约束的表格(为了便于交谈)。

  • 名字
  • 姓氏
  • 电子邮件
  • 大学

如果用户输入 FirstName 的值,我希望能够获取我的 SQL 表的所有值。稍后我会将 FirstName 更改为 NTID 或一些有意义的列。现在,如果用户输入 FirstName,我的 Web 服务只返回单个值,比如说 LastName。

作为 Web 服务的新手,我正在努力学习尽可能多的知识,非常感谢您花时间和精力帮助我。 TIA。

我在哪里/如何在下面的代码中进行更改

这是我的数据助手类

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

namespace EmployeeRecs
{
    public class DataHelper
    {
        //create new method to get Employee record based on First Name
        public static string GetEmployee(string firstName)
        {
            string LastName = "";

            //Create Connection
            SqlConnection con = new SqlConnection (@"Data Source=myDBServer;Initial Catalog=MyDataBase;Integrated Security=true;");

            //Sql Command
            SqlCommand cmd = new SqlCommand("Select LastName from Employees where FirstName ='" + firstName.ToUpper() + "'", con);

            //Open Connection
            con.Open();

            //To Read From SQL Server
            SqlDataReader dr = cmd.ExecuteReader();

                while (dr.Read())
                {
                    LastName = dr["LastName"].ToString();
                }

            //Close Connection
                dr.Close();
                con.Close();

            return LastName;


        }

    }
}

这是我的 asmx.cs 类

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

namespace EmployeeRecs
{
    /// <summary>
    /// Summary description for Service1
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]
    public class Service1 : System.Web.Services.WebService
    {

               //Create new web method to get Employee last name
        [WebMethod]
        public string GetEmployee(string firstName)
        {
            return DataHelper.GetEmployee(firstName);

        }
    }
}

【问题讨论】:

  • 代码中可能的 sql 注入
  • 最好使用存储过程,而不是内联sql查询
  • @Nemo SqlCommand cmd = new SqlCommand("mystoredprocedurename", con); cmd.CommandType = CommandType.StoredProcedure;
  • SqlCommandBuilder.DeriveParameters(vCmd); vCmd.Parameters["@firstname"].Value = firstName;
  • 谢谢内森。我将尝试使用 Stored Proc 并让您知道它是如何进行的。

标签: c# .net web-services sql-server-2008 asmx


【解决方案1】:

除了 SQL 注入之外,还有几件事:

创建一个 DataContract 并为要返回的数据创建一个模型

[DataContract]
public class Employee
{
    [DataMember]
    public int NTID { get; set; }

    [DataMember]
    public string LastName { get; set; }

    [DataMember]
    public int FirstName { get; set; }
}

用您的 SQL 查询结果填充该模型并从您的服务中返回它

    //create new method to get Employee record based on First Name
    public static List<Employee> GetEmployee(string firstName)
    {
        //Create Connection
        SqlConnection con = new SqlConnection (@"Data Source=myDBServer;Initial Catalog=MyDataBase;Integrated Security=true;");

        //Sql Command
        SqlCommand cmd = new SqlCommand("Select NTID, LastName, FirstName from Employees where FirstName ='" + firstName.ToUpper() + "'", con);

        //Open Connection
        con.Open();

        List<Employee> employees = new List<Employee>();

        //To Read From SQL Server
        SqlDataReader dr = cmd.ExecuteReader();

        while (dr.Read())
        {
            var employee = new Employee { 
                       NTID = dr["NTID"].ToString();
                       LastName = dr["LastName"].ToString();
                       FirstName = dr["FirstName"].ToString();
                    };
            employees.Add(employee);
        }
        //Close Connection
        dr.Close();
        con.Close();
        return employees;
}

公开:

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

namespace EmployeeRecs
{
    /// <summary>
    /// Summary description for Service1
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]
    public class Service1 : System.Web.Services.WebService
    {

               //Create new web method to get Employee last name
        [WebMethod]
        public List<Employee> GetEmployee(string firstName)
        {
            return DataHelper.GetEmployee(firstName);

        }
    }
}

来自 OP 的完整代码供后代使用:

这可能对其他在相同情况下苦苦挣扎的人有用。因此,我发布了解决方案的代码: 在 VS 2010 中创建一个新的 WCF 项目,我使用 .net 版本 3.5 并在 WCF 模板下选择了 WCF 服务库。

这是我在 IService1.cs 下的代码

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.Serialization; 
using System.ServiceModel; 
using System.Text; 

namespace WcfServiceLibrary1 
{ 
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together. 
    [ServiceContract] 
    public interface IService1 
    { 
        [OperationContract] 
        List<Employee> GetEmployee(string firstName); 


        [OperationContract] 
        CompositeType GetDataUsingDataContract(CompositeType composite); 

        // TODO: Add your service operations here 
    } 


    //Custon Data contract 

    [DataContract] 
    public class Employee 
    { 
        [DataMember] 
        public string FirstName { get; set; } 

        [DataMember] 
        public string LastName { get; set; } 

        [DataMember] 
        public string Email { get; set; } 

        [DataMember] 
        public string University { get; set; } 

    }  



    // Use a data contract as illustrated in the sample below to add composite types to service operations 
    [DataContract] 
    public class CompositeType 
    { 
        bool boolValue = true; 
        string stringValue = "Hello "; 

        [DataMember] 
        public bool BoolValue 
        { 
            get { return boolValue; } 
            set { boolValue = value; } 
        } 

        [DataMember] 
        public string StringValue 
        { 
            get { return stringValue; } 
            set { stringValue = value; } 
        } 
    } 
} 

这是我在 Service1.cs 下的代码

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.Serialization; 
using System.ServiceModel; 
using System.Text; 
using System.Data; 
using System.Data.SqlClient; 

namespace WcfServiceLibrary1 
{ 
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in both code and config file together. 
    public class Service1 : IService1 
    { 
        public List<Employee> GetEmployee(string firstName)  

        { 
            //Create Connection  
            SqlConnection con = new SqlConnection(@"Data Source=gsops4;Initial Catalog=MultiTabDataAnalysis;Integrated Security=true;"); 

            //Sql Command  
            SqlCommand cmd = new SqlCommand("Select LastName, FirstName, Email, University from Employees where FirstName ='" + firstName.ToUpper() + "'", con); 

            //Open Connection  
            con.Open(); 

            List<Employee> employees = new List<Employee>(); 

            //To Read From SQL Server  
            SqlDataReader dr = cmd.ExecuteReader();  


            while (dr.Read())  
        {  
            var employee = new Employee {   

                       FirstName = dr["FirstName"].ToString(),  
                       LastName = dr["LastName"].ToString(), 
                       Email = dr["Email"].ToString(), 
                       University = dr["University"].ToString() 



                    };  
            employees.Add(employee);  
        }  
        //Close Connection  
        dr.Close();  
        con.Close();  
        return employees; 

        } 

        public CompositeType GetDataUsingDataContract(CompositeType composite) 
        { 
            if (composite == null) 
            { 
                throw new ArgumentNullException("composite"); 
            } 
            if (composite.BoolValue) 
            { 
                composite.StringValue += "Suffix"; 
            } 
            return composite; 
        } 
    } 
} 

【讨论】:

  • @J Torres-感谢您的及时回复。由于我是网络服务的新手,我如何/从哪里开始#1? TIA。
  • 更新了代码示例。我什至没有尝试构建它,所以如果它有效,我绝对 100% 的功劳,如果它不成功,我将承担 0% 的责任;-)
  • @J Torres- 谢谢。我正在使用 .NET 3.5。我认为[Data contract]是基于4.0的WCF,我不熟悉。因此,创建 [DataContract] 和 [Data member] 给了我错误“找不到类型或命名空间名称‘DataContract’..您是否缺少 using 指令或对程序集的引用...请为我的方案提供任何解决方案?
  • 它在 3.5 中可用。专业提示:在这样的类名上按 CTRL-SPACE,如果有效,它应该自动解析。在这种情况下,您需要确保包含 System.Runtime.Serialization 命名空间。
  • @J Torres- 感谢战利品。你让我今天一整天都感觉很好! :) 在您的帮助下,我更新了我的版本。再次感谢!你真是个鼓舞人心的人! :D
猜你喜欢
  • 2015-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-30
  • 1970-01-01
  • 2014-02-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多