抓住“;& # 39; System.ServiceModel.EndpointNotFoundException& #

本文关键字:ServiceModel EndpointNotFoundException System 抓住 | 更新日期: 2023-09-27 18:12:01

我正在用c#创建一个使用SOAP web服务的应用程序。我使用svcutil工具为web服务WSDL生成了一个代理类。

我将代理类添加到我的代码中,我使用它来调用web服务并异步获取结果。

当客户端有互联网接入时,一切都很好。但是,如果我在应用程序没有Internet访问时运行尝试访问,它会崩溃并引发以下异常:

An exception of type 'System.ServiceModel.EndpointNotFoundException' occurred in
System.ServiceModel.Internals.dll but was not handled in user code

我试图捕捉这个异常,以防止应用程序崩溃,并为用户提供一个更友好的错误信息,然而,因为我正在做异步web调用,简单地围绕web服务调用的try - catch没有帮助。

根据异常细节,它发生在自动生成的代理文件中定义的End_FunctionName函数中。

关于如何优雅地处理这个异常有什么建议吗?

抓住“;& # 39; System.ServiceModel.EndpointNotFoundException& #

很难确切地知道发生了什么;但是,我将假设您有一个像

这样的web服务
[ServiceContract]
public interface IMyService
{
    [OperationContract]
    String Hello(String Name);
    [OperationContract]
    Person GetPerson();
}

您可能有这样的代理:

public class MyPipeClient : IMyService, IDisposable
{
    ChannelFactory<IMyService> myServiceFactory;
    public MyPipeClient()
    {
        //This is likely where your culprit will be.
        myServiceFactory = new ChannelFactory<IMyService>(new NetNamedPipeBinding(), new EndpointAddress(Constants.myPipeService + @"/" + Constants.myPipeServiceName));
    }
    public String Hello(String Name)
    {
        //But this is where you will get the exception
        return myServiceFactory.CreateChannel().Hello(Name);
    }
    public Person GetPerson()
    {
        return myServiceFactory.CreateChannel().GetPerson();
    }
    public void Dispose()
    {
        ((IDisposable)myServiceFactory).Dispose();
    }
}

如果你有一个错误的连接,你会得到它不是当你试图连接到通道工厂,而是当你实际尝试调用一个函数。

为了解决这个问题,你可以在每个函数调用周围放置一个try catch,并手动处理异步调用。

相反,您可以拥有像init()这样的函数,每次实例化连接时都同步调用它。这样你就知道,如果那个电话接通了,你就有了一个连接。

如果你有随时掉线的危险,我建议你选择前者。

无论如何,这里有一个如何修复它的例子:

public class MyPipeClient : IMyService, IDisposable
{
    ChannelFactory<IMyService> myServiceFactory;
    public MyPipeClient()
    {
        myServiceFactory = new ChannelFactory<IMyService>(new NetNamedPipeBinding(), new EndpointAddress(Constants.myPipeService + @"/" + Constants.myPipeServiceName + 2) );
    }
    public String Hello(String Name)
    {
        try 
        {
            return Channel.Hello(Name);
        }
        catch
        {
            return String.Empty;
        }
    }
    public Person GetPerson()
    {
        try 
        { 
            return Channel.GetPerson();
        }
        catch
        {
            return null;
        }
    }
    public Task<Person> GetPersonAsync()
    {
        return new Task<Person>(()=> GetPerson());
    }
    public Task<String> HelloAsync(String Name)
    {
        return new Task<String>(()=> Hello(Name));
    }
    public void Dispose()
    {
        myServiceFactory.Close();
    }
    public IMyService Channel
    {
        get
        {
            return myServiceFactory.CreateChannel();
        }
    }
}

我上传了我写的源代码,这样你就可以下载完整的源代码。你可以在这里下载:https://github.com/Aelphaeis/MyWcfPipeExample

PS:此存储库抛出您得到的异常。为了删除它,只需转到MyPipeClient并删除构造函数中的+ 2。

如果您使用的是双工,请考虑使用这个存储库:https://github.com/Aelphaeis/MyWcfDuplexPipeExample