简体   繁体   English

连接响应属性为驼峰式

[英]Connection response properties are camel case

I have no idea why this is happening. 我不知道为什么会这样。 I'm connecting my angular 4 app to a signalR hub from the hosting server and it works like a charm (version 2.2.2) 我正在将我的angular 4应用程序从托管服务器连接到signalR集线器,它的工作原理就像一个超级按钮(2.2.2版)

I'm now having to add a second signalR connection to another project and for some unknown reason the properties of the response are all camelCase in stead of PascalCase. 我现在必须向另一个项目添加第二个signalR连接,并且由于某些未知的原因,响应的属性全部是camelCase而不是PascalCase。 The jquery.signalr-2.2.2.js file however expects them to be PascalCase and throws an error that the server version is "undefined". 但是,jquery.signalr-2.2.2.js文件期望它们为PascalCase,并抛出服务器版本“未定义”的错误。

"Undefined" is logical since he's looking for res.ProtocolVersion and that property does not exist on my deserialized response. 由于他正在寻找res.ProtocolVersion,因此“未定义”是合乎逻辑的,并且该属性在我的反序列化响应中不存在。 I do however have a res.protocolVersion and that one holds the exact value that he needs. 但是,我确实有一个res.protocolVersion,它拥有他需要的确切值。

I've been losing a lot of time on this, any help is seriously appreciated! 我为此已经浪费了很多时间,我们非常感谢您的帮助!

调试jquery.signalR-2.2.2.js

Edit: @rory-mccrossan 编辑:@ rory-mccrossan 在此处输入图片说明 I thought as much and that's why I commented out the server side json serializer/formatter code, but to no avail. 我想了很多,这就是为什么我注释掉了服务器端的json序列化器/格式化程序代码,但无济于事。

I'm taking any suggestion where to look next 我正在考虑下一个建议

So after Rory's hint I searched some more on the internet and of course, someone else has run into this problem: 因此,在罗瑞(Rory)的提示下,我在互联网上搜索了更多内容,当然,其他人也遇到了这个问题:

SignalR : use camel case SignalR:使用骆驼套

However, the solution isn't working for me :/ 但是,该解决方案不适用于我:/

Then I found a similar solution, here however you'll always have the default contract resolver except when the object comes from a certain library -the one with your view models-. 然后,我找到了一个类似的解决方案,但是在这里,您将始终具有默认的合同解析器,除非对象来自某个库(带有视图模型的库)。 https://blogs.msdn.microsoft.com/stuartleeks/2012/09/10/automatic-camel-casing-of-properties-with-signalr-hubs/ https://blogs.msdn.microsoft.com/stuartleeks/2012/09/10/automatic-camel-casing-of-properties-with-signalr-hubs/

Note: This is not the perfect solution, but it is one that worked best for my scenario 注意:这不是理想的解决方案,但它是最适合我的情况的解决方案

So I came up with a new solution all together that ties in nicely with the existing code that is giving me the problem. 因此,我想出了一个新的解决方案,它与存在问题的现有代码很好地结合在一起。

The other way to go around this is to let your app use the DefaultContractResolver . 解决此问题的另一种方法是让您的应用使用DefaultContractResolver SignalR will now connect, but the rest of your application will break. SignalR现在将连接,但是您的其他应用程序将中断。 To mitigate this in the solution I'm working in I used two simple extension methods. 为了缓解该问题,我正在使用两种简单的扩展方法。

Firstly I extended the HttpConfiguration class to swap out the formatter for a CamelCasePropertyNamesContractResolver 首先,我扩展了HttpConfiguration类,以换出CamelCasePropertyNamesContractResolver的格式化程序

public static class HttpConfigurationExtensions
    {
        public static HttpConfiguration ToCamelCaseHttpConfiguration(this HttpConfiguration configuration)
        {
            var jsonFormatter = configuration.Formatters.OfType<JsonMediaTypeFormatter>().FirstOrDefault();
            bool needToAddFormatter = jsonFormatter == null;
            if (needToAddFormatter)
            {
                jsonFormatter = new JsonMediaTypeFormatter();
            }
            jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            jsonFormatter.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
            if (needToAddFormatter)
            {
                configuration.Formatters.Add(jsonFormatter);
            }
            return configuration;
        }
    }

The existing Web API will always return a HttpResponseMessage and that's why I could go about it in the way that I did. 现有的Web API将始终返回HttpResponseMessage ,这就是为什么我可以像以前那样处理它。

Example of an api call api调用示例

[Route("")]
[HttpPost]
public async Task<HttpResponseMessage> CreateSetting(Setting setting)
{
   // the response object is basically the data you want to return
   var responseData = await ...

   return Request.CreateResponse(responseData.StatusCode, responseData);
}

I noticed every Api call was using the Request.CreateResponse(...) method. 我注意到每个Api调用都使用Request.CreateResponse(...)方法。 What I didn't see immediately is that Microsoft actually has foreseen all necessary overloads, this meant I couldn't just make my own Request.CreateResponse(...) implementation. 我没有立即看到的是Microsoft实际上已经预见到了所有必要的重载,这意味着我不能只做自己的Request.CreateResponse(...)实现。

That's why it's called MakeResponse 这就是为什么它被称为MakeResponse

public static class HttpRequestMessageExtensions
{
    public static HttpResponseMessage MakeResponse<T>(this HttpRequestMessage request, T response) where T : Response
    {
        return request.CreateResponse(response.StatusCode, response,
            request.GetConfiguration().ToCamelCaseHttpConfiguration());
    }
}

The Response classes are the data structures that you want your api to return. Response类是您希望api返回的数据结构。 In our api they all got wrapped into one of these structures. 在我们的api中,它们全都包裹在这些结构之一中。 This results into an api with responses similar to the ones on the Slack API. 这会导致api的响应类似于Slack API上的响应。

So now the controllers all use Request.MakeResponse(responseData) 因此,现在所有控制器都使用Request.MakeResponse(responseData)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM