WCF - 接收到 http://xxxxx/Service/ 的 HTTP 响应时出错

Posted

技术标签:

【中文标题】WCF - 接收到 http://xxxxx/Service/ 的 HTTP 响应时出错【英文标题】:WCF - An error occurred while receiving the HTTP response to http://xxxxx/Service/ 【发布时间】:2013-03-27 03:30:12 【问题描述】:

我正在我的 WCF 服务中进行此调用:

public User GetStudentRecord(string userName)
    
        try
        
            return new DashboardFacade().GetStudentRecord(userName);
        
        catch (Exception ex)
        
            ServiceFault fault = new ServiceFault();
            fault.Operation = "GetStudentRecord";
            fault.Reason = "Who knows...";
            fault.Message = ex.Message;
            throw new FaultException<ServiceFault>(fault, fault.Message, new FaultCode(fault.Reason), fault.Operation);
        
    

DashboardFacade().GetStudentRecord(..) 定义如下:

public User GetStudentRecord(string userName)

    User user = ctx.Users.Where(x => x.ADUserName == userName).SingleOrDefault();
    return user;

ctx 是我的 DbContext。我首先使用实体​​框架代码。 User 对象如下所示:

public class User

    public User()
    
        //UserDetails = new UserDetail();
    
    [Key]
    public Guid MasterKey  get; set; 
    public string FirstName  get; set; 
    public string LastName  get; set; 
    public string Email  get; set; 
    public string ADUserName  get; set; 
    public string UserType  get; set; 
    public virtual UserDetail UserDetails  get; set; 
    public Nullable<DateTime> LastModifiedDate  get; set; 

最后,您可能需要查看 WCF 应用程序上的 web.config:

<?xml version="1.0"?>
    <configuration>
      <connectionStrings>
        <add name="NotMyDBContextDB" connectionString="[omitted]" providerName="System.Data.SqlClient"/>
        <add name="ApplicationContext" connectionString="Data Source=.;Initial Catalog=MyApp;Integrated Security=True;Pooling=False" providerName="System.Data.SqlClient"/>
      </connectionStrings>
   <system.web>
     <compilation debug="true" targetFramework="4.0"/>
   </system.web>
   <system.serviceModel>
     <behaviors>
       <serviceBehaviors>
          <behavior>
             <serviceMetadata httpGetEnabled="true"/>
             <serviceDebug includeExceptionDetailInFaults="true"/>
          </behavior>
        </serviceBehaviors>
      </behaviors>
      <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
  </system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>

谁能指出我哪里出错了?

这是我得到的确切错误:

An error occurred while receiving the HTTP response to http://localhost:5843/MyService.svc. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.

Inner Exception:
The underlying connection was closed: An unexpected error occurred on a receive.

Inner Exception:
Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.

Inner Exception:
An existing connection was forcibly closed by the remote host

【问题讨论】:

错误在哪里抛出?在调试器中运行您的服务。 刚刚添加了我收到的错误和内部异常消息。我可以在调试器中运行它,它可以让我逐步完成上面的所有代码。一旦我在实际服务中离开 GetStudentRecord() 调用,几秒钟后我就会收到错误。 【参考方案1】:

经过大量的咒骂和思考外面的天气多么好,找到了根本原因。我从 User 对象内的 UserDetails 对象中删除了 virtual 关键字。

现在可以了!

至于这导致问题的原因,我的假设是序列化或 DbContext 问题,但我将不得不更多地研究它,不确定。

我现在要出去了。

因此,作为参考,如果您在这里结束并且不知道发生了什么,那么您应该查看的所有其他事项(大小、超时等):

Check to see if your object has virtual keyword on it.

【讨论】:

我花了一整天的时间才找到这个答案。谢谢!【参考方案2】:

我遇到了这个问题,就我而言,问题是 WCF 服务返回了一个类,该类的属性只有一个 getter 而没有 setter。我试图阻止接收者修改该属性。要解决此问题,请参阅此...

WCF Services and Object Constructors

【讨论】:

这救了我!实际错误是由引发空引用异常的只读属性引起的......但这一切都隐藏在深处。 WCF 疯狂! 刚来这里发这个。真希望我早点看到这个。 DataContractSerializer 要求属性有一个 setter(尽管它可以接受该 setter 上的任何访问修饰符),即使只进行序列化而不是反序列化,这对我来说毫无意义。这显然会在响应时通过强行关闭连接来做出反应,从而给您这个无用的错误消息。就我而言,我的属性是根据其他属性计算得出的,我只想将这些计算值返回给客户端。 顺便说一句:Visual Studio(我猜是 svcutil)仍然会为属性创建一个 getter 和一个 setter,不管你是否声明了一个 setter。需要控制客户端如何使用从您的服务返回的数据可能表明存在更大的设计缺陷。即使您可以阻止设置它,客户端也可以将所有值复制到它自己的本地类型中并在那里修改它想要的任何内容。您的服务可以控制它接受的内容,因此如果您收到不应该设置的值,您可以简单地忽略它,返回验证错误,或者一开始就不接收它。【参考方案3】:

我有同样的错误。

在我的情况下,我有一个表,其中包含一个名为 OEM 的 int 列。 在模型层中,我有一个类(DTO),该列由枚举表示。 表中有一行 OEM 列中的值无效。 当我尝试使用 LINQ 获取所有数据时,出现了 VisualStudio 未捕获的错误。 当 WCF 尝试检索消息时引发该错误。

【讨论】:

对我来说,我的枚举没有明确定义 0 的值,我通过 WCF 传递了一个对象,该对象具有此枚举类型的属性,但未分配该属性(默认为0)。【参考方案4】:

我有同样的例外,但上面的答案都没有给我一个解决方案。 我通过在 web.config 中定义跟踪找出了错误:

<system.diagnostics>
<sources>
  <source propagateActivity="true" name="System.ServiceModel" switchValue="Information, ActivityTracing">
    <listeners>
      <add type="System.Diagnostics.DefaultTraceListener" name="Default">
        <filter type="" />
      </add>
      <add initializeData="C:/temp/tracelog.svclog" type="System.Diagnostics.XmlWriterTraceListener" name="traceListener">
        <filter type="" />
      </add>
    </listeners>
  </source>
</sources>
</system.diagnostics>

我在本地运行网站,触发了一些失败的调用,然后打开了选择失败条目的跟踪日志,在该条目中我看到了这个异常:

无法在 LINQ to Entities 查询中构造实体或复杂类型“Person”。

在查询之外构造人解决了这个问题,而不是:

 var persons = (from p in db.Persons
                  select new Person
                  
                      Id = p.Id,
                      Name = p.Name,
                      LastName = p.LastName,
                      Email = p.Email
                  
              ).AsEnumerable();

  return persons;

我不得不这样做:

var persons = (from p in db.Persons
                  select new 
                  
                      Id = p.Id,
                      Name = p.Name,
                      LastName = p.LastName,
                      Email = p.Email
                  
              ).AsEnumerable()
                //construct the complex type outside of DB  (to prevent the exception that model cannot be constructed in linq to entities)
                .Select(item =>

                    new Person
                    
                        Id = item.Id,
                        Name = item.Name,
                        LastName = item.LastName,
                        Email = item.Email
                    ).ToList(); 

            return persons;

如果异常消息更全面,我可以节省很多时间,从本主题中列出的所有不同原因来看,我想人们会同意我的观点。

无论如何,这就是我解决问题的方法,希望这对其他人有帮助

【讨论】:

【参考方案5】:

这些方法都不适合我。我所做的是在从 WCF 测试客户端运行时调试服务,我能够找到我的问题。这与服务库缺少 app.config 中的连接字符串有关。

如果有人尝试了所有其他方法但仍然无法找到问题,请发布。

【讨论】:

【参考方案6】:

也许您需要禁用延迟加载和代理创建,如下所示:

  db.LazyLoadingEnabled = false;
  db.ProxyCreationEnabled = false;

这样做你的 wcf 服务应该可以工作。

【讨论】:

【参考方案7】:

Webservice 的情况更糟。

我返回了一个带有 Enum 属性的简单 POCO 对象。

属性中返回的数值不在枚举值的集合中,因此,我得到了误导性错误。

这不是我第一次遇到与 .NET 中的枚举值相关的问题 ....

因此,简而言之,请确保您在 WebService 中的响应不会这样做:

enum exampleEnum
    
        A = 1
    

    class webService
    
        public object foo() // Suppose WebService method
        
            // Bad, make sure the Enum value is in the list defined!
            return new  age = 12, A = (exampleEnum)2 ;
        
    

【讨论】:

以上是关于WCF - 接收到 http://xxxxx/Service/ 的 HTTP 响应时出错的主要内容,如果未能解决你的问题,请参考以下文章

WCF - 接收到 http://xxxxx/Service/ 的 HTTP 响应时出错

从 ajax 调用传递到 wcf 的参数被接收为 null

在 WCF 中提供故障方法接收到没有详细信息的 FaultException

使用具有复杂对象的 KSoap2 调用 WCF 服务。 WCF 接收空值

WCF - 检查正在发送/接收的消息?

WCF 从 XML 接收空模型