Update record in grid does not not work with WebApiAdaptor
I have an issue in syncfusion blazor grid , that i am binding using Adaptor="Adaptors.WebApiAdaptor for SfDataManager
Query 2:
I have a production WebApi and all the Get methods in its controllers return the data count in a property named "TotalCount" but your grid requires it to be named "Count"
I cannot modify the code of this API as it is production and used by other apps but I want to map this property "TotalCount" to your property "Count" in order for the paging of the grid to work directly
----------------------------------------------------------------
|
<SfGrid TValue="Orders" AllowFiltering="true" Toolbar="@(new List<string> {"Add","Edit","Delete","Update","Cancel","Search" })" AllowSorting="true" AllowPaging="true">
<GridFilterSettings Type="Syncfusion.Blazor.Grids.FilterType.Menu"></GridFilterSettings>
<SfDataManager AdaptorInstance="@typeof(CustomAdaptor)" Adaptor="Adaptors.CustomAdaptor"></SfDataManager>
<GridEditSettings AllowAdding="true" AllowDeleting="true" AllowEditing="true"></GridEditSettings>
<GridColumns>
<GridColumn Field="OrderID" HeaderText="Order ID" IsPrimaryKey="true" TextAlign="TextAlign.Right" Width="120"></GridColumn>
. . .
</GridColumns>
</SfGrid>
@code{
static OrderService Ord { get; set; }
protected override void OnInitialized()
{
Ord = OrderData;
}
// Implementing custom adaptor by extending the DataAdaptor class
public class CustomAdaptor : DataAdaptor
{
// Performs data Read operation
public override async Task<object> ReadAsync(DataManagerRequest dm, string key = null)
{
IEnumerable<Orders> DataSource = await Ord.GetPeople();
. . .
return dm.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource;
}
//// Performs Insert operation
public override async Task<object> InsertAsync(DataManager dm, object value, string key)
{
await Ord.InsertOrderAsync(value as Orders);
return value;
}
//// Performs Remove operation
public override async Task<object> RemoveAsync(DataManager dm, object value, string keyField, string key)
{
await Ord.DeleteOrderAsync(value.ToString());
return value;
}
//// Performs Update operation
public override async Task<object> UpdateAsync(DataManager dm, object value, string keyField, string key)
{
await Ord.UpdateOrderAsync((value as Orders).OrderID.ToString(), value as Orders);
return value;
}
}
} |
Many thanks for your reply
For Query 2, Does this mean that I can not inject the HttpClient directly in the page without using an extra service class. I want to minimize the code written for these simple crud operations, for best code maintainability. Please confirm. Note I my project is Blazor WASM based project, not Blazor Server project
|
. . .
@inject HttpClient Http
<SfGrid TValue="Orders" AllowFiltering="true" Toolbar="@(new List<string> {"Add","Edit","Delete","Update","Cancel","Search" })" AllowSorting="true" AllowPaging="true">
<GridFilterSettings Type="Syncfusion.Blazor.Grids.FilterType.Menu"></GridFilterSettings>
<SfDataManager AdaptorInstance="@typeof(CustomAdaptor)" Adaptor="Adaptors.CustomAdaptor"></SfDataManager>
. . .
</SfGrid>
@code{
static HttpClient http { get; set; }
protected override void OnInitialized()
{
http = Http;
}
// Implementing custom adaptor by extending the DataAdaptor class
public class CustomAdaptor : DataAdaptor
{
// Performs data Read operation
public override async Task<object> ReadAsync(DataManagerRequest dm, string key = null)
{
//var orddata = await http.GetJsonAsync<List<Orders>>("api/Default");
IEnumerable<Orders> DataSource = await http.GetJsonAsync<List<Orders>>("api/Default");
. . .
}
//// Performs Insert operation
public override async Task<object> InsertAsync(DataManager dm, object value, string key)
{
await http.PostJsonAsync("api/Default/", value as Orders);
return value;
}
//// Performs Remove operation
public override async Task<object> RemoveAsync(DataManager dm, object value, string keyField, string key)
{
await http.DeleteAsync("api/Default/" + value.ToString());
return value;
}
//// Performs Update operation
public override async Task<object> UpdateAsync(DataManager dm, object value, string keyField, string key)
{
await http.PutJsonAsync("api/Default/" + (value as Orders).OrderID, value as Orders);
return value;
}
}
} |
Thanks for your info. I have tried the crud using the "CustomAdaptor" and injected "HttpClient" and its ok
Query 3, I noticed that when editing a record in the grid and navigating to another row , the Update event is fired . I agree it should be fired with "Enter" key press only but others should be disable even using an option Can this behavior be changed?
Attachment: BlazorApp_DataGridUpdateWithApi_Issue_850a29d0.zip
|
<SfGrid TValue="Orders" AllowFiltering="true" Toolbar="@(new List<string> { "Add", "Edit", "Delete", "Update", "Cancel", "Search" })" AllowSorting="true" AllowPaging="true">
<GridFilterSettings Type="Syncfusion.Blazor.Grids.FilterType.Menu"></GridFilterSettings>
<SfDataManager Url="https://localhost:44354/api/Default/"
UpdateUrl="https://localhost:44354/api/Default/" Adaptor="Adaptors.WebApiAdaptor"></SfDataManager> //remove this
<GridEditSettings AllowAdding="true" AllowDeleting="true" AllowEditing="true" Mode="EditMode.Dialog"></GridEditSettings>
<GridColumns>
<GridColumn Field="OrderID" HeaderText="Order ID" IsPrimaryKey="true" TextAlign="TextAlign.Right" Width="120"></GridColumn>
<GridColumn Field="CustomerID" HeaderText="Customer Name" Width="150"></GridColumn>
<GridColumn Field="Freight" HeaderText="Freight" Format="C2" TextAlign="TextAlign.Right" EditType="EditType.NumericEdit" Width="120"></GridColumn>
<GridColumn Field="OrderDate" HeaderText="Freight" TextAlign="TextAlign.Right" EditType="EditType.DatePickerEdit" Type="ColumnType.DateTime" Width="120"></GridColumn>
</GridColumns>
</SfGrid>
@code{ |
|
//PUT: api/Default1/5
[HttpPut("{id}")]
public object Put(int id, [FromBody] Orders value) //remove the highlighted codes. You don’t need to pass id
{
var data = order.Where(or => or.OrderID == value.OrderID).FirstOrDefault();
. . .
return value;
} |
- Whether did you want to cancel the previously edited record state while clicking other rows?
- Whether did you want to stay the edited state while clicking other rows?
- For my CRUD query using API, it is OK
- For the Grid editing , when the user clicks in other rows I suggest to add an option for grid contains both the following values:
- cancel the previously edited record
- stay the edited state
|
<SfGrid DataSource="@Orders" AllowPaging="true" Toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Cancel", "Update" })" Height="315">
<GridEditSettings AllowAdding="true" AllowEditing="true" AllowDeleting="true" Mode="EditMode.Normal"></GridEditSettings>
<GridEvents OnToolbarClick="ToolbarClickHandler" OnActionBegin="ActionBeginHandler" OnRecordClick="RecordClickHandler" TValue="Order"></GridEvents>
<GridColumns>
<GridColumn Field=@nameof(Order.OrderID) HeaderText="Order ID" IsPrimaryKey="true" ValidationRules="@(new ValidationRules{ Required=true})"
TextAlign="TextAlign.Right" Width="120"></GridColumn>
. . .
</GridColumns>
</SfGrid>
@code{
public List<Order> Orders { get; set; }
bool save = false; //introducing Boolean value to achieve the requirement
. . .
public void RecordClickHandler(RecordClickEventArgs<Order> args)
{
save = true;
}
public void ActionBeginHandler(ActionEventArgs<Order> args)
{
if (save && args.RequestType == Syncfusion.Blazor.Grids.Action.Save)
{
args.Cancel = true; //cancelling save action while clicking other rows
}
}
public void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args)
{
if(args.Item.Text == "Update")
{
save = false;
}
}
}
|
Hi, I've tried the sample provided, the update works find when the Mode="EditMode.Normal" or Mode="EditMode.Dialog" in GridEditSettings .
However when I changed the
Mode="EditMode.Batch" in
GridEditSettings
it doesn't update anymore, am I missing something?
<SfGrid TValue="Orders" AllowFiltering="true" Toolbar="@(new List<string> { "Add", "Edit", "Delete", "Update", "Cancel", "Search" })" AllowSorting="true" AllowPaging="true">
<GridFilterSettings Type="Syncfusion.Blazor.Grids.FilterType.Menu"></GridFilterSettings>
<SfDataManager Url="https://localhost:44354/api/Default/" Adaptor="Adaptors.WebApiAdaptor"></SfDataManager>
<GridEditSettings AllowAdding="true" AllowDeleting="true" AllowEditing="true" Mode="EditMode.Batch"></GridEditSettings>
<GridColumns>
<GridColumn Field="OrderID" HeaderText="Order ID" IsPrimaryKey="true" TextAlign="TextAlign.Right" Width="120"></GridColumn>
<GridColumn Field="CustomerID" HeaderText="Customer Name" Width="150"></GridColumn>
<GridColumn Field="Freight" HeaderText="Freight" Format="C2" TextAlign="TextAlign.Right" EditType="EditType.NumericEdit" Width="120"></GridColumn>
<GridColumn Field="OrderDate" HeaderText="Freight" TextAlign="TextAlign.Right" EditType="EditType.DatePickerEdit" Type="ColumnType.DateTime" Width="120"></GridColumn>
</GridColumns>
</SfGrid>
Regards,
Alvin
Hi Alvin,
Greetings from Syncfusion support.
We checked your query and you are using WebApiAdaptor to bind data from Web API service to grid. When performing batch add/update/delete actions, the batch request will be send along with selected records. But unfortunately the ASP.NET Core Web API with batch is not yet supported by ASP.NET Core v3+. Hence it is not feasible from us to support batch edit with Web API, until ASP.NET Core provide the support for the proper batch handler.
Please find the general GitHub link below.
GitHub Link : https://github.com/aspnet/AspNetCore/issues/14722
Please get back to us if you need further assistance.
Regards,
Naveen Palanivel
- 9 Replies
- 4 Participants
- Marked answer
-
MO Mohamed
- Jun 6, 2020 07:52 AM UTC
- Aug 30, 2022 12:41 AM UTC