【问题标题】:Deploy WCF service on Azure, timeout when try to access database在 Azure 上部署 WCF 服务,尝试访问数据库时超时
【发布时间】:2012-12-28 11:12:50
【问题描述】:

我有第一个项目“MyProject.Core”,我有 EDMX:

回购类:

class MyProjectRepo : IMyProjects
{
    public int NumberOfUser()
    {
        return new context().User.Count();
    }

    public string HelloWorld()
    {
        return "Hello World!";
    }
}

界面:

public interface IMyProjects
{
    int NumberOfUser();
    string HelloWorld();
}

工厂:

public static class MyProjectFactory
{
    private static IMyProjects _returnedObject;

    public static IMyProjects GetObject()
    {
        lock (typeof(MyProjectFactory))
        {
            _returnedObject = new MyProjectRepo();
        }
        return _returnedObject;
    }
}

一个测试项目“MyProject.Core.Tests”(测试通过):

[Test]
public void NumberOfUser_Test()
{
    var number = MyProjectFactory.GetObject().NumberOfUser();
    Assert.AreEqual(1, number);
}

[Test]
public void HelloWorld_Test()
{
    var hello = MyProjectFactory.GetObject().HelloWorld();
    Assert.AreEqual("Hello World!", hello);
}

我创建了一个“云”项目和一个 WCFServiceWebRole。

在 WCFServiceWebRole 中,我有这个:

public class Service1 : IService1
{
    public int NumberOfUser()
    {
        return MyProjectFactory.GetObject().NumberOfUser();
    }

    public string Hello()
    {
        return MyProjectFactory.GetObject().HelloWorld(); 
    }
}

[ServiceContract]
public interface IService1
{
    [OperationContract]
    int NumberOfUser(string login, string password);

    [OperationContract]
    string Hello();
}

一个测试 WCF 的项目,方法“Hello”返回正确的值。 这是我遇到问题的另一种方法。在 app.config 中,我有这个 :

<bindings>
    <basicHttpBinding>
        <binding name="BasicHttpBinding_IService1" />
    </basicHttpBinding>
</bindings>

<client>
    <endpoint address="http://myproject.azurewebsites.net/Service1.svc"
        binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1"
        contract="myprojectServiceAzure.IService1" name="BasicHttpBinding_IService1" />
</client>

错误:

System.TimeoutException : 请求通道在 00:00:59.7138476 之后等待回复时超时。增加通过的超时值 调用 Request 或增加 SendTimeout 值 捆绑。 分配给此操作的时间可能是较长超时的一部分。 ----> System.TimeoutException:对“http://MyProject.azurewebsites.net/Service1.svc”的 HTTP 请求已超过 分配的超时时间为 00:00:59.9270000。分配给这个的时间 操作可能是一个 更长的超时时间。 ----> System.Net.WebException : 操作已超时 MyProject.Azure.Tests\Service References\MyProjectServiceAzure\Reference.cs(487, 0) : MyProject.Azure.Tests.PointageServiceAzure.Service1Client.MyMethod(字符串 登录名,字符串密码) MyProject.Azure.Tests\AzureTests.cs(18, 0) : MyProject.Azure.Tests.AzureTests.Test()

【问题讨论】:

    标签: c# .net wcf unit-testing azure


    【解决方案1】:

    您是否检查过 Azure 防火墙规则?您需要“允许”WCF 服务访问 SQL Azure 数据库。从内存中,您需要选中一个复选框,它允许托管应用程序访问数据库,因为默认情况下不选中。

    【讨论】:

    • 防火墙规则里面有home的ip,是的WINDOWS AZURE SERVICES。
    【解决方案2】:

    您是否尝试在 web.config 中设置 MaxReceivedMessageSize 等?

    Here

    【讨论】:

    • 刚刚试了,没有变化。请参阅更新 2(尝试发布更多信息)
    【解决方案3】:

    这不是您问题的答案。这是您面临的真正问题的解决方案:)

    您实际上不是在编写单元测试,而是在编写集成测试。

    你必须问问自己你真正想测试什么。据我所知,您正在测试与 WCF 服务的连接,而这不是单元测试的目的。

    我的建议是关注点分离。 WCF 是唯一允许远程通信的代理。因此,它不是核心业务逻辑的一部分。你的业务逻辑应该尽可能的纯粹。没有可能难以摆脱的不必要的依赖。如果您必须用信鸽 ( ;) ) 替换 WCF,而逻辑不知道 WCF,您根本不必接触逻辑代码。

    这是我的想法的一个例子:

    interface IService //pure business logic, no knowledge of WCF
    {
        double Add(double a, double b);
    }
    
    class NonWcfService : IService //pure business logic
    {
        public double Add(double a, double b)
        {
            return a + b;
        }
    }
    
    [ServiceContract]
    interface IServiceContract //wcf-bound (because of the attributes)
    {
        [OperationContract]
        double Add(double a, double b);
    }
    
    class WcfService : IServiceContract //wcf-bound delegates calls to pure business logic
    {
        IService sourceService;
    
        public WcfService(IService sourceService)
        {
            this.sourceService = sourceService; 
        }
    
        public double Add(double a, double b)
        {
            return sourceService.Add(a,b);
        }
    }
    

    现在您可以为 NonWcfService 编写单元测试,而无需连接到任何服务。这意味着您的单元测试会运行得更快。

    您还可以为 WcfService 编写单元测试,以检查此包装器是否作为代理运行良好。

    【讨论】:

    • 我知道,这适用于只返回一个字符串的方法。问题是当一个方法需要访问数据库时。
    • 哪种方法?请更准确一点。
    • 随便...你的业务逻辑不能知道确切的数据源! BL 应该对提供者进行操作(接口要清晰)。您的“生产”实现读取数据库记录,而在单元测试中您模拟这样的接口。
    • 1.你需要这个工厂做什么?它没有任何价值。此外,锁定 this/GetType() 是完全不安全的,应该被禁止。 2. 在你的 MyProjectRepo 单元测试中你不应该使用这个工厂。而是使用构造函数创建 repo。将工厂放在那里会导致测试实际上测试两件事:回购本身和工厂。 3.使用提供的代码,假设 Context 使用 DB,您仍然无法摆脱 DB 连接。 4. 避免工厂的静态类。它们和单例都是纯粹的邪恶——在你的单元测试中,你不能切换依赖关系——例如摆脱 DB。
    猜你喜欢
    • 2022-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多