Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 4.0 作为HttpError的一部分将数组序列化为XML时出现InvalidOperationException_C# 4.0_Asp.net Web Api - Fatal编程技术网

C# 4.0 作为HttpError的一部分将数组序列化为XML时出现InvalidOperationException

C# 4.0 作为HttpError的一部分将数组序列化为XML时出现InvalidOperationException,c#-4.0,asp.net-web-api,C# 4.0,Asp.net Web Api,当从包含集合的HttpError创建错误响应时,是否有办法绕过invalidoOperationException 只有当响应序列化为XML时,才会出现这种情况,序列化为JSON效果绝对不错 问题似乎与HttpError将要序列化的数据存储在字典中这一事实有关。如果我添加了一个自定义类的数组(FieldError),那么它就不能正确地将其序列化为XML。但是,当我直接用一个属性序列化一个类时,该属性是FieldError类的数组,该数组确实被正确地序列化为XML 有没有办法让集合也作为HTTP错

当从包含集合的
HttpError
创建错误响应时,是否有办法绕过
invalidoOperationException

只有当响应序列化为XML时,才会出现这种情况,序列化为JSON效果绝对不错

问题似乎与HttpError将要序列化的数据存储在
字典中这一事实有关。如果我添加了一个自定义类的数组(
FieldError
),那么它就不能正确地将其序列化为XML。但是,当我直接用一个属性序列化一个类时,该属性是
FieldError
类的数组,该数组确实被正确地序列化为XML

有没有办法让集合也作为HTTP错误的一部分进行序列化

引发异常时,我得到的完整响应是:

<Error>
    <Message>An error has occurred.</Message>
    <ExceptionMessage>The 'ObjectContent`1' type failed to serialize the response body for content type 'text/xml; charset=utf-8'.</ExceptionMessage>
    <ExceptionType>System.InvalidOperationException</ExceptionType>
    <StackTrace />
    <InnerException>
        <Message>An error has occurred.</Message>
        <ExceptionMessage>Xml type 'xdt:untypedAtomic' does not support a conversion from Clr type 'FieldError' to Clr type 'String'.</ExceptionMessage>
        <ExceptionType>System.InvalidCastException</ExceptionType>
        <StackTrace>at System.Xml.Schema.XmlUntypedConverter.ChangeListType(Object value, Type destinationType, IXmlNamespaceResolver nsResolver)
            at System.Xml.Schema.XmlUntypedConverter.ChangeTypeWildcardDestination(Object value, Type destinationType, IXmlNamespaceResolver nsResolver)
            at System.Xml.Schema.XmlUntypedConverter.ToString(Object value, IXmlNamespaceResolver nsResolver)
            at System.Xml.Schema.XmlListConverter.ListAsString(IEnumerable list, IXmlNamespaceResolver nsResolver)
            at System.Xml.Schema.XmlListConverter.ChangeListType(Object value, Type destinationType, IXmlNamespaceResolver nsResolver)
            at System.Xml.Schema.XmlUntypedConverter.ChangeListType(Object value, Type destinationType, IXmlNamespaceResolver nsResolver)
            at System.Xml.Schema.XmlUntypedConverter.ChangeTypeWildcardDestination(Object value, Type destinationType, IXmlNamespaceResolver nsResolver)
            at System.Xml.Schema.XmlUntypedConverter.ToString(Object value, IXmlNamespaceResolver nsResolver)
            at System.Xml.XmlWriter.WriteValue(Object value)
            at System.Web.Http.HttpError.System.Xml.Serialization.IXmlSerializable.WriteXml(XmlWriter writer)
            at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteIXmlSerializable(XmlWriterDelegator xmlWriter, Object obj, XmlSerializableWriter xmlSerializableWriter)
            at System.Runtime.Serialization.XmlDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context)
            at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
            at System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
            at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
            at System.Runtime.Serialization.DataContractSerializer.WriteObject(XmlWriter writer, Object graph)
            at System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content)
            at System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)
            --- End of stack trace from previous location where exception was thrown ---
            at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
            at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
            at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
            at System.Web.Http.WebHost.HttpControllerHandler.&lt;WriteBufferedResponseContentAsync&gt;d__1b.MoveNext()
        </StackTrace>
    </InnerException>
</Error>
我有一个
ExceptionFilterAttribute
,它将API抛出的任何自定义异常转换为
HttpError
,并返回错误响应:

public override void OnException(HttpActionExecutedContext context)
{
    var apiException = context.Exception as ApiException;
    if (apiException != null)
    {
        context.Response = context.Request.CreateErrorResponse((HttpStatusCode)apiException.ReasonCode, apiException.ToHttpError());
        return;
    }

    base.OnException(context);
}
自定义API异常的基类转换为HttpErrors,如下所示:

internal virtual HttpError ToHttpError()
{
    var httpError = new HttpError(this.Message) { { "ExceptionType", this.TypeName } };

    var innerApiError = this.InnerException as ApiException;
    if (innerApiError != null)
    {
        httpError.Add("InnerError", innerApiError.ToHttpError());
    }
    else if (this.InnerException != null)
    {
        httpError.Add("InnerError", new HttpError(this.InnerException.Message) { { "ExceptionType", this.InnerException.GetType().Name } });
    }

    return httpError;
}
然后,我有一个派生的异常类,它带有一个数组,该数组重载了
到httperror

public FieldError[] Errors { get; private set; }

internal override HttpError ToHttpError()
{
    var error = base.ToHttpError();

    error.Add("Errors", this.Errors);

    return error;
}
FieldErrors
属性是一个填充数组,
FieldError
类声明为:

[DataContract(Namespace = "")]
public class FieldError
{
    [DataMember]
    public string Field
    {
        get;
        set;
    }

    [DataMember]
    public string Error
    {
        get;
        set;
    }

    [IgnoreDataMember]
    public ApiErrorTypes ErrorType
    {
        get;
        set;
    }
}
当我告诉API返回JSON时,得到的响应是:

{
    "Message":"The supplied parameters are invalid.",
    "ExceptionType":"InvalidRequestDataException",
    "Errors":[
      {
        "Field":"CollectionDate",
        "Error":"Collection date is not in a valid date format"
      }
    ]
}

我发现解决这个问题的唯一方法是创建一个新类,该类使用
DataContract
并调用
context.Request.CreateResponse()
从中创建响应,而不是使用
HttpError
context.Request.CreateErrorResponse()

{
    "Message":"The supplied parameters are invalid.",
    "ExceptionType":"InvalidRequestDataException",
    "Errors":[
      {
        "Field":"CollectionDate",
        "Error":"Collection date is not in a valid date format"
      }
    ]
}