我正在使用Signal在ASP.NET服务器和WPF客户端之间通信.

根据我对文档的阅读,我们应该使用使用SignalR的简单POCO类.但是文档示例也使用枚举.我的类确实引用了另一个POCO类.在文档示例中,我没有找到任何其他类引用.另外,我的班级也不完全是波科.

实际上,我try 转移的类几乎是一个Poco(但不是HubConnection.On<LogItem>("NewLogItem", (logItem)=> OnNewLogItemFromServer(logItem));%),它没有正确地转移到SignalR中.在下面的客户端代码中,如果服务器向客户端发送"LogItem":HubConnection.On<LogItem>("NewLogItem", (logItem)=> OnNewLogItemFromServer(logItem));,则也永远不会调用lambda.服务器和客户端共享包含"LogItem"类的完全相同的库.

但我找不到阻止SignalR接受我的类实例传输的原因.我try 了许多方法,但都没有成功,以便在我的类"LogItem"(类实例被转移)中找到阻止使用SignalR进行转移的有问题的属性.

我try 了一下:Logging and diagnostics in ASP.NET Core SignalR,但它并没有帮助我找到我的LogItem类中有问题的(一个或多个)字段,阻止它被传输.

谁能告诉我一种调试SignalR的方法,以便找到阻止SignalR传输该Class的一个或多个有问题的一个或多个属性?

我的代码:我将我的代码放在引用BUT中,我正在寻找一种方法来调试SignalR.不仅仅是找到确切的实际原因,因为我将不得不使用SignalR来做其他事情.

注意:如果SignalR框架应该为我解码,我不想自己解码JSON.我想使用它,因为它是为使用而设计的.

当服务器向我发送"LogItem"但它是其中的"JsonElement"时,以下代码被调用到我的客户端:

HubConnection.On<Object>("NewLogItem", (obj) =>
            { ...

这是我的LogItem类代码作为参考(但我正在寻找一种通用的方法来查找阻止类在SignalR中成为TFR的问题):

using CommunityToolkit.Mvvm.ComponentModel;
using General.Diagnostics;
using Microsoft.Extensions.Logging;
using System;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Runtime.Serialization;
using System.Text.Json.Serialization;
using System.Xml.Serialization;

namespace General.LogEx
{
    [DataContract(Namespace = "")]
    public class LogItem : ObservableObject
    {
        private const string DateFormat = "yyyy-MM-dd HH:mm:ss.fff";

        // ******************************************************************
        [DataMember]
        public UInt64 Id { get; set; }

        //private bool _isAcknowledged = false;
        //public bool IsAcknowledged
        //{
        //    get => _isAcknowledged;
        //    set => SetProperty(ref _isAcknowledged, value);
        //}

        // ******************************************************************
        public DateTime DateTime { get; set; }

        // ******************************************************************
        [XmlIgnore]
        [JsonIgnore]
        public string TimeStamp
        {
            get
            {
                return DateTime.ToString(DateFormat);
            }
            set
            {
                DateTime = DateTime.ParseExact(value, DateFormat, CultureInfo.InvariantCulture);
            }
        }

        // ******************************************************************
        [DataMember]
        public LogCategory LogCategory { get; set; }

        // ******************************************************************
        [DataMember]
        public LogLevel LogLevel { get; set; }

        // ******************************************************************
        private string _message = null;

        [DataMember]
        public string Message
        {
            get
            {
                return _message;
            }
            set
            {
                _message = value;
            }
        }

        // ******************************************************************
        private Exception _exception = null;

        [DataMember]
        public Exception Exception
        {
            get
            {
                return _exception;
            }
            set
            {
                _exception = value;
            }
        }

        // ******************************************************************
        [XmlIgnore]
        [JsonIgnore]
        public string ExceptionMessage
        {
            get
            {
                return _exception?.Message;
            }
        }

        [DataMember]
        public string MoreInfo { get; set; }
        // ******************************************************************

        [DataMember]
        public int Occurence { get; set; } = 1;

        /// <summary>
        /// Public only for serialization (XML or JSON)
        /// </summary>
        public LogItem()
        {
        }

        // ******************************************************************
        public LogItem(UInt64 id, LogCategory logCategory, LogLevel logLevel, string message)
        {
            Id = Id;
            DateTime = DateTime.Now;
            LogCategory = logCategory;
            LogLevel = logLevel;
            Message = FixMessage(message);
        }

        // ******************************************************************
        /// <summary>
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        private string FixMessage(string message)
        {
            //if (message != null && message.Length > 0)
            //{
            //    if (message[0] == ' ' || message[message.Length - 1] == ' ')
            //    {
            //        message = message.Trim();
            //    }

            //    if (message.EndsWith("."))
            //    {
            //        return message.Substring(0, message.Length - 1);
            //    }
            //}

            return message;
        }

        // ******************************************************************
        public LogItem(UInt64 id, LogCategory logCategory, LogLevel logType, string message, Exception exception)
        {
            Id = id;
            DateTime = DateTime.Now;
            LogCategory = logCategory;
            LogLevel = logType;
            Message = FixMessage(message);
            if (exception != null)
            {
                Exception = exception;

                MoreInfo = "Exception:\nMessage:\n" + exception.Message +
                    "\nSource:\n" + exception.Source +
                    "\nStack:\n" + exception.StackTrace +
                    "\nToString():\n" + exception.ToString();
            }
            else
            {
                if (LogLevel == LogLevel.Error || LogLevel == LogLevel.Critical)
                {
                    MoreInfo = StackUtil.GetStackTraceWithoutIntialTypes(new Type[] { typeof(Log), typeof(LogItem) }).ToString();

                    if (MoreInfo.EndsWith("\r\n"))
                    {
                        MoreInfo = MoreInfo.Remove(MoreInfo.Length - 2);
                    }
                }
            }
        }

        // ******************************************************************
        [XmlIgnore]
        [JsonIgnore]
        public string MessageAndException
        {
            get { return Message + ExceptionMessage; }
        }

        // ******************************************************************
        [XmlIgnore]
        [JsonIgnore]
        public string DateTimeFormated
        {
            get { return DateTime.ToString("yyyy-MM-dd hh:mm:ss.ffffff"); }
        }

        // ******************************************************************
        public void WriteTo(StreamWriter streamWriter)
        {
            streamWriter.Write(ToString());
        }

        // ******************************************************************
        [XmlIgnore]
        [JsonIgnore]
        public string QuickDescription
        {
            get
            {
                return string.Format($"{Id}, {DateTimeFormated}, {LogLevel}, {LogCategory} , {Message.Replace("\r\n", "[CRLF]")}");
            }
        }

        // ******************************************************************
        public override string ToString()
        {
            if (string.IsNullOrEmpty(MoreInfo))
            {
                if (Occurence == 1)
                {
                    // return String.Format($"{DateTimeFormated,-26}, {LogLevel,-12}, {Message}.");
                    return string.Format("{0,5}, {1,-26}, {2,-12}, {3}.", Id, DateTimeFormated, LogLevel, Message);
                }

                // return String.Format($"{DateTimeFormated,-26}, {LogLevel,-12}, {Message}. Occurence: {Occurence}.");
                return string.Format("{0,5}, {1,-26}, {2,-12}, {3}. Occurence: {4}.", Id, DateTimeFormated, LogLevel, Message, Occurence);
            }
            else
            {
                if (Occurence == 1)
                {
                    // return String.Format($"{DateTimeFormated,-26}, {LogLevel,-12}, {Message}. MoreInfo: {MoreInfo}.");
                    return string.Format("{0,5}, {1,-26}, {2,-12}, {3}. MoreInfo: {4}.", Id, DateTimeFormated, LogLevel, Message, MoreInfo);
                }

                // return String.Format($"{DateTimeFormated,-26}, {LogLevel,-12}, {Message}. Occurence: {Occurence}, MoreInfo: {MoreInfo}.");
                return string.Format("{0,5}, {1,-26}, {2,-12}, {3}. Occurence: {4}. MoreInfo: {5}.", Id, DateTimeFormated, LogLevel, Message, Occurence, MoreInfo);
            }
        }

        // ******************************************************************
    }
}

推荐答案

我终于找到了解决我的具体问题的办法,主要是找出问题的根源.

因此,我无法接收特定于SignalR的对象类型(此处:"LogItem").因此,我替换了以下函数

HubConnection.On<LogItem>("NewLogItem", (logItem)=> OnNewLogItemFromServer(logItem));

有:

HubConnection.On<Object>("NewLogItem", (obj) => {...

但obj实际上是一个"JsonElement",需要反序列化为我的特定类型,所以我对其进行了编程,它导致了一个异常,显示了初始行在HubConnection上不起作用的确切原因.

代码是这样的:

    HubConnection.On<Object>("NewLogItem", (obj) =>
    {
        if (obj is JsonElement jsonElement)
        {
            JsonSerializerOptions opts = new JsonSerializerOptions();
            opts.PropertyNameCaseInsensitive = true;
            var logItem2 = JsonSerializer.Deserialize<LogItem>(jsonElement, opts);
        }
    });

但我得到的例外是:

The exception

这个例外很容易就解决了我的问题.我的解决方案是将"LogCategory"属性从一个类更改为一个字符串(在我的例子中是可能的).LogCategory的构造者既复杂又有问题.在我应用解决方案之后,Json反序列化没有任何例外.在我纠正了我的问题之后,如果SigalR为我做了所有的反序列化,我能够恢复到我的初始代码行.

Csharp相关问答推荐

使用ElasticsearchClient设置忽略属性.默认MappingFor<>

在实际上是List T的 IESEARCH上多次调用First()是否不好?

使用C#中的Shape API从Azure目录获取所有用户

C++/C#HostFXR通过std::tuple传递参数

REST API端点中异步后台代码执行的类型

内部接口和类的DI解析

Rider将.NET安装在哪里

Blazorise折线图仅绘制数据集的一部分

当用户右键单击文本框并单击粘贴时触发什么事件?

C#DateTime.ParseExact不使用特定日期

VS 2022 for ASP.NET Core中缺少自定义项模板

C#LINQ延迟执行和嵌套方法

从Base64转换为不同的字符串返回相同的结果

如何使用EPPlus C#在单个单元格中可视化显示多行文字

如何使用类似于[SELECT*FROM&Q;&Q;WHERE&Q;]SQL查询的System.Data.Entity创建查询?

为什么我可以在注册表编辑器中更改值,但不能在以管理员身份运行的C#表单应用程序中更改?

如何在.NET MAUI上在iOS和Mac之间共享代码?(no条件编译和无代码重复)

当要删除的子模型没有父模型的1:多属性时,如何告诉实体框架设置1:1 FK条目?

为什么INTEGER在通过反射调用时对空对象返回TRUE,而在INTEGER上调用时返回FALSE?

是否在异步方法中避免Span<;T>;.ToArray()?