Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions BootstrapBlazor.Extensions.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
<Project Path="src/components/BootstrapBlazor.FontAwesome/BootstrapBlazor.FontAwesome.csproj" />
<Project Path="src/components/BootstrapBlazor.Gantt/BootstrapBlazor.Gantt.csproj" />
<Project Path="src/components/BootstrapBlazor.Graph/BootstrapBlazor.Graph.csproj" />
<Project Path="src/components/BootstrapBlazor.HikVision/BootstrapBlazor.HikVision.csproj" Id="62fa4e31-4a04-4c99-9074-3ea0c037e244" />
<Project Path="src/components/BootstrapBlazor.Holiday/BootstrapBlazor.Holiday.csproj" />
<Project Path="src/components/BootstrapBlazor.Html2Image/BootstrapBlazor.Html2Image.csproj" />
<Project Path="src/components/BootstrapBlazor.Html2Pdf.Playwright/BootstrapBlazor.Html2Pdf.Playwright.csproj" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<Version>10.0.0-beta01</Version>
</PropertyGroup>

<PropertyGroup>
<PackageTags>Bootstrap Blazor WebAssembly wasm UI Components Graph</PackageTags>
<Description>Bootstrap UI components extensions of Graph</Description>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BootstrapBlazor" Version="$(BBVersion)" />
</ItemGroup>

<ItemGroup>
<Using Include="Microsoft.JSInterop" />
</ItemGroup>

</Project>
3 changes: 3 additions & 0 deletions src/components/BootstrapBlazor.HikVision/Component1.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div class="my-component">
This component is defined in the <strong>BootstrapBlazor.HikVision</strong> library.
</div>
Comment on lines +1 to +3
Copy link

Copilot AI Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These appear to be template files from a component library scaffold that are not relevant to the HikVision component. They should be removed as they are unused and add unnecessary files to the project.

Suggested change
<div class="my-component">
This component is defined in the <strong>BootstrapBlazor.HikVision</strong> library.
</div>

Copilot uses AI. Check for mistakes.
6 changes: 6 additions & 0 deletions src/components/BootstrapBlazor.HikVision/Component1.razor.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.my-component {
border: 2px dashed red;
padding: 1em;
margin: 1em 0;
background-image: url('background.png');
}
Comment on lines +1 to +6
Copy link

Copilot AI Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This CSS file references a non-existent 'background.png' file and appears to be a template file that's unused by the actual HikVision component. It should be removed.

Suggested change
.my-component {
border: 2px dashed red;
padding: 1em;
margin: 1em 0;
background-image: url('background.png');
}

Copilot uses AI. Check for mistakes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@namespace BootstrapBlazor.Components
@inherits BootstrapModuleComponentBase

<div @attributes="AdditionalAttributes" class="@ClassString" id="@Id">
<div id="@PreviewId" class="bb-hik-preview" style="width: 500px; height: 300px;"></div>
<div class="bb-hik-controls">
<button class="btn btn-primary bb-hik-login">
<span>登录</span>
</button>
<button class="btn btn-primary bb-hik-logout">
<span>退出</span>
</button>
<button class="btn btn-primary bb-hik-start">
<span>开始预览</span>
</button>
<button class="btn btn-primary bb-hik-stop">
<span>停止预览</span>
</button>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/

namespace BootstrapBlazor.Components;

/// <summary>
/// 海康威视网络摄像机组件
/// </summary>
[JSModuleAutoLoader("./_content/BootstrapBlazor.HikVision/Components/HikVision.razor.js")]
public partial class HikVision
{
private string PreviewId => $"{Id}_preview";

private string? ClassString => CssBuilder.Default("bb-hik")
.AddClassFromAttributes(AdditionalAttributes)
.Build();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { init as initVision, login, logout, startRealPlay, stopRealPlay, dispose as disposeVision } from '../hikvision.js';
import EventHandler from '../../BootstrapBlazor/modules/event-handler.js';

export async function init(id) {
const el = document.getElementById(id);
if (el === null) {
return;
}

const previewId = `${id}_preview`;
await initVision(previewId);

const controls = el.querySelector('.bb-hik-controls');
if (controls) {
EventHandler.on(controls, 'click', '.bb-hik-login', async e => {
console.log('login');
await login(previewId, '47.121.113.151', 9980, 'admin', 'vhbn8888', 1)
Copy link

Copilot AI Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded credentials detected in production code. The IP address '47.121.113.151', port '9980', username 'admin', and password 'vhbn8888' should not be hardcoded in the JavaScript file. These credentials should be passed as parameters from the C# component or removed entirely if this is test/demo code. This is a serious security vulnerability that exposes the credentials to anyone who can access the client-side JavaScript.

Copilot uses AI. Check for mistakes.
});
EventHandler.on(controls, 'click', '.bb-hik-logout', e => {
console.log('logout');
logout(previewId);
});
EventHandler.on(controls, 'click', '.bb-hik-start', e => {
console.log('start');
startRealPlay(previewId);
});
EventHandler.on(controls, 'click', '.bb-hik-stop', e => {
console.log('stop');
stopRealPlay(previewId);
});
}
}

export function dispose(id) {
const el = document.getElementById(id);
if (el !== null) {
const controls = el.querySelector('.bb-hik-controls');
if (controls) {
EventHandler.off(controls, 'click');
}
}

const previewId = `${id}_preview`;
disposeVision(previewId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/

using BootstrapBlazor.Components;
using Microsoft.Extensions.DependencyInjection.Extensions;

namespace Microsoft.Extensions.DependencyInjection;

/// <summary>
/// BootstrapBlazor 服务扩展类
/// </summary>
public static class ServiceCollectionExtensions
{
/// <summary>
/// 增加海康威视网络摄像机 Web 服务
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
public static IServiceCollection AddBootstrapBlazorHikVision(this IServiceCollection services)
{
services.TryAddScoped<IHikVision, DefaultHicVision>();
Copy link

Copilot AI Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The service registration uses DefaultHicVision which has a typo in the class name (should be DefaultHikVision). This needs to be updated to match the corrected class name.

Suggested change
services.TryAddScoped<IHikVision, DefaultHicVision>();
services.TryAddScoped<IHikVision, DefaultHikVision>();

Copilot uses AI. Check for mistakes.
return services;
}
}
21 changes: 21 additions & 0 deletions src/components/BootstrapBlazor.HikVision/LoginType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/

namespace BootstrapBlazor.Components;

/// <summary>
/// 登录方式
/// </summary>
public enum LoginType
{
/// <summary>
/// http 方式
/// </summary>
Http = 1,

/// <summary>
/// https 方式
/// </summary>
Https = 2
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/

namespace BootstrapBlazor.Components;

sealed class DefaultHicVision(IJSRuntime jsRuntime) : IHikVision
Copy link

Copilot AI Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The class is named DefaultHicVision but the interface and all other related names use HikVision. This appears to be a typo - it should be DefaultHikVision to maintain consistency with the naming convention.

Suggested change
sealed class DefaultHicVision(IJSRuntime jsRuntime) : IHikVision
sealed class DefaultHikVision(IJSRuntime jsRuntime) : IHikVision

Copilot uses AI. Check for mistakes.
{
private JSModule _module = default!;
private bool _initialized;
private bool _logined;

public async Task<bool> Login(string ip, int port, string userName, string password, LoginType loginType = LoginType.Http)
{
await LoadAsync();

if (!_logined)
{
_logined = await _module.InvokeAsync<bool>("login", ip, port, userName, password, (int)loginType);
Copy link

Copilot AI Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method parameter order is inconsistent between the interface method signature Login(string ip, int port, string userName, string password, LoginType loginType) and the JavaScript invocation login(ip, port, userName, password, (int)loginType). However, looking at the JavaScript function in hikvision.js line 56, the signature is login(id, ip, port, userName, password, loginType). The id parameter is missing from the C# invocation on line 19, which will cause the parameters to be misaligned and the function to fail.

Suggested change
_logined = await _module.InvokeAsync<bool>("login", ip, port, userName, password, (int)loginType);
_logined = await _module.InvokeAsync<bool>("login", 0, ip, port, userName, password, (int)loginType);

Copilot uses AI. Check for mistakes.
}

return _logined;
}

public async Task<bool> Logout(string ip, int port)
{
if (_logined)
{
_logined = await _module.InvokeAsync<bool>("logout");
Copy link

Copilot AI Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logout method is missing the id parameter when invoking the JavaScript function. According to hikvision.js line 157, the logout function signature is logout(id), but the C# code on line 29 calls it without any parameters. This will cause the logout functionality to fail.

Suggested change
_logined = await _module.InvokeAsync<bool>("logout");
_logined = await _module.InvokeAsync<bool>("logout", ip);

Copilot uses AI. Check for mistakes.
}

return _logined;
Comment on lines +29 to +32
Copy link

Copilot AI Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Logout method returns the inverse of the expected result. When logout is successful (completed = true), _logined should be set to false, but the method returns _logined which would still be true. The logic should be: if logout succeeds, set _logined = false and return true (success), or return !_logined instead of _logined.

Suggested change
_logined = await _module.InvokeAsync<bool>("logout");
}
return _logined;
var completed = await _module.InvokeAsync<bool>("logout");
if (completed)
{
_logined = false;
return true;
}
else
{
return false;
}
}
return false;

Copilot uses AI. Check for mistakes.
}

public async Task StartRealPlay()
{
if (_logined)
{
await _module.InvokeVoidAsync("startRealPlay");
}
}

public async Task StopRealPlay()
{
if (_logined)
{
await _module.InvokeVoidAsync("stopRealPlay");
Comment on lines +35 to +47
Copy link

Copilot AI Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The startRealPlay and stopRealPlay methods are missing the id parameter when invoking their corresponding JavaScript functions. According to hikvision.js lines 178 and 218, both functions require an id parameter, but the C# code on lines 39 and 47 calls them without any parameters. This will cause these methods to fail.

Suggested change
public async Task StartRealPlay()
{
if (_logined)
{
await _module.InvokeVoidAsync("startRealPlay");
}
}
public async Task StopRealPlay()
{
if (_logined)
{
await _module.InvokeVoidAsync("stopRealPlay");
public async Task StartRealPlay(string id)
{
if (_logined)
{
await _module.InvokeVoidAsync("startRealPlay", id);
}
}
public async Task StopRealPlay(string id)
{
if (_logined)
{
await _module.InvokeVoidAsync("stopRealPlay", id);

Copilot uses AI. Check for mistakes.
}
}

private async Task LoadAsync()
{
if (!_initialized)
{
var module = await jsRuntime.InvokeAsync<IJSObjectReference>("import", "./_content/BootstrapBlazor.HikVision/hikvision.js");
_module = new JSModule(module);

_initialized = true;
}
}

public async ValueTask DisposeAsync()
{
if (_module != null)
{
await _module.InvokeVoidAsync("dispose");
await _module.DisposeAsync();
}
GC.SuppressFinalize(this);
}
}
42 changes: 42 additions & 0 deletions src/components/BootstrapBlazor.HikVision/Services/IHikVision.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/

namespace BootstrapBlazor.Components;

/// <summary>
/// 海康威视网络摄像机接口
/// </summary>
public interface IHikVision : IAsyncDisposable
{
/// <summary>
/// 登录方法
/// </summary>
/// <param name="loginType">登录方式 <see cref="LoginType"/> 实例</param>
/// <param name="ip">设备 Ip 地址</param>
/// <param name="port">设备端口</param>
/// <param name="userName">用户名</param>
/// <param name="password">密码</param>
/// <returns></returns>
Task<bool> Login(string ip, int port, string userName, string password, LoginType loginType = LoginType.Http);

/// <summary>
/// 登出方法
/// </summary>
/// <param name="ip">设备 Ip 地址</param>
/// <param name="port">设备端口</param>
/// <returns></returns>
Task<bool> Logout(string ip, int port);

/// <summary>
/// 开始实时预览画面方法
/// </summary>
/// <returns></returns>
Task StartRealPlay();

/// <summary>
/// 停止实时预览画面方法
/// </summary>
/// <returns></returns>
Task StopRealPlay();
}
1 change: 1 addition & 0 deletions src/components/BootstrapBlazor.HikVision/_Imports.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@using Microsoft.AspNetCore.Components.Web
Loading