【问题标题】:WCF: Getting (400) Bad Request when sending small amount of dataWCF:发送少量数据时出现(400)错误请求
【发布时间】:2012-08-28 21:46:14
【问题描述】:

当我尝试发送超过 100 个审核条目时,我收到“远程服务器返回意外响应:(400) 错误请求”。我正在使用 Fiddler 来帮助调试并确实看到请求被发送到服务器。客户端和服务器都使用相同的接口。

[ServiceContract]
public interface ISyncDataContract
{
    #region Audit Log

    /// <summary>
    /// Creates a collection of new audit entries items in the database.
    /// </summary>
    /// <param name="items">The audit entry items to be created.</param>
    /// <returns><c>True</c> if created successfully; otherwise, <c>false</c>.</returns>
    [OperationContract]
    [WebInvoke(UriTemplate = "AuditEntries", Method = "PUT")]
    bool CreateAuditEntryItems(AuditEntryItemCollection items);

    /// <summary>
    /// Gets all the audit entry items available.
    /// </summary>
    /// <returns>An <see cref="AuditEntryItemCollection"/> object containing all the
    /// available audit entry items.</returns>
    [OperationContract]
    [WebGet(UriTemplate = "AuditEntries")]
    Message GetAuditEntryItems();

    #endregion
}

AuditEntryItem.cs

[DataContract]
public class AuditEntryItem
{
    #region Constructor/Deconstructor

    /// <summary>
    /// Initializes a new instance of the <see cref="AuditEntryItem"/> class.
    /// </summary>
    public AuditEntryItem()
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="AuditEntryItem"/> class.
    /// </summary>
    /// <param name="auditEntry">The audit entry.</param>
    public AuditEntryItem(AuditEntry auditEntry)
    {
        if (auditEntry == null)
        {
            throw new ArgumentNullException("auditEntry");
        }

        this.Audit_Type = auditEntry.Audit_type;
        this.ComputerName = Environment.MachineName;
        this.Message = auditEntry.Message;
        this.Sequence_Number = auditEntry.Sequence_number;
        this.Session_ID = auditEntry.Session_ID;
        this.SyncDate = DateTime.Now;
        this.Time_Stamp = auditEntry.Time_stamp;
        this.User_ID = auditEntry.User_ID;
    }

    #endregion Constructor/Deconstructor

    #region Properties

    /// <summary>
    /// Gets or sets the session ID.
    /// </summary>
    /// <value>
    /// The session ID.
    /// </value>
    [DataMember]
    [XmlElement(ElementName = @"Session_ID")]
    public string Session_ID { get; set; }

    /// <summary>
    /// Gets or sets the user ID.
    /// </summary>
    /// <value>
    /// The user ID.
    /// </value>
    [DataMember]
    [XmlElement(ElementName = @"User_ID")]
    public string User_ID { get; set; }

    /// <summary>
    /// Gets or sets the time stamp.
    /// </summary>
    /// <value>
    /// The time stamp.
    /// </value>
    [DataMember]
    [XmlElement(ElementName = @"Time_Stamp")]
    public string Time_Stamp { get; set; }

    /// <summary>
    /// Gets or sets the sequence number.
    /// </summary>
    /// <value>
    /// The sequence number.
    /// </value>
    [DataMember]
    [XmlElement(ElementName = @"Sequence_number")]
    public int Sequence_Number { get; set; }

    /// <summary>
    /// Gets or sets the message.
    /// </summary>
    /// <value>
    /// The message.
    /// </value>
    [DataMember]
    [XmlElement(ElementName = @"Message")]
    public string Message { get; set; }

    /// <summary>
    /// Gets or sets the type of the audit.
    /// </summary>
    /// <value>
    /// The type of the audit.
    /// </value>
    [DataMember]
    [XmlElement(ElementName = @"Audit_type")]
    public string Audit_Type { get; set; }

    /// <summary>
    /// Gets or sets the name of the computer.
    /// </summary>
    /// <value>
    /// The name of the computer.
    /// </value>
    [DataMember]
    [XmlElement(ElementName = @"ComputerName")]
    public string ComputerName { get; set; }

    /// <summary>
    /// Gets or sets the sync date.
    /// </summary>
    /// <value>
    /// The sync date.
    /// </value>
    [DataMember]
    [XmlElement(ElementName = @"SyncDate")]
    public DateTime? SyncDate { get; set; }

    /// <summary>
    /// Gets the time stamp value in a date time format.
    /// </summary>
    [XmlIgnore]
    public DateTime DisplayTimeStamp
    {
        get { return this.TimeStampDateTime(); }
    }

    #endregion Properties

    #region Overrides

    public override bool Equals(object obj)
    {
        return obj is AuditEntryItem ? this.Equals((AuditEntryItem)obj) : false;
    }

    public bool Equals(AuditEntryItem other)
    {
        if (ReferenceEquals(this, other))
        {
            return true;
        }

        return string.Equals(this.Audit_Type, other.Audit_Type) &&
               string.Equals(this.ComputerName, other.ComputerName) &&
               string.Equals(this.Message, other.Message) &&
               this.Sequence_Number == other.Sequence_Number &&
               string.Equals(this.Session_ID, other.Session_ID) &&
               this.SyncDate == other.SyncDate &&
               string.Equals(this.Time_Stamp, other.Time_Stamp) &&
               string.Equals(this.User_ID, other.User_ID);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            var result = (this.Audit_Type != null ? this.Audit_Type.GetHashCode() : 0);
            result = (result * 397) ^ (this.ComputerName != null ? this.ComputerName.GetHashCode() : 0);
            result = (result * 397) ^ (this.Message != null ? this.Message.GetHashCode() : 0);
            result = (result * 397) ^ this.Sequence_Number.GetHashCode();

            result = (result * 397) ^ (this.Session_ID != null ? this.Session_ID.GetHashCode() : 0);
            result = (result * 397) ^ (this.SyncDate != null ? this.SyncDate.GetHashCode() : 0);
            result = (result * 397) ^ (this.Time_Stamp != null ? this.Time_Stamp.GetHashCode() : 0);
            result = (result * 397) ^ (this.User_ID != null ? this.User_ID.GetHashCode() : 0);
            return result;
        }
    }

    #endregion Overrides

    /// <summary>
    /// Converts the Java time stamp value into a readable format.
    /// </summary>
    /// <returns>A readable date time format.</returns>
    private DateTime TimeStampDateTime()
    {
        if (this.Time_Stamp.IsNullOrEmpty())
        {
            return new DateTime(1970, 01, 01);
        }

        long value;
        if (!long.TryParse(this.Time_Stamp, out value))
        {
            return new DateTime(1970, 01, 01);
        }

        value = value / 1000;
        return new DateTime(1970, 01, 01).AddSeconds(value);
    }
}

AuditEntryItemCollection.cs

[DataContract]
[XmlRoot(ElementName = "AuditLog")]
public class AuditEntryItemCollection
{
    #region Declarations

    #endregion Declarations

    #region Constructor/Deconstructor

    /// <summary>
    /// Initializes a new instance of the <see cref="AuditEntryItemCollection"/> class.
    /// </summary>
    public AuditEntryItemCollection()
    {
        this.AuditEntryItems = new List<AuditEntryItem>();
    }

    #endregion Constructor/Deconstructor

    #region Properties

    /// <summary>
    /// Gets or sets the collection of <see cref="AuditEntryItem"/>
    /// objects.
    /// </summary>
    /// <value>
    /// The collection of <see cref="AuditEntryItem"/> objects.
    /// </value>
    [XmlElement(ElementName = @"AuditEntry")]
    [DataMember]
    public List<AuditEntryItem> AuditEntryItems { get; set; }

    #endregion Properties
}

App.config

<?xml version="1.0" encoding="utf-8" ?>

<behaviors>
  <endpointBehaviors>
    <behavior name="restXmlBehavior">
      <webHttp helpEnabled="true" defaultOutgoingResponseFormat="Xml" />
      <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
    </behavior>
    <behavior name="rssAtomBehavior">
      <webHttp/>
    </behavior>
  </endpointBehaviors>

  <serviceBehaviors>
    <behavior name="metadataBehavior" >
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
      <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

<bindings>
  <webHttpBinding>
    <binding name="StreamedHttp"
             maxReceivedMessageSize="2147483647"
             transferMode="Streamed" >
      <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="6000000" />
    </binding>
  </webHttpBinding>
</bindings>

更新:

我现在得到的错误是“已超出传入消息的最大消息大小配额 (65536)。要增加配额,请在适当的绑定元素上使用 MaxReceivedMessageSize 属性。”据我所知,我已经这样做了。我还需要设置其他设置吗?

【问题讨论】:

  • 您可以访问服务器吗?检查 Windows 事件查看器是否有错误。另请查看服务跟踪查看器:msdn.microsoft.com/en-us/library/ms732023.aspx
  • 尝试在您的服务上启用跟踪以了解您收到错误请求的确切原因。另外,请发布您的原始请求如何来自 Fiddler。

标签: wcf


【解决方案1】:

您可以确保 httpRuntime 也针对大型请求进行了配置:

(从我用来上传文件的服务中获取的示例:)

<httpRuntime executionTimeout="3600" maxRequestLength="50000000" maxQueryStringLength="2097151" requestValidationMode="2.0" />

也许还可以查看绑定上的缓冲池大小(同样,这些值只是示例):

 <binding name="WHB" maxReceivedMessageSize="50000000" maxBufferPoolSize="50000000" crossDomainScriptAccessEnabled="true">
          <readerQuotas maxArrayLength="50000000" maxStringContentLength="50000000" />

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-10
    • 1970-01-01
    • 2016-01-06
    • 2021-05-19
    • 1970-01-01
    • 1970-01-01
    • 2021-12-21
    • 1970-01-01
    相关资源
    最近更新 更多