上篇博客介绍了webservice的基础认识和一个简单的Hello World例子,实现过程几乎没有遇到什么问题,但是不运用到实际应用中就真不知道能有这么多问题,下面通过web service来改造三层结构。
一. One Demo
实现功能:
实现查询Northwind数据库Employees表数据。(Northwind,SQLServer自带的数据库,msdn上基本用的都是这个数据库,我们做Demo用这个就能让代码不做修改的在本地运行)
效果如下:
1.首先还是先写web service
只贴主要代码了,具体的web service创建请看上篇博客:Web Service(一)
public class WebService1 : System.Web.Services.WebService
{
public const string connection = @"server=192.168.24.44;database=Northwind;uid=sa;pwd=123456;Trusted_Connection=SSPI";
[WebMethod]
public string HelloWorld()
{
return "Hello World!";
}
/// <summary>
/// 获取Employees表数据(无参数)
/// </summary>
/// <param name="sqlText">SQL查询语句</param>
/// <returns>DataSet</returns>
[WebMethod(Description = "Returns Northwind Employees", EnableSession = false)]
public DataSet GetEmployees(string sqlText)
{
SqlDataAdapter adapter = new SqlDataAdapter(sqlText, connection);
DataSet ds = new DataSet();
adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
adapter.Fill(ds, "Employees"); //填充数据ds
return ds;
}
}
2. 三层结构(主要是DAL层的变化)
(1)Web后台绑定
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
namespace Web
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
BLL.GridBLL gridBLL = new BLL.GridBLL();
DataTable dt = new DataTable();
dt = gridBLL.Grid();
GridView1.DataSource = dt;
GridView1.DataBind();
}
}
}
(2)BLL:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
namespace BLL
{
public class GridBLL
{
DAL.GridDAL gridDAL = new DAL.GridDAL();
public DataTable Grid()
{
return gridDAL.Grid();
}
}
}
(3)DAL:
using DAL.ServiceReference1; //添加web service的服务引用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
namespace DAL
{
public class GridDAL
{
//实例化添加web service引用后的WebService1SoapClient 类
public static WebService1SoapClient client = new WebService1SoapClient();
/// <summary>
/// 查询数据
/// </summary>
/// <returns>DataTable</returns>
public DataTable Grid()
{
DataSet ds = new DataSet();
StringBuilder strSql = new StringBuilder();
strSql.Append("select * from Employees ");
ds = client.GetCustomers(strSql.ToString());
return ds.Tables[0];
}
}
二. More Questions
代码写完啦,满心欢喜的去F5,结果意料之中很多错,有错了才好!
1.配置文件
在 ServiceModel客户端配置部分中,找不到引用协定“ServiceReference1.WebService1Soap”的默认终结点元素。这可能是因为未找到应用程序的配置文件,或者是因为客户端元素中找不到与此协定匹配的终结点元素。
错误提示很明显,是客户端配置文件的问题,一番查询,看解决办法:
需要把DAL层引用web service后生成的app.config(包含了引用的web service地址和配置等信息),复制到Web下的Web.config中
将app.config(如下)复制到Web.config的<configuration>标记下
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="WebService1Soap" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8091/WebService1.asmx" binding="basicHttpBinding"
bindingConfiguration="WebService1Soap" contract="ServiceReference1.WebService1Soap"
name="WebService1Soap" />
</client>
</system.serviceModel>
满心欢喜再去F5,这回可以了吧!
OMG!
2.MaxReceivedMessageSize
已超过传入消息(65536)的最大消息大小配额。若要增加配额,请使用相应绑定元素上的MaxReceivedMessageSize 属性。
MaxReceivedMessageSize是什么,msdn一下,MaxReceivedMessageSize
获取或设置配置了此绑定的通道上可以接收的消息的最大大小。MaxReceivedMessageSize 限制整个消息(标头和正文)的大小
类型:System.Int64,绑定可处理的最大消息大小(以字节为单位)。默认值为 65,536 字节。所以我们需要手动配置MaxReceivedMessageSize的大小。
回到Web.config,添加MaxReceivedMessageSize设置,完整代码如下:
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="WebService1Soap" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8091/WebService1.asmx" binding="basicHttpBinding"
bindingConfiguration="WebService1Soap" contract="ServiceReference1.WebService1Soap"
name="WebService1Soap" />
</client>
</system.serviceModel>
<system.webServer>
<validation validateIntegratedModeConfiguration ="false"/>
</system.webServer>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
</configuration>
Web.config设置完成,满心欢喜再去F5!
3. 服务器请求
System.Web.Services.Protocols.SoapException:服务器无法处理请求。 --->System.Data.SqlClient.SqlException: 登录失败。该登录名来自不受信任的域,不能与 Windows身份验证一起使用。
首先需要说明的是,web service中使用的数据库连接是服务器的地址,而非本机的。
该登录名来自不受信任的域,不能与 Windows身份验证一起使用。问题出在web service上,web service访问数据库时,web service所在主机被列为不受信用的域,且不能与Windows身份验证一起使用,那我们就把访问设置成非Windows身份验证。
添加Integrated Security=false;
当 Integrated Security 为 false 时,将在连接中指定用户 ID 和密码;当为 true 时,将使用当前的 Windows 帐户凭据进行身份验证。
F5继续,大功告成!
相当简单的三层结构,只是添加了Web Service实现,从实现中看,Web Service的作用相当于SqlHelper类,去实现程序间的访问。
三. 总结
遇到问题,解决问题,这个过程是一个很享受的过程,曾几何时,总是提心吊胆的怕遇到问题,躲着问题走,又从何时起,提高班三年的学习,知道问题都不是问题,问题越多,说明需要学习的越多,需要自己改变的也越多,敢于面对问题,解决问题,是你成长的机会。