【问题标题】:WCF throwing NetDispatcherFaultException when trying to deserialize posted data尝试反序列化发布的数据时,WCF 抛出 NetDispatcherFaultException
【发布时间】:2015-01-22 13:14:44
【问题描述】:

我正在处理一个必须调用我创建的简单 WCF 的面试项目。我以前从未使用过这些,所以我有点迷茫。昨晚我花了几个小时试图让它工作,现在把它缩小到一个序列化错误。

这是我正在使用的 WCF。

[ServiceContract(Namespace = "HighEnergy.Web")]
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class CustomerService {
    private const string ACCT   = "9999999999";
    private const string PHONE  = "111-111-1111";

    [OperationContract]
    [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
    public bool Validate(OutageModel model) {
        if (!string.IsNullOrWhiteSpace(model.AccountNumber) && !string.IsNullOrWhiteSpace(model.PhoneNumber)) {
            if (string.IsNullOrWhiteSpace(model.AccountNumber)) {
                model.AccountNumber = ACCT;
            }
            if (string.IsNullOrWhiteSpace(model.PhoneNumber)) {
                model.PhoneNumber = PHONE;
            }

            return model.AccountNumber == ACCT &&
                   model.PhoneNumber == PHONE;
        }

        return false;
    }
}

这是我用于该呼叫的OutageModel

[Serializable]
public class OutageModel {
    [RegularExpression(Utilities.AccountNumberRegex, ErrorMessage = "Your account number is 10 digits.")]
    public string AccountNumber { get; set; }
    [Phone(ErrorMessage = "Your phone number must be in 123-456-7890 format.")]
    public string PhoneNumber   { get; set; }

    public OutageModel() {
        this.Clear();
    }

    private void Clear() {
        this.AccountNumber  = string.Empty;
        this.PhoneNumber    = string.Empty;
    }
}

这是我尝试从我的 MVC 页面调用它的方式。我没有将它连接到任何按钮事件或任何东西,只是坐在页面底部以在解析时运行。

$.ajax({
        url: '/CustomerService.svc/Validate',
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        data: {
            "AccountNumber": "9999999999",
            "PhoneNumber": "111-111-1111"
        }
    }
    ).done(function (data) {
        alert(data);
    }).error(function (xhr, status, error) {
        console.log(xhr.responseText);
        //alert("Error\n-----\n" + xhr.status + '\n' + xhr.responseText);
    });

web.config 的相关部分:

<system.serviceModel>
  <diagnostics>
    <messageLogging
        logEntireMessage = "true"
        logMalformedMessages ="false"
        logMessagesAtServiceLevel ="true"
        logMessagesAtTransportLevel = "false"
        maxMessagesToLog = "3000"
        maxSizeOfMessageToLog ="2000" />
  </diagnostics>
  <bindings>
    <webHttpBinding>
      <binding name="WebHttpEndpointBinding">
        <security mode="TransportCredentialOnly">
          <transport clientCredentialType="Windows"/>
        </security>
      </binding>
    </webHttpBinding>
  </bindings>
  <behaviors>
    <endpointBehaviors>
      <behavior name="HighEnergy.Web.CustomerServiceAspNetAjaxBehavior">
        <enableWebScript />
        <dataContractSerializer maxItemsInObjectGraph="2147483647" />
      </behavior>
    </endpointBehaviors>
    <serviceBehaviors>
      <behavior name="debug">
        <serviceDebug includeExceptionDetailInFaults="true" />
      </behavior>
      <behavior name="AjaxServiceBehavior">
        <serviceMetadata httpGetEnabled="true" />
        <serviceThrottling
                     maxConcurrentCalls="4096"
                     maxConcurrentSessions="4096"
                     maxConcurrentInstances="4096"
                   />
      </behavior>
    </serviceBehaviors>
  </behaviors>
  <standardEndpoints>
    <webHttpEndpoint>
      <standardEndpoint name="" contentTypeMapper="HighEnergy.Web.WebContentTypeMapper.JsonContentTypeMapper, JsonContentTypeMapper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </webHttpEndpoint>
  </standardEndpoints>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
    multipleSiteBindingsEnabled="false" />
  <services>
    <service name="HighEnergy.Web.CustomerService">
      <endpoint address="http://localhost:44208/CustomerService.svc" behaviorConfiguration="HighEnergy.Web.CustomerServiceAspNetAjaxBehavior"
        binding="webHttpBinding" contract="HighEnergy.Web.CustomerService" />
    </service>
  </services>
</system.serviceModel>

以下是在该 AJAX 调用中返回给客户端的异常详细信息的基础知识(为简洁起见进行了编辑):

"Type" : "System.ServiceModel.Dispatcher.NetDispatcherFaultException"},
"ExceptionType" : "System.ServiceModel.Dispatcher.NetDispatcherFaultException",
"Message" : "The formatter threw an exception while trying to deserialize the message: Error in deserializing body of request message for operation 'Validate'. Encountered unexpected character 'A'."

如果需要,我可以提供更多这些细节。我已经检查了severalotherquestions,但大约 6 小时后无法让它工作。我想这可能是我想念的非常简单的东西,但我们将不胜感激。

【问题讨论】:

  • 我在 Windows 8 上的 Visual Studio 2013 Ultimate 中运行它。它只是通过 localhost 运行。我确实在 Windows Features 下打开了 .NET 3.5 和 4.5 下的 WCF 项。
  • 如果您定义了 webhttpendpoint,那么为什么我们需要标准端点?我并不是说它会解决您的问题,但让我们尽量减少问题以缩小问题范围。
  • 一个比另一个更可取吗?
  • 视具体情况而定。标准端点定义具有默认值或一个或多个端点属性不变的端点,而通过显式端点配置,我们可以按照我们想要的方式更改属性。
  • 我会说您在 AjaxServiceBehavior 中添加 并检查提琴手中的响应。它可能会给出详细的例外情况。

标签: c# json wcf deserialization


【解决方案1】:

我相信您在 data 参数周围缺少一个 JSON.stringify()。在我的脑海中,我不知道 javascript 对象序列化到什么。他们可能应该假设大多数人都希望它序列化为 json 并适应它 - 但他们没有,因此 $.ajax 的参数必须在 POST 之前进行字符串化。

【讨论】:

    【解决方案2】:

    我认为问题在于您混淆了两种不同的事物。一方面,您正在通过 AJAX 请求在主机端使用 webHTTPBinding。这应该没问题,但是您还添加了 AspNetCompatibilityRequirements,这是一个以 .NET 为中心、仅限 Microsoft 的需求,它不适用于您的 Java 内容。

    所以我会摆脱 AspNetCompatibilityRequirements 并再次尝试。

    【讨论】:

    • 你是指 JavaScript 的东西吗?
    • 没错。 javascript /ajax 的东西很好。它将与 webhttpbinding 和 WCF 一起使用,但是当您添加 AspNetCompatibilityRequirements 选项时,我认为您正在为自己制造问题。摆脱它,看看会发生什么。
    • 我删除了类上的属性,但仍然遇到同样的错误。我关于 JavaScript 的问题是因为在你的回答中,你只是说“Java”,我没有在这个解决方案中使用它。
    • AspNetCompatibilityRequirements 不应导致有问题的异常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-26
    • 2013-04-20
    • 1970-01-01
    • 1970-01-01
    • 2012-10-13
    相关资源
    最近更新 更多