gpt4 book ai didi

c# - 如何在 C# WCF REST POST 中的 StreamReader.ReadToEnd() 之后抛出 WebFaultException?

转载 作者:行者123 更新时间:2023-11-30 16:15:00 25 4
gpt4 key购买 nike

我有一个 WCF REST 项目,它将 http 状态代码作为 WebFaultExceptions 返回。这对于 GET 调用非常有效,但我在为 POST 调用返回 WebFaultException 时遇到问题。请求正文中的数据使用的内容类型为“application/x-www-form-urlencoded;charset=utf-8”。我认为问题是当上下文切换出 using 子句以抛出 WebFaultException 时,底层请求流被关闭。

如果我在“using”子句之前抛出 WebFaultException,异常将按预期返回。如果我从“using”子句中抛出 WebFaultException,则异常不会返回给客户端。

对于如何在使用流阅读器读取请求正文时能够成功抛出 WebFaultException,有没有人有任何建议?

这是我的服务器端代码的简化版本。请注意,此示例的 httpstatuscodes 对我的实际实现而言并不现实。

[WebInvoke(Method = "POST"
, UriTemplate = "urls/{id}"
, BodyStyle = WebMessageBodyStyle.WrappedRequest
)]
public string PostItem(string id, object streamdata)
{

int _id = 0;
if (int.TryParse(companyIdSr2, out _id))
{
using (System.IO.StreamReader reader = new System.IO.StreamReader(streamdata))
{
string body = reader.ReadToEnd();

if(string.IsNullOrEmpty(body))
{
// this exception doesn't make it back to the client's request object
ThrowError(HttpStatusCode.BadRequest, "empty body");
}
}
}
else
{
// this exception is successfully returned to the client's request object
ThrowError(HttpStatusCode.BadRequest, "invalid id");
}
}

private static void ThrowError(HttpStatusCode status, string message)
{
request_error error = new request_error
{
request_url = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri.OriginalString,
error_status_code = status.ToString(),
error_message = message,
};

throw new WebFaultException<request_error>(error, status);
}

public class request_error
{
[XmlElement("request_url")]
public string request_url { get; set; }
[XmlElement("error_status_code")]
public string error_status_code { get; set; }
[XmlElement("error_message")]
public string error_message { get; set; }
}

我看过这个问题 - Wrong WebFaultException when using a Stream and closing the stream - 尽管它在一定程度上解决了这个问题,但仍 Unresolved 是不处置或关闭流是否合理。

非常感谢,

特里

最佳答案

question您链接到的内容现在已收到解决您问题的已接受答案。

你说:

and although it addresses the issue somewhat, left unanswered is whether it is reasonable to not dispose or close the stream.

对此,答案是:

But it would be better to not leave the StreamReader without disposing it because it can't clean any unmanaged resources.

为了支持这一点,我们在另一个 StackOverflow 线程上有以下答案,该线程争论为什么调用 Dispose() 很重要:https://stackoverflow.com/a/2548694/700926

为了解决您在问题中提出的最初问题(WebFaultException 不会发送回客户端),我最终按照 this answer 中的建议做了- 将 System.IO.StreamReader 子类化并覆盖 Close,以便它告诉 StreamReader 仅释放非托管资源而不关闭流。

我的 WcfFriendlyStreamReader 看起来像这样:

public class WcfFriendlyStreamReader : StreamReader
{
public WcfFriendlyStreamReader(Stream s) : base(s) { }

public override void Close()
{
base.Dispose(false);
}
}

MSDN documentation 可以看出调用 Dispose(false) 只会释放非托管资源。正如反编译器所揭示的那样,这也会导致 Stream 保持打开状态,这似乎可以解决问题:

protected override void Dispose(bool disposing)
{
try
{
if (this.LeaveOpen || !disposing || this.stream == null)
return;
this.stream.Close();
}
finally
{
if (!this.LeaveOpen && this.stream != null)
{
this.stream = (Stream) null;
this.encoding = (Encoding) null;
this.decoder = (Decoder) null;
this.byteBuffer = (byte[]) null;
this.charBuffer = (char[]) null;
this.charPos = 0;
this.charLen = 0;
base.Dispose(disposing);
}
}
}

关于c# - 如何在 C# WCF REST POST 中的 StreamReader.ReadToEnd() 之后抛出 WebFaultException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19986488/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com