任何人都可以建议从ASP.net页面使用WCF服务的良好模式吗?似乎如果没有正确控制Client(:ServiceModel.ClientBase)的生命周期,我们会抛出PipeException。它目前作为Page类的一个字段存在,但是在每个页面请求时都要重新实例化而不进行清理(.Close方法)。
我怀疑这个问题可以改写为“管理ASP.net页面中的有限资源”,并且可能与ASP.net页面的生命周期更相关。我是ASP.net的新手,所以我对此的理解有点薄。
TIA。
编辑:一些代码(没有多少代码!)
public partial class Default : Page
{
//The WCF client... obviously, instantiating it here is bad,
//but where to instantiate, and where to close?
private readonly SearchClient client = new SearchClient();
protected void Page_Load(object sender, EventArgs e)
{
第二编辑:以下会更好吗?
public partial class Default : Page
{
private SearchClient client;
protected void Page_Unload(object sender, EventArgs e)
{
try
{
client.Close();
}
catch
{
//gobbled
}
}
protected void Page_Load(object sender, EventArgs e)
{
client= new SearchClient();
//.....
答案 0 :(得分:1)
我同意迈克尔的观点,如果可能的话,将其抽象出另一层。
但是,如果你打算从你的aspx页面调用它,我会创建一个单独的方法来调用它,返回它的结果和清理。将所有内容放在一个地方,保持代码清洁。只记得在finally块中处置,并且必须将wcf代理转换为IDisposable才能进行处理。
例如:
void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
RemoteCall();
}
}
void RemoteCall()
{
var client = new SearchClient();
try
{
var results = client.Search(params);
clients.Close();
}
catch(CommunicationException cex)
{
//handle
}
catch(Exception ex)
{
//handle
}
finally
{
((IDisposable)client).Dispose();
}
}
答案 1 :(得分:0)
通常,您不应直接从表示层调用外部服务。它会产生两个问题:第一,性能(池化,缩放等),其次,如果需要进行身份验证,则会产生安全风险(DMZ中的身份验证代码不好。
即使您没有应用程序层,也应考虑将服务调用重构为表示层中的私有服务。这将允许您将服务的生命周期与页面的生命周期分离(如您所述,这是有问题的。)