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的主要内容,如果未能解决你的问题,请参考以下文章