在 Razor 页面中调用操作

Posted

技术标签:

【中文标题】在 Razor 页面中调用操作【英文标题】:Calling Action in Razor Pages 【发布时间】:2019-05-22 12:42:24 【问题描述】:

作为 Razor Pages 的新手,我有一个关于从 Razor Page 调用方法的问题。

我的域模型中定义了一个名为subtractProduct 的方法。

在我的索引页面代码中,我定义了 IActionResult sellProduct,它在指定的 ProductId 上调用了 subproduct。但我不知道如何在我的 html 页面上调用此方法。我尝试了很多组合,但似乎没有任何效果。任何人都知道如何处理这个问题?非常感谢任何帮助!

我的领域模型是:

public class Product


    public int ProductId  get; set; 
    public int Quantity  get; set;    
    ...
    public void SubtractProduct()
    
        Quantity -= 1;
    

我的索引页面代码是:

public class IndexModel : PageModel

    private readonly CfEshop.Data.ApplicationDbContext _context;

    public IndexModel(CfEshop.Data.ApplicationDbContext context)
    
        _context = context;
    

    public IList<Models.Product> Product  get;set; 

    public async Task OnGetAsync()
    
        Product = await _context.Products
            .Include(p => p.Categories).ToListAsync();
    

    public IActionResult sellProduct(int id)
    
        var products = _context.Products;

        _context.Products.Find(id).SubtractProduct();
        return Page();
    

最后是我的 Razor 页面:

@page
@model CfEshop.Pages.Product.IndexModel
<h2>Index</h2>

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Product[0].Quantity)
            </th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Product)
        
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Quantity)
                </td>
                <td>
                    <a asp-page-handler="SellProduct" asp-route="@item.ProductId">Sell Product</a>
                </td>
            </tr>
        
    </tbody>
</table>

【问题讨论】:

【参考方案1】:

Razor 页面有 handler-methods,它们是 HTTP 动词。因此,要从您的页面调用方法,您需要输入On,然后是the http verb you want,然后是您的method name

例如:

public IActionResult OnGetSellProduct(int id)

    var products = _context.Products;

    _context.Products.Find(id).SubtractProduct();
    return Page();

在您看来,将名称传递给asp-page-handler,不带OnPost or OnGet 前缀或Async 后缀。

编辑:这是视图示例:

<a asp-page-handler="SellProduct" asp-route-id="@item.ProductId">Sell Product</a>

欲了解更多信息,请查看:

Introduction to Razor Pages.

Razor Pages Handler Methods.

【讨论】:

在我将视图更改为 销售产品 我收到此错误:InvalidOperationException:无法确定 的“href”属性。以下属性互斥:asp-route asp-controller, asp-action asp-page, asp-page-handler Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper.Process(TagHelperContext context, TagHelperOutput output) 你的 应该是这样的:销售产品,你需要添加asp-route-id 以匹配您的操作id 中的参数。 我将视图示例添加到答案中。请尝试一下。 谢谢它有效 - 我现在的方法是: public async Task OnGetSellProductAsync(int id) _context.Products.Find(id).SubtractProduct();等待 _context.SaveChangesAsync();产品 = 等待 _context.Products .Include(p => p.Categories).ToListAsync();但现在我面临另一个问题 - 每当我在调用此方法后按 F5 时,我的 Quantity 都会再次减去 :)。在我的网址中有localhost:44321/Product?id=55&handler=SellProduct 有没有办法重置它?比如动作重定向什么的? 您可以使用return RedirectToPage();返回当前页面。通常应该通过 Post HTTP 动词提交表单来更改数据库或值。【参考方案2】:

添加以下 tagHelper 和用户 asp-action="@Model.ReturnUrl" 以解析 Razor 页面中调用操作的 url

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

【讨论】:

以上是关于在 Razor 页面中调用操作的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Razor 页面中调用 onPost

YbSoftwareFactory 代码生成插件二十五:Razor视图中以全局方式调用后台方法输出页面代码的三种方法

如何以 10 秒的间隔在 mvc razor 页面中使用 jQuery 调用方法并将输出附加到 html

如何从服务器端 Blazor 应用程序中的 Blazor 组件调用 razor 页面而不导致页面刷新

在 ASP.NET MVC 中:从 Razor 视图调用控制器操作方法的所有可能方式

当 API 调用完成时,如何从 .RAZOR 主页面中的所有子组件触发/刷新我的主 .RAZOR 页面?