Right now my CRUD doesn't work - buttons don't trigger my back-end methods. I can get it to trigger a OnBeginHandler in the razor component, but my DataManager using UrlAdaptor just doesn't want to talk to my EntityFramework Api, which is using a data context class. Nothing at all in network or console browser debugs. I thought I was following this documentation closely: https://blazor.syncfusion.com/documentation/datagrid/connecting-to-database/entityframework
But it seems like the alternate method/example here uses the WebApiAdaptor: https://blazor.syncfusion.com/documentation/datagrid/data-binding#entity-framework
and I guess I'm not understanding the difference as to why the first method isn't working for me (or maybe the second wouldn't either and I'm missing something obvious?)
My Api service: https://pastebin.com/gpQMffxZ
My razor component: https://pastebin.com/4iirQw6w
Hi
Nathan Smith,
Based on the reported problem, it seems that there is a mismatch between the
URLs specified in the <SfDataManager> component and the corresponding API
route methods in your controllers. There is no route defined for Update and
Delete in the provided code. For your reference we have attached a code snippet
and a simple sample.
|
<SfGrid @ref="Grid" DataSource="@CarrierData" AllowPaging="true" AllowSorting="true" ShowColumnChooser="true" Toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Update", "Search", "Cancel", "ColumnChooser" })"> <GridEvents OnActionBegin="OnBeginHandler" TValue="Carrier"></GridEvents> <SfDataManager Url="https://localhost:7074/api/Carrier" InsertUrl="https://localhost:7074/api/Carrier/Insert" UpdateUrl="https://localhost:7074/api/Grid/Update" RemoveUrl="https://localhost:7074/api/Grid/Delete" Adaptor="Adaptors.UrlAdaptor"></SfDataManager> </SfGrid>
[HttpPost] [Route("api/Carrier/Insert")] public void Insert([FromBody] CRUDModel<Carrier> Value) { _context.Carriers.Add(Value.Value); _context.SaveChangesAsync(); }
[HttpPost] [Route("api/Grid/Update")] public void Update([FromBody] CRUDModel<Carrier> Value) { var existingOrder = _context.Carriers.Find(Value.Value.CarrierId); if (existingOrder != null) { // Update the existing order with the new values _context.Entry(existingOrder).CurrentValues.SetValues(Value.Value); // Save changes to the database _context.SaveChanges(); } } |
Note : After connecting the database, we need to copy the path of the database and change the connection string with the copied path in GridController.cs file based on the NORTHWND.MDF file
Regards,
Prathap Senthil
Thank you for your response! So I already tried the above and still nothing... Can't get it to work after spending hours of debugging. I've tried five different rewrites and every time I can get the data in the tables and the filtering and sorting but any CRUD operations seem to not want to go to my methods...
I have tried:
-Restructuring all the code to use the WebApiAdaptor instead (same problem)
Code: https://pastebin.com/ehMU3Ahd
-Used code straight from your zip and created completely new classes
Code: https://pastebin.com/QArx1AvR
I tried two different Api methods here, one using my existing EF context logic, and a more direct-to-SQL-server approach
-Downloaded the EntityFrame work example referenced in the documentation which uses the EjsGrid to try things a few different ways
-Tried process of elimination with stuff in my Program.cs https://pastebin.com/5kq74mmT
I wish I could build a working example to recreate this issue. I guess I will have to at some point since it has to be something either obvious I'm missing or deep buried in my Program.cs or Imports or something... The project isn't THAT complicated but... yeah this is frustrating! :-)
Will send you some bitcoin for a coffee if someone can help me figure this out!
We noticed that the shared code snippet still has a mismatch between the URLs specified in the <SfDataManager> component and the corresponding API route methods in your controllers- https://pastebin.com/QArx1AvR. We also suggest cross-verifying your project with the previously shared working project. If the issue persists, please share a reproducible sample with duplicate data or try to reproduce the reported issue using the previous attached sample. Based on this, we will provide a solution as soon as possible. Additionally, verify if the CORS policy is correctly configured in your service project's Program.cs file. Kindly refer to the code snippet and sample below for your reference.
|
{ options.AddPolicy("NewPolicy", builder => builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader()); }); var app = builder.Build();
if (app.Environment.IsDevelopment()) { app.UseSwagger(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseCors("NewPolicy"); |
|
<SfDataManager Url="https://localhost:7074/api/Carrier" InsertUrl="https://localhost:7074/api/Carrier/Insert" UpdateUrl="https://localhost:7074/api/Carrier/Update" RemoveUrl="https://localhost:7074/api/Carrier/Delete" Adaptor="Adaptors.UrlAdaptor"></SfDataManager>
[ApiController] public class GridController : ControllerBase { [HttpPost] [Route("api/[controller]")] public object Post([FromBody] DataManagerRequest DataManagerRequest) { IEnumerable<Carrier> DataSource = GetOrderData(); if (DataManagerRequest.Search != null && DataManagerRequest.Search.Count > 0) { DataSource = DataOperations.PerformSearching(DataSource, DataManagerRequest.Search); } if (DataManagerRequest.Where != null && DataManagerRequest.Where.Count > 0) { DataSource = DataOperations.PerformFiltering(DataSource, DataManagerRequest.Where, DataManagerRequest.Where[0].Operator); } if (DataManagerRequest.Sorted != null && DataManagerRequest.Sorted.Count > 0) { DataSource = DataOperations.PerformSorting(DataSource, DataManagerRequest.Sorted); } int TotalRecordsCount = DataSource.Cast<Carrier>().Count(); IDictionary<string, object> Aggregates = null; if (DataManagerRequest.Aggregates != null) // Aggregation { Aggregates = DataUtil.PerformAggregation(DataSource, DataManagerRequest.Aggregates); } if (DataManagerRequest.Skip != 0) { DataSource = DataOperations.PerformSkip(DataSource, DataManagerRequest.Skip); } if (DataManagerRequest.Take != 0) { DataSource = DataOperations.PerformTake(DataSource, DataManagerRequest.Take); } return new { result = DataSource, count = TotalRecordsCount, aggregates = Aggregates }; } [Route("api/[controller]")] public List<Carrier> GetOrderData() { //BREAKPOINT WILL HIT HERE string ConnectionString = @""; string QueryStr = "SELECT * FROM dbo.Carriers ORDER BY CarrierId;"; SqlConnection sqlConnection = new(ConnectionString); sqlConnection.Open(); SqlCommand SqlCommand = new(QueryStr, sqlConnection); SqlDataAdapter DataAdapter = new(SqlCommand); DataTable DataTable = new(); DataAdapter.Fill(DataTable); sqlConnection.Close(); var DataSource = (from DataRow Data in DataTable.Rows select new Carrier() { CarrierId = Convert.ToInt32(Data["CarrierId"]), CarrierName = Data["CarrierName"].ToString() }).ToList(); return DataSource; }
[HttpPost] [Route("api/Carrier/Insert")] public void Insert([FromBody] CRUDModel<Carrier> Value) { //BREAKPOINT DOES ***NOT*** HIT IN HERE string ConnectionString = @""; }
public class CRUDModel<T> where T : class { [JsonProperty("action")] public string? Action { get; set; } [JsonProperty("keyColumn")] public string? KeyColumn { get; set; } [JsonProperty("key")] public object? Key { get; set; } [JsonProperty("value")] public T? Value { get; set; } [JsonProperty("added")] public List<T>? Added { get; set; } [JsonProperty("changed")] public List<T>? Changed { get; set; } [JsonProperty("deleted")] public List<T>? Deleted { get; set; } [JsonProperty("params")] public IDictionary<string, object>? Params { get; set; } } } |
So, the issue is model validation on my end. I added an OnActionFailure handler and see that a foreign key / ApplicationUser object isn't being handled correctly as it is required. The "CreatedBy" field isn't found.
I guess this still begs the questions of:
-Any special handling of User objects with DataGrid and/or CRUD Api methods?
-Why isn't the breakpoint hitting in my Update handler before it realizes the model error - where is it validating the model.
Sorry for the delay in getting back to you.
We have analyzed the reported issue at our end and we are able to reproduce the reported issue at our end also. We would like to inform you that we have used EditForm component and Microsoft Validation to perform validation at the client end. Validation will be executed and applied to column when focusing out from the Field in the Edit Form itself. But when Primary Key column is enabled for IsIdentity (AutoGenerated / Identity) column, it will be disabled state while editing or Add operations so its value will be null and Required validation gets thrown, which in turn caused the reported issue.
Since the validation is being performed in the client end and columns gets disabled due to IsIdentity property, we request you to remove the ValidationRules property defined for IsIdentity Column.
Also we have logged improvement task to update the our UG documentation code example and it will be updated as early as possible. So we request you to resolve the reported issue by removing the ValidationRules applied for Identity column. Please get back to us if you have further queries.