HttpRequestMessage.CreateResponse 抛出 ***Exception
Posted
技术标签:
【中文标题】HttpRequestMessage.CreateResponse 抛出 ***Exception【英文标题】:HttpRequestMessage.CreateResponse threw ***Exception 【发布时间】:2021-01-25 22:48:55 【问题描述】:我有一个函数应用。我写了一个单元测试项目(xunit)来测试我的函数应用代码。在单元测试方法中,我正在调用函数应用的 Run 方法。当请求为“Get”时,我的函数应用返回一个简单的 json 对象。虽然这在我的机器上运行良好,但在我同事的所有机器中,下面一行都在抛出 ***Exception
。当我检查异常详细信息时,StackTrace 为空。
request.CreateResponse(HttpStatusCode.OK, jObject)
在调试窗口中,我看到错误为 “System.private.corlib.dll 中发生未处理的异常”
功能应用:
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequestMessage req, ILogger log)
if (req.Method.Method.Equals(HttpMethod.Get.Method))
NameValueCollection queryString = System.Web.HttpUtility.ParseQueryString(req.RequestUri.Query);
operation = queryString.Get("operation");
if (operation == "GetVersion")
version = VersionHistory.GetVersion("ABC");// returns
// "ABC" : "2.1"
return req.CreateResponse(HttpStatusCode.OK, version);
//Above line causes ***Exception
else
return 'Error message'
上面代码中的 VersionHistory 只是我正在使用的一个静态类。它只是返回一个类似于 "ABC": "0.1.2" 的 json 对象。与.net框架版本无关。
public static JObject GetVersion(string key)
// some logic. This logic is hit only once. I'm sure this is not
// causing any exception
return JObject.Parse("\"" + key + "\":\"0.1.2\"");
单元测试:
public async Task Run_WhenGetRequest_ShouldReturnAppropriateFunctionAppVersion()
const string QUERYSTRING_KEY = "operation";
const string QUERYSTRING_VALUE = "GetVersion";
const string FUNCTION_APP_NAME = "ABC";
const string FUNCTION_APP_VERSION = "2.1";
_request.Method = HttpMethod.Get;
NameValueCollection queryList = HttpUtility.ParseQueryString(_request.RequestUri.Query);
if (queryList.Get(QUERYSTRING_KEY) == null)
string queryString = QueryHelpers.AddQueryString(_request.RequestUri.ToString(), QUERYSTRING_KEY, QUERYSTRING_VALUE);
_request.RequestUri = new System.Uri(queryString);
HttpResponseMessage response = await FunctionAppClassName.Run(_request, _logger);
// Assert code
我在 Fixture 类中构造了请求对象,如下所示,并模拟了 Logger 实例。
Request = new HttpRequestMessage
Content = new StringContent("", Encoding.UTF8, "application/json"),
RequestUri = new Uri("http://localhost/")
;
var services = new ServiceCollection().AddMvc().AddWebApiConventions().Services.BuildServiceProvider();
Request.Properties.Add(nameof(HttpContext), new DefaultHttpContext RequestServices = services );
知道如何解决这个问题吗?
【问题讨论】:
minimal reproducible example 请... 很可能是两个问题之一 1) 存在凭据问题,因此响应中没有返回数据 2) 由于使用了默认 TLS 版本,HTTP 连接失败。我会使用像wireshark或fiddler这样的嗅探器并检查响应中的状态。一个好的响应应该是 200 OK。错误的响应将是 400/500 错误。还要比较工作与非工作。检查 TLS 版本并检查第一个请求中的标头。确保用户代理标头在工作和非工作中是相同的。 @mjwills 添加了最小可重现示例。正如我所说它在我的机器上工作我不确定你是否会得到异常。 本网站的主要规则之一是关闭没有最小可重复示例的问题,原因很简单,几乎不可能回答这样的问题。 版本历史从何而来?你是如何部署代码的?如果两台机器的 Net 版本不同,或者机器上的微处理器不同,就会出现错误。看起来版本可能为空。 【参考方案1】:我们终于找到了问题所在。问题是当我们从测试用例调用 Http 触发函数应用程序时,它无法找到 MediaType。在响应中添加媒体类型后,如下所示。
return req.CreateResponse(HttpStatusCode.OK, jObject, "application/json");
我仍然不确定为什么此问题仅出现在 Visual Studio 2019 16.6.x 和 16.7.x 中,但未出现在 16.4.x 中。如果有人能对此有所了解,我们将不胜感激
感谢那些付出时间的人。
【讨论】:
我认为您已经接受了我的评论,即它有点“sus”。但作为 OP 和 SO 指南的一部分,您应该提供minimal reproducible example,或者在创建此线程时至少发布错误详细信息。另外我过去也遇到过类似的错误,不是因为我使用的是16.6x版本,而是因为我没有在Visual Studio中安装所有适当的包,当VS去查看时在那里存储在不可用的注册表中的媒体/类型。因此,您可能只需要安装一些 IIS 组件,或者 VS 安装中缺少 Web api @Kishan 我们要求问题可以通过 here 发布的代码重现,而不是在外部存储库中,抱歉。从长远来看,我们正在为未来的访问者构建一个问题和答案的存储库,并且不保证外部存储库的持续时间相同。以上是关于HttpRequestMessage.CreateResponse 抛出 ***Exception的主要内容,如果未能解决你的问题,请参考以下文章