You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET按钮OnClick事件报无法从'void'转换为'object'错误求助

错误原因

你当前的写法存在两个核心问题,直接触发编译错误:

  1. Razor视图中@开头的表达式会在服务端页面渲染阶段立即执行,而非等待用户在浏览器端点击按钮时触发。你写的@Like(item)会在页面生成HTML的时候直接调用返回值为void的Like方法,Razor引擎尝试将方法的void返回值渲染到onclick属性中时,就会抛出"Cannot convert from 'void' to 'object'"的错误。
  2. 原生HTML的onclick属性只能绑定浏览器端执行的JavaScript代码,无法直接关联服务端运行的C#方法。哪怕你绕过编译错误,实际效果也是页面渲染时就把所有遍历到的item都执行一遍点赞,等页面送到用户手里时,点赞数早就被改完了,点击按钮不会有任何服务端逻辑触发。

另外你把操作数据库的逻辑直接写在视图的内联代码块里,本身也是不符合分层规范的写法,会带来数据库上下文生命周期异常、代码难以维护的问题。

可行解决方法

根据你的交互需求二选一即可:

方案1:表单提交实现(无额外JS,适合简单场景)

把点赞逻辑从视图挪到对应的Razor Page的PageModel类中,通过表单POST请求触发服务端方法:

  1. 首先在PageModel中添加POST处理方法,注入数据库上下文:
public class LinkListModel : PageModel
{
    private readonly AppDbContext _context;
    public LinkListModel(AppDbContext context)
    {
        _context = context;
    }
    // 页面原有绑定Link列表的逻辑省略
    public IActionResult OnPostLike(int linkId)
    {
        var targetLink = _context.Links.FirstOrDefault(l => l.Id == linkId);
        if (targetLink != null)
        {
            targetLink.likes += 1;
            _context.SaveChanges();
        }
        // 操作完成后重定向回当前页面,避免重复提交
        return RedirectToPage();
    }
}
  1. 替换视图中的按钮代码,用表单包裹提交参数:
<form method="post" style="display:inline">
    <input type="hidden" name="linkId" value="@item.Id" />
    <button type="submit" asp-page-handler="Like">🚀 @item.likes</button>
</form>

注意:需要提前在Program.cs中注册Razor Pages服务与路由,即添加builder.Services.AddRazorPages()和app.MapRazorPages()配置,框架会自动处理防伪令牌验证,无需额外开发。

方案2:异步接口调用(无刷新交互,体验更好)

通过接口+前端JS实现点击后异步提交点赞请求,不需要整页刷新:

  1. 先写点赞接口,可以用最小API快速实现:
// Program.cs中添加接口路由
app.MapPost("/api/links/{linkId:int}/like", async (int linkId, AppDbContext _context) =>
{
    var targetLink = await _context.Links.FindAsync(linkId);
    if (targetLink == null) return Results.NotFound();
    targetLink.likes += 1;
    await _context.SaveChangesAsync();
    return Results.Ok(new { newLikeCount = targetLink.likes });
});
  1. 替换视图中的按钮代码,添加少量交互JS:
<button class="like-btn" data-link-id="@item.Id">
    🚀 <span class="like-count">@item.likes</span>
</button>

@section Scripts{
<script>
document.querySelectorAll('.like-btn').forEach(btn => {
    btn.addEventListener('click', async function() {
        const linkId = this.dataset.linkId;
        const countEle = this.querySelector('.like-count');
        // 简单防重复点击
        this.disabled = true;
        const resp = await fetch(`/api/links/${linkId}/like`, {method: 'POST'});
        if (resp.ok) {
            const data = await resp.json();
            countEle.textContent = data.newLikeCount;
        }
        this.disabled = false;
    })
})
</script>
}

提示:不要在视图层直接写数据库操作逻辑,视图只需要负责渲染UI,数据增删改逻辑统一放在PageModel、控制器或者业务服务层,能避免绝大多数生命周期、权限校验相关的bug。

内容的提问来源于stack exchange,提问作者CheckerPhil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 10:03:21