使用委托包装异常处理时 Web-API 调用不起作用
Web-API call not working when using delegate to wrap exception handling
我有一个带有自托管 OWIN 的 .NET 4.5.2 应用程序来支持内部 Web api。为了进行一般的异常处理,我尝试将所有调用包装在方法 "TryOk" 中,并以委托作为参数。 TryOk 然后会关心异常并处理它们。
我尝试在没有委托的情况下调用 web-api,它成功了。仅在使用委托时出现错误。
我最大限度地减少了代码并删除了所有代码镇流器,如异步。
[HttpPost, Route("echo")]
public IHttpActionResult MyEchoApi([FromBody]string echo)
{
// this is working: direct return
//return Ok("you say " + echo ?? "nothing");
// this is also working: direct return with exception handling
//try { return Ok(call()); }
//catch (Exception ex) { return BadRequest(ex.Message); }
// this is not working: wrapping in delegate
return TryOk(() => { return Ok("you say " + echo ?? "nothing"); });
}
private IHttpActionResult TryOk<T>(Func<T> call)
{
try { return Ok(call()); }
catch (Exception ex) { return BadRequest(ex.Message); }
}
我得到异常 "Error getting value from 'Length' on 'Microsoft.Owin.Host.HttpListener.RequestProcessing.HttpListenerStreamWrapper'.",内部异常 "This stream does not support seek operations"。
异常详情:
"ExceptionMessage": "Error getting value from 'Length' on 'Microsoft.Owin.Host.HttpListener.RequestProcessing.HttpListenerStreamWrapper'.",
"ExceptionType": "Newtonsoft.Json.JsonSerializationException",
"StackTrace": " bei Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)
bei Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues(JsonWriter writer, Object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, JsonContract& memberContract, Object& memberValue)
bei Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
bei Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeDictionary(JsonWriter writer, IDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
bei Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
bei Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
bei Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeDictionary(JsonWriter writer, IDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
bei Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
bei Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
bei Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
bei Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)
bei System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)
bei System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)
bei System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
bei System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
bei System.Web.Http.Owin.HttpMessageHandlerAdapter.<BufferResponseContentAsync>d__27.MoveNext()",
"InnerException": {
"Message": "An error has occurred.",
"ExceptionMessage": "This stream does not support seek operations.",
"ExceptionType": "System.NotSupportedException",
"StackTrace": " bei System.Net.HttpResponseStream.get_Length()
bei GetLength(Object )
bei Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)"
}
我做错了什么?
感谢您的任何回答或想法。
-- 贾兹
您是 ,这就是导致您出现该错误的原因。
在这一行中,您在回调函数中 return 编辑了一个 IHttpActionResult:
return TryOk(() => { return Ok("you say " + echo ?? "nothing"); });
您不需要调用Ok(call())
,只需调用return call()
。
private IHttpActionResult TryOk<T>(Func<T> call)
{
// call itself returns an Ok http action result, you are returning a reposnse on another response! just change to call();
try { return Ok(call()); }
catch (Exception ex) { return BadRequest(ex.Message); }
}
编辑 1:
您甚至可以通过检查 callbac 函数的 return 值使您的 TryOk
方法更加智能。
try
{
var returnValue = call();
if(returnValue is IHttpActionResult)
return returnValue;
return Ok(returnValue);
}
catch(Exception ex)
{
return BadRequest(ex.Message);
}
我还有一个建议,我推荐你使用A global Exception Filter。
我有一个带有自托管 OWIN 的 .NET 4.5.2 应用程序来支持内部 Web api。为了进行一般的异常处理,我尝试将所有调用包装在方法 "TryOk" 中,并以委托作为参数。 TryOk 然后会关心异常并处理它们。
我尝试在没有委托的情况下调用 web-api,它成功了。仅在使用委托时出现错误。
我最大限度地减少了代码并删除了所有代码镇流器,如异步。
[HttpPost, Route("echo")]
public IHttpActionResult MyEchoApi([FromBody]string echo)
{
// this is working: direct return
//return Ok("you say " + echo ?? "nothing");
// this is also working: direct return with exception handling
//try { return Ok(call()); }
//catch (Exception ex) { return BadRequest(ex.Message); }
// this is not working: wrapping in delegate
return TryOk(() => { return Ok("you say " + echo ?? "nothing"); });
}
private IHttpActionResult TryOk<T>(Func<T> call)
{
try { return Ok(call()); }
catch (Exception ex) { return BadRequest(ex.Message); }
}
我得到异常 "Error getting value from 'Length' on 'Microsoft.Owin.Host.HttpListener.RequestProcessing.HttpListenerStreamWrapper'.",内部异常 "This stream does not support seek operations"。
异常详情:
"ExceptionMessage": "Error getting value from 'Length' on 'Microsoft.Owin.Host.HttpListener.RequestProcessing.HttpListenerStreamWrapper'.",
"ExceptionType": "Newtonsoft.Json.JsonSerializationException",
"StackTrace": " bei Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)
bei Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues(JsonWriter writer, Object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, JsonContract& memberContract, Object& memberValue)
bei Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
bei Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeDictionary(JsonWriter writer, IDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
bei Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
bei Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
bei Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeDictionary(JsonWriter writer, IDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
bei Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
bei Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
bei Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
bei Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)
bei System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)
bei System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)
bei System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
bei System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
bei System.Web.Http.Owin.HttpMessageHandlerAdapter.<BufferResponseContentAsync>d__27.MoveNext()",
"InnerException": {
"Message": "An error has occurred.",
"ExceptionMessage": "This stream does not support seek operations.",
"ExceptionType": "System.NotSupportedException",
"StackTrace": " bei System.Net.HttpResponseStream.get_Length()
bei GetLength(Object )
bei Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)"
}
我做错了什么?
感谢您的任何回答或想法。
-- 贾兹
您是
在这一行中,您在回调函数中 return 编辑了一个 IHttpActionResult:
return TryOk(() => { return Ok("you say " + echo ?? "nothing"); });
您不需要调用Ok(call())
,只需调用return call()
。
private IHttpActionResult TryOk<T>(Func<T> call)
{
// call itself returns an Ok http action result, you are returning a reposnse on another response! just change to call();
try { return Ok(call()); }
catch (Exception ex) { return BadRequest(ex.Message); }
}
编辑 1:
您甚至可以通过检查 callbac 函数的 return 值使您的 TryOk
方法更加智能。
try
{
var returnValue = call();
if(returnValue is IHttpActionResult)
return returnValue;
return Ok(returnValue);
}
catch(Exception ex)
{
return BadRequest(ex.Message);
}
我还有一个建议,我推荐你使用A global Exception Filter。