英文:
Try to use SignalR in my cshtml to update schedule time table in background with out refresh browser ,but got an error in Hub class
问题
await Clients.All.SendAsync("updateSchedule", Schedule);
这段代码出现了空引用异常,我确信Schedule不是空的,问题可能出在Clients上。这个函数每少于60秒调用一次,但无法将数据发送给客户端(通过我的cshtml页面使用javascript)。请提供一些方法来解决这个问题,谢谢。
<details>
<summary>英文:</summary>
every thing is fine when i try to connect to signalR and gave me a token and Connection is stablished
but when client call the hub class and i i want to invoke my updated json data to client got error and never found what happend .
my project is an asp.net core web app razor page with .net 7
i have a TimeTable.cshtml that shows scheduleTime Table and must update every 1 minute at least so , i connect to signalR via javascript
here is my code in hub class
using Dapper;
using GameFest.Model;
using GameFest.Web.Data;
using GameFest.Web.Helpers;
using GameFest.Web.Services.Contracts;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using System.Data;
using System.Threading.Tasks;
using Timer = System.Timers.Timer;
namespace GameFest.Web.Areas.Portal.Services
{
[Authorize]your text
public class BtlNetHub : Hub
{
private readonly ApplicationDbContext _db;
private readonly IConfiguration _config;
private Timer _timer;
public BtlNetHub(ApplicationDbContext db, IConfiguration config)
{
_db = db;
_config = config;
// set up the timer
_timer = new Timer();
_timer.Interval = IntervalInMilliseconds;
_timer.Elapsed += _timer_Elapsed;
_timer.Enabled = true;
}
public void Dispose()
{
_timer?.Dispose();
}
private const int IntervalInMilliseconds = 60000;
// define method as an endpoint
[HubMethodName("updateSchedule")]
public async Task UpdateSchedule()
{
using IDbConnection connection = new SqlConnection(_config.GetConnectionString("GameFestConnection"));
using var data = await connection.QueryMultipleAsync("p_GameFest_Events_AllSchedule", new { },
commandType: CommandType.StoredProcedure);
ScheduleTimeTableDto Schedule = new ScheduleTimeTableDto();
try
{
var holdings = (await data.ReadAsync<ScheduleHoldingDto>()).ToList();
if (holdings == null)
{
// handle null value
Console.WriteLine("holdings is null");
}
else
{
List<EventHoldingDto> hl = new List<EventHoldingDto>();
foreach (var evnt in holdings)
{
hl.Add(new EventHoldingDto
{
HoldingCode = evnt.HoldingCode,
EventID = evnt.EventID,
StartDate = DateTimeConverter.ConvertToDateTime(evnt.StartDate),
Status = evnt.Status,
OrgFirstName = evnt.OrgFirstName,
EventTitle = evnt.EventTitle,
ShortDesc = evnt.ShortDesc,
StatusTitle = StatusComponents.ShowStatusTitle(evnt.Status, "holding"),
EndDate = DateTimeConverter.ConvertToDateTime(evnt.EndDate),
OrgImageUrl = evnt.OrgImageUrl,
OrgLastName = evnt.OrgLastName,
ParticipantQty = evnt.ParticipantQty,
OrganizerID = evnt.OrganizerID,
PlayerQty = evnt.ParticipantQty - evnt.PlayerQty
});
}
Schedule.Holdings = hl;
}
if (Schedule != null)
{
await Clients.All.SendAsync("updateSchedule", Schedule);
}
else
{
await Clients.All.SendAsync("showErrorMessage", "خطا در بروزرسانی برنامهزمانی رخ داده است.");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
await Clients.Caller.SendAsync("showErrorMessage", ex.Message);
}
}
private async Task CallUpdateSchedule()
{
using (var hub = new BtlNetHub(_db, _config))
{
if (hub != null && _timer.Enabled)
{
await hub.UpdateSchedule();
}
}
}
private void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
try
{
// update the schedule on the client
_ = CallUpdateSchedule();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
}
}
}
await Clients.All.SendAsync("updateSchedule", Schedule);
this code got error null exception and i am sure that Schedule is not null and something wrong with Clinets .
this function call every less than 60 second and couldn't send data to client(My cshtml page via javascript)
please give me someway to figure it out thanks
</details>
# 答案1
**得分**: 0
如我所说,客户端对象等于null,与数据计划无关。这就是为什么我要找出这是为什么发生的原因。
结果,我意识到我应该为具有上下文的客户端使用IHubContext接口。
```csharp
public BtlNetHub(ApplicationDbContext db, IConfiguration config, IHubContext<BtlNetHub> hubContext)
{
_db = db;
_config = config;
_hubContext = hubContext;
// 设置计时器
_timer = new Timer();
_timer.Interval = IntervalInMilliseconds;
_timer.Elapsed += _timer_Elapsed;
_timer.Enabled = true;
}
public void Dispose()
{
_timer?.Dispose();
}
private const int IntervalInMilliseconds = 60000;
// 将方法定义为终端点
[HubMethodName("updateSchedule")]
public async Task UpdateSchedule()
{
using IDbConnection connection = new SqlConnection(_config.GetConnectionString("GameFestConnection"));
using var data = await connection.QueryMultipleAsync("p_GameFest_Events_AllSchedule", new { },
commandType: CommandType.StoredProcedure);
ScheduleTimeTableDto Schedule = new ScheduleTimeTableDto();
try
{
var holdings = (await data.ReadAsync<ScheduleHoldingDto>()).ToList();
if (holdings == null)
{
// 处理null值
Console.WriteLine("holdings is null");
}
else
{
List<EventHoldingDto> hl = new List<EventHoldingDto>();
foreach (var evnt in holdings)
{
hl.Add(new EventHoldingDto
{
HoldingCode = evnt.HoldingCode,
EventID = evnt.EventID,
StartDate = DateTimeConverter.ConvertToDateTime(evnt.StartDate),
Status = evnt.Status,
OrgFirstName = evnt.OrgFirstName,
EventTitle = evnt.EventTitle,
ShortDesc = evnt.ShortDesc,
StatusTitle = StatusComponents.ShowStatusTitle(evnt.Status, "holding"),
EndDate = DateTimeConverter.ConvertToDateTime(evnt.EndDate),
OrgImageUrl = evnt.OrgImageUrl,
OrgLastName = evnt.OrgLastName,
ParticipantQty = evnt.ParticipantQty,
OrganizerID = evnt.OrganizerID,
PlayerQty = evnt.ParticipantQty - evnt.PlayerQty
});
}
Schedule.Holdings = hl;
}
if (Schedule != null)
{
await _hubContext.Clients.All.SendAsync("updateSchedule", Schedule);
}
else
{
await Clients.All.SendAsync("showErrorMessage", "Error");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
await _hubContext.Clients.All.SendAsync("showErrorMessage", ex.Message);
}
}
英文:
As I said, the client object was equal to null and had nothing to do with the data schedule. That's why I looked for why this happens.
As a result, I realized that I should use the IHubContext interface for clients that are context
public BtlNetHub(ApplicationDbContext db, IConfiguration config,IHubContext<BtlNetHub> hubContext)
{
_db = db;
_config = config;
_hubContext = hubContext;
// set up the timer
_timer = new Timer();
_timer.Interval = IntervalInMilliseconds;
_timer.Elapsed += _timer_Elapsed;
_timer.Enabled = true;
}
public void Dispose()
{
_timer?.Dispose();
}
private const int IntervalInMilliseconds = 60000;
// define method as an endpoint
[HubMethodName("updateSchedule")]
public async Task UpdateSchedule()
{
using IDbConnection connection = new SqlConnection(_config.GetConnectionString("GameFestConnection"));
using var data = await connection.QueryMultipleAsync("p_GameFest_Events_AllSchedule", new { },
commandType: CommandType.StoredProcedure);
ScheduleTimeTableDto Schedule = new ScheduleTimeTableDto();
try
{
var holdings = (await data.ReadAsync<ScheduleHoldingDto>()).ToList();
if (holdings == null)
{
// handle null value
Console.WriteLine("holdings is null");
}
else
{
List<EventHoldingDto> hl = new List<EventHoldingDto>();
foreach (var evnt in holdings)
{
hl.Add(new EventHoldingDto
{
HoldingCode = evnt.HoldingCode,
EventID = evnt.EventID,
StartDate = DateTimeConverter.ConvertToDateTime(evnt.StartDate),
Status = evnt.Status,
OrgFirstName = evnt.OrgFirstName,
EventTitle = evnt.EventTitle,
ShortDesc = evnt.ShortDesc,
StatusTitle = StatusComponents.ShowStatusTitle(evnt.Status, "holding"),
EndDate = DateTimeConverter.ConvertToDateTime(evnt.EndDate),
OrgImageUrl = evnt.OrgImageUrl,
OrgLastName = evnt.OrgLastName,
ParticipantQty = evnt.ParticipantQty,
OrganizerID = evnt.OrganizerID,
PlayerQty = evnt.ParticipantQty - evnt.PlayerQty
});
}
Schedule.Holdings = hl;
}
if (Schedule != null)
{
await _hubContext.Clients.All.SendAsync("updateSchedule", Schedule);
}
else
{
await Clients.All.SendAsync("showErrorMessage", "Error");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
await _hubContext.Clients.All.SendAsync("showErrorMessage", ex.Message);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论