c# - 第一次在 Blazor 服务器端应用程序中调用 Web API 不起作用
问题描述
当我启动我的 ASP.Net Core Blazor 服务器端应用程序时,我第一次单击保存按钮时,没有任何反应。发送到控制器/API 的帖子会触发,但我的控制器/API 中的 PostListing 函数永远不会被调用。但是,如果我在之后第二次单击“保存”按钮,它会按预期工作。这是怎么回事?感谢任何可以提供帮助的人。
这是我的页面:
@page "/fetchdata"
@using SellEverywhere.Data
@using SellEverywhere.Models
@using System.Net.Http.Json
@inject HttpClient Http
<h1>Your Listings</h1>
<table width="100%" style="background:#05163D;color:honeydew">
<tr>
<td width="20"> </td>
<td>
<h2> Add New Listing Details</h2>
</td>
<td> </td>
<td align="right">
<button class="btn btn-info" @onclick="AddNewListing">Add New Listing</button>
</td>
<td width="10"> </td>
</tr>
<tr>
<td colspan="2"></td>
</tr>
</table>
<hr />
<form>
<table class="form-group">
<tr>
<td>
<label for="Name" class="control-label">ID</label>
</td>
<td>
<input type="text" class="form-control" @bind="@lsts.Id" readonly />
</td>
<td width="20"> </td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Title</label>
</td>
<td>
<input type="text" class="form-control" @bind="@lsts.Title" />
</td>
<td width="20"> </td>
<td>
<label for="Description" class="control-label">Description</label>
</td>
<td>
<input type="text" class="form-control" @bind="@lsts.Description" />
</td>
<td width="20"> </td>
<td>
<label for="Name" class="control-label">Brand</label>
</td>
<td>
<input type="text" class="form-control" @bind="@lsts.Brand" />
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Size</label>
</td>
<td>
<input type="text" class="form-control" @bind="@lsts.Size" />
</td>
<td width="20"> </td>
<td>
<label for="Name" class="control-label">Color</label>
</td>
<td>
<input type="text" class="form-control" @bind="@lsts.Color" />
</td>
<td width="20"> </td>
<td>
<label for="Name" class="control-label">Condition</label>
</td>
<td>
<input type="text" class="form-control" @bind="@lsts.Condition" />
</td>
<td width="20"> </td>
<td></td>
<td>
<button type="submit" class="btn btn-success" @onclick="(async () => await AddListing())" style="width:220px;">Save</button>
</td>
</tr>
</table>
</form>
<table width="100%" style="background:#0A2464;color:honeydew">
<tr>
<td width="20"> </td>
<td>
<h2>Listing Details</h2>
</td>
</tr>
<tr>
<td colspan="2"></td>
</tr>
</table>
@if (listing == null)
{
<p><em>No listing found...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>Brand</th>
<th>Color</th>
<th>Condition</th>
<th>Size</th>
<th>Description</th>
<th>Tag1</th>
<th>Tag2</th>
<th>Tag3</th>
<th>Price</th>
<th>Lowest Price</th>
<th>Shipping Price</th>
</tr>
</thead>
<tbody>
@foreach (var lst in listing)
{
<tr>
<td>@lst.Id</td>
<td>@lst.Title</td>
<td>@lst.Brand</td>
<td>@lst.Color</td>
<td>@lst.Condition</td>
<td>@lst.Size</td>
<td>@lst.Description</td>
<td>@lst.Tag1</td>
<td>@lst.Tag2</td>
<td>@lst.Tag3</td>
<td>@lst.Price</td>
<td>@lst.LowestPrice</td>
<td>@lst.ShippingPrice</td>
<td><button class="btn btn-primary" @onclick="@(async () => await EditListing(@lst.Id))" style="width:110px;">Edit</button></td>
<td><button class="btn btn-danger" @onclick="@(async () => await DeleteListing(@lst.Id))">Delete</button></td>
</tr>
}
</tbody>
</table>
}
@code {
Listing[] listing;
Listing lsts = new Listing();
string ids = "0";
//bool showAddrow = false;
protected override async Task OnInitializedAsync()
{
listing = await Http.GetFromJsonAsync<Listing[]>("https://localhost:44324/api/Listings/");
}
void AddNewListing()
{
lsts = new Listing();
}
// Add New Listings Details Method
protected async Task AddListing()
{
if (lsts.Id == 0)
{
await Http.PostAsJsonAsync("https://localhost:44324/api/Listings/", lsts);
}
else
{
await Http.PutAsJsonAsync("https://localhost:44324/api/Listings/" + lsts.Id, lsts);
}
lsts = new Listing();
listing = await Http.GetFromJsonAsync<Listing[]>("https://localhost:44324/api/Listings/");
}
// Edit Method
protected async Task EditListing(int listingID)
{
ids = listingID.ToString();
lsts = await Http.GetFromJsonAsync<Listing>("https://localhost:44324/api/Listings/" + Convert.ToInt32(listingID));
}
// Delete Method
protected async Task DeleteListing(int listingID)
{
ids = listingID.ToString();
await Http.DeleteAsync("https://localhost:44324/api/Listings/" + Convert.ToInt32(listingID));
listing = await Http.GetFromJsonAsync<Listing[]>("https://localhost:44324/api/Listings/");
}
}
这是我的控制器/API:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using SellEverywhere.Data;
using SellEverywhere.Models;
namespace SellEverywhere.Controllers
{ [Produces("application/json")]
[Route("api/[controller]")]
[ApiController]
public class ListingsController : ControllerBase
{
private readonly ApplicationDbContext _context;
public ListingsController(ApplicationDbContext context)
{
_context = context;
}
// GET: api/Listings
[HttpGet]
public async Task<ActionResult<IEnumerable<Listing>>> GetListing()
{
return await _context.Listing.ToListAsync();
}
// GET: api/Listings/5
[HttpGet("{id}")]
public async Task<ActionResult<Listing>> GetListing(int id)
{
var listing = await _context.Listing.FindAsync(id);
if (listing == null)
{
return NotFound();
}
return listing;
}
// PUT: api/Listings/5
// To protect from overposting attacks, enable the specific properties you want to bind to, for
// more details, see https://go.microsoft.com/fwlink/?linkid=2123754.
[HttpPut("{id}")]
public async Task<IActionResult> PutListing(int id, Listing listing)
{
if (id != listing.Id)
{
return BadRequest();
}
_context.Entry(listing).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ListingExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
// POST: api/Listings
// To protect from overposting attacks, enable the specific properties you want to bind to, for
// more details, see https://go.microsoft.com/fwlink/?linkid=2123754.
[HttpPost]
public async Task<ActionResult<Listing>> PostListing(Listing listing)
{
listing.UserId = User.FindFirstValue(ClaimTypes.NameIdentifier);
_context.Listing.Add(listing);
await _context.SaveChangesAsync();
return CreatedAtAction("GetListing", new { id = listing.Id }, listing);
}
// DELETE: api/Listings/5
[HttpDelete("{id}")]
public async Task<ActionResult<Listing>> DeleteListing(int id)
{
var listing = await _context.Listing.FindAsync(id);
if (listing == null)
{
return NotFound();
}
_context.Listing.Remove(listing);
await _context.SaveChangesAsync();
return listing;
}
private bool ListingExists(int id)
{
return _context.Listing.Any(e => e.Id == id);
}
}
}
这是我的模型:
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace SellEverywhere.Models
{
public class Listing
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public int Id { get; set; }
public string UserId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Color { get; set; }
public string Condition { get; set; }
public string Brand { get; set; }
public string Type { get; set; }
public string Size { get; set; }
public string Tag1 { get; set; }
public string Tag2 { get; set; }
public string Tag3 { get; set; }
public int Price { get; set; }
public int LowestPrice { get; set; }
public int ShippingPrice { get; set; }
public ICollection<Photos> Photos { get; set; }
}
public class Photos
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public int Id { get; set; }
//[ForeignKey("Listing")]
public int ListingId { get; set; }
public byte[] Image { get; set; }
public virtual Listing Listing { get; set; }
}
}
解决方案
“提交”按钮在执行时会将表单数据提交到服务器,对吗?这是你的意图吗?我猜不是......您实际上想要调用 AddListing 方法,您可以从该方法执行对 Web Api 端点的 HTTP Fetch API(HttpClient 服务)调用,而不是执行表单数据的传统发布请求,这不会存在于SPA应用领域。因此,您应该使用不执行发布请求的类型的按钮,而只调用您的 AddListing 方法...
注意:在 Blazor 开发的早期阶段,Blazor JS 代码包含简单地取消“提交”请求的代码。
对于像您这样的任务,您应该使用 EditForm 组件和 Blazor Forms 组件,例如 InputText 等。在这种情况下,您可以使用“提交”按钮,其提交操作会被框架自动取消。
推荐阅读
- haskell - 具有多种类型的递归方案
- python - 需要在带有滚动条的ttk笔记本中安装鼠标滚轮
- javascript - 使用 Javascript 隐藏具有特定类的 HTML 元素,除非 URL 参数存在
- lua - Checking if an instance *doesn't* exist -> "Not a valid member"
- php - 如何在 php 中使用正则表达式搜索 XML 文件
- javascript - javascript exception in while controller in jmeter
- google-cloud-platform - 我们可以在 ParDo 函数中编写 ParDo 函数吗?
- marklogic - MarkLogic DHF 协调流程失败
- python - How to replace or modify a Tornado Handler at runtime?
- cakebuild - Cake Task output log to file