Scenario
A grid showing datas, with an add new record function,
checking the data submitted from client with custom validation,
if the result isn't valid, directly return View("gridPage").
However, the grid still shows the data with the one client had just submiitted, which isn't valid.
How can I prevent from this situation?
Grid Code
<div>
@(Html.Kendo().Grid<Sinotech.AntiSeismic.Digitalization.Web.Controllers.ViewModels.AgentViewModel>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(c => c.Code).Title("經銷商代號");
columns.Bound(c => c.Name).Title("經銷商名稱");
columns.Bound(c => c.TaxIdnum).Title("統一編號");
columns.Bound(c => c.PersonInCharge).Title("負責人姓名");
columns.Bound(c => c.TelNum).Title("電話");
columns.Bound(c => c.Addr).Title("地址");
columns.Bound(c => c.MailAddr).Title("通訊地址");
columns.Bound(c => c.BankCode).Title("銀行代號");
columns.Bound(c => c.BankName).Title("銀行別");
columns.Bound(c => c.BankAccount).Title("銀行帳號");
columns.Bound(c => c.BankAccountName).Title("銀行帳號戶名");
columns.Bound(c => c.Sales).Title("業務姓名");
columns.Bound(c => c.SalesTelNum).Title("業務電話");
columns.Bound(c => c.Accountant).Title("會計姓名");
columns.Bound(c => c.AccountantTelNum).Title("會計電話");
columns.Command(c => c.Edit());
columns.Command(c => c.Destroy());
})
.Pageable()
.Scrollable()
.Sortable()
.Editable(editable => editable.Mode(GridEditMode.PopUp))
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Create(create => create.Action("AddAgent", "Vendor"))
.Read(read => read.Action("GetAgentData", "Vendor", new { Id = Id }))
.Update(update => update.Action("UpdateAgent", "Vendor"))
.Destroy(destroy => destroy.Action("DeleteAgent", "Vendor"))
.Model(m => {
m.Id(id => id.Id);
m.Field(f => f.Id).Editable(false);
})
)
.ToolBar(tools =>
{
tools.Create();
})
)
</div>
Thought that the DataSource.Read function would refresh the data on grid,
since I've just return back to the page after validation error, and it automatically runs through the DataSource.Read.
But it's not working
An extension question had poped up after I submitted this question,
How can the grid automatically refresh after Creat, Update operations?
Update
Finding out after the create function failure of the grid,
the processs didn't run through the grid code section as I thought before,
So it did not automatically refresh datas on the grid,
How could I achieve this ?
Hi Chihpei,
Thank you for sharing the configuration of your Grid, but it is difficult for me to understand the scenario at hand without knowing the custom validation you apply. Is it in any way similar to the example in the Custom Validator Demo of the Grid?
That said when a Read, Create, Update or Destroy operations are done the Grid refreshes - meaning that its DataBound event is thrown and all of its data rebinds to the DOM.
Therefore at this point I suppose that the reported issues could be related to the way the data values are added to the DataSourceResult returned by Controller Action methods.
public ActionResult Update([DataSourceRequest] DataSourceRequest request, ProductViewModel product) { //validate product based on the ProductViewModel DataAnnotations if (product != null && ModelState.IsValid) { //persist the updated data item productService.Update(product); } return Json(new[] { product }.ToDataSourceResult(request, ModelState)); }
Please consider sharing additional information about the scenario at hand. Ideally a runnable project with dummy data that showcases the observed behaviors will enable us to research the matter in more depth.
Thank you for your cooperation.
Hi Stoyan,
My scenario is quite complicated to provide a runnable project since I'm trying it in a three tier structure,
thought it would be confusing.
What I can say is that I'm using a common three tier structure( with Controller / Service / Repository Layer),
the DataAnnotation works fine for me,
but I'm adding custom validations in the Service layer,
I'll try to provide some code snippets
Once the user adds a new record, it will lead the process into "AddCustomer" action,
In this action will do the custom validation with the "IsInsertValid" function from service layer,
this function is checking wether if the data add from the user was already in DB,
If so, the service layer will throw an exception back to controller.
Then, it will directly return back to View.
And here is the issue,
the picture is a Grid sample,
Grid Columns
the yellow row is the one that user add, which was a data already in DB,
so after the vlaidation from the Service layer and went back to the view,
the Grid still adds the new data on grid,
How can I solve this problem, since the grid hasn't automatically refresh with the DataSource.Read() function after the validation ?
customer.cshtml (Telerik UI Grid)
<div> @(Html.Kendo().Grid<Sinotech.AntiSeismic.Digitalization.Web.Controllers.ViewModels.CustomerViewModel>() .Name("grid") .Columns(columns => { columns.Bound(c => c.Code).Title("Code"); columns.Bound(c => c.Name).Title("Name"); columns.Bound(c => c.Sex).Title("Sex"); columns.Bound(c => c.PhoneNum).Title("PhoneNum"); columns.Command(c => c.Edit()); columns.Command(c => c.Destroy()); }) .Pageable() .Scrollable() .Sortable() .Editable(editable => editable.Mode(GridEditMode.PopUp)) .DataSource(dataSource => dataSource .Create(create => create.Action("AddCustomer", "Customer")) .Read(read => read.Action("GetCustomer", "Customer", new { Id = Id })) .Update(update => update.Action("UpdateCustomer", "Customer")) .Destroy(destroy => destroy.Action("DeleteCustomer", "Customer")) .Model(m => { m.Id(id => id.Id); m.Field(f => f.Id).Editable(false); }) ) .ToolBar(tools => { tools.Create(); }) ) </div>
Controller (UI Layer)
public async Task<IActionResult> AddCustomer(CustomerViewModel customerViewModel) { try { await this._customerService.IsInsertValid(customerViewModel.Code, customerViewModel.Name); } catch(Exception ex) { TempData["error"] = ex.Message; return View("Customer"); } try { customerDto agentDto = this._mapper.Map<AgentDto>(customerViewModel); string msg = await this._customerService.Add(customerDto); TempData["success"] = msg; } catch(Exception ex) { TempData["error"] = ex.Message; } return View("customer"); }
Service Layer (Custom Validations)
public async Task<string> IsInsertValid(string code, string name) { var obj = await this._unitOfWork.Repository<Customer>().GetAsync(x => x.Code == code && x.Name == name); if(obj != null) { throw new System.Exception("Same data already exists"); } return await Task.FromResult("Validated"); }