简体   繁体   中英

Blazor EditForm is submitted twice instead of once

UPDATED

I have an EditForm component(I missed some non-important stuff, so just to view important pieces of code), written like this below:

<EditForm Model="@product" OnValidSubmit=@(async () => await SaveProduct())>
  <div class="form-group row">
    <MatPaper Elevation="10" Rounded="true" Style="padding-left: 30px;">
        <div class="col-12 row">
            <label class="col-4 font-weight-bold">Caption:</label>
            <input @ref="firstNameTextBox" class="form-control col-12" @bind="product.Caption" placeholder="Caption" />
            &nbsp;<ValidationMessage For="@(() => product.Caption)" />
        </div>
        <br />
        <div class="col-12 row">
            <label class="col-4 font-weight-bold">Description:</label>
            <InputText class="form-control col-12" @bind-Value="product.Description" placeholder="Description" />
            &nbsp;<ValidationMessage For="@(() => product.Description)" />
        </div>
        <br />
        <div class="col-12 row">
            <label class="col-4 font-weight-bold">Price :</label>
            <InputNumber class="form-control col-12" @bind-Value="product.Price" placeholder="Price" />
            &nbsp;<ValidationMessage For="@(() => product.Price)" />
        </div>

        <div class="form-group row">
            <label for="department" class="col-sm-2 col-form-label">
                Brand:
            </label>
            <div class="col-sm-10">
                <InputSelect id="brandtype" @bind-Value="product.BrandTypeEID" class="form-control">
                    @foreach (var brand in Brands)
                    {
                        <option value="@brand.brandTypeEID">@brand.caption</option>
                    }
                </InputSelect>
            </div>
        </div>


        <br />

        @*<div class="col-12 row">
                <label class="col-4 font-weight-bold">Brand:</label>
                <SelectBrand OnChangeEvent="OnSelectBrandChange"></SelectBrand>
            </div>*@
    </MatPaper>

    <label class="col-2 font-weight-bold"></label>

    <MatPaper Elevation="10" Rounded="true" Style="padding-left: 40px; margin-left: 100px;">
        <label class="col-8 font-weight-bold">
            Categories:
            <CheckBoxList Data="@Categories"
                          TextField="@((item)=>item.Caption)"
                          ValueField="@((item)=>item.CategoryID)"
                          SelectedValues="@SelectedIdsCategory" />
        </label>
    </MatPaper>

    <label class="col-2 font-weight-bold"></label>

    <MatPaper Elevation="10" Rounded="true" Style="padding-left: 30px;">
        <label class="col-2 font-weight-bold"></label>
        <label class="col-2 font-weight-bold">Size types:</label>
        <CheckBoxList Data="@SizeTypes"
                      TextField="@((item)=>item.Caption)"
                      ValueField="@((item)=>item.SizeTypeEID)"
                      SelectedValues="@SelectedIdsSizeType" />
    </MatPaper>
</div>
<br />
<div>
    <h3>Upload PNG images</h3>

    <p>
        <InputFile OnChange="@OnInputFileChange" multiple />
    </p>

    @if (imageDataUrls.Count > 0)
    {
        <h4>Images</h4>

        <div class="card" style="width:30rem;">
            <div class="card-body">
                @foreach (var imageDataUrl in imageDataUrls)
                {
                    <img class="rounded m-1" src="@convertImageToDisplay(imageDataUrl.PictureDisplay)" />
                }
            </div>
        </div>
    }

</div>
<br />

<br />
<div class="col-12 row">
    <span class="col-2"></span>
    <input type="submit" class="form-control col-1 btn btn-primary" @onclick="(() => SaveProduct())" value="Save" />
    <span>&nbsp;</span>
    <input type="submit" class="form-control col-1 btn btn-primary" value="Clear" />
</div>
</EditForm>

And here it is a SaveProduct method:

private async Task SaveProduct()
{
   var productToSave = new ProductForCreationDto();
        
   //some logic 
   if (product.Uid is null)
      await apiCreateProductService.SaveAsync("product/CreateProduct", productToSave);
   else
      await apiCallService.UpdateAsync("product/", product.Uid, product);

   await LoadProducts();

   Result = true;
   IsVisible = true;

   var caption = product.Caption;


   RecordName = caption;

   product = new Product();

        
   await JSRuntime.InvokeVoidAsync("setFocusOnElement", firstNameTextBox);
}

The issue is like the SaveProduct method is called twice, not once. I have 2 same records in database. I think that problem lies on EditForm, but I couldn't get the solution for this problem. What could be a fix?

You have

<EditForm Model="@product" OnValidSubmit=@(async () => await SaveProduct())>

and

<input type="submit" class="..." @onclick="(() => SaveProduct())" value="Save" />

So yes, SaveProduct() will be called twice when you Submit. Both will be called.

The easy fix is to just omit the @onclick and let the EditForm handle it:

<input type="submit" class="..." value="Save" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM