This is a migrated thread and some comments may be shown as answers.

Looking for General Error Handling Guidelines

5 Answers 416 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Marcab
Top achievements
Rank 1
Veteran
Marcab asked on 11 May 2020, 08:56 PM

Hello,

I currently have an ASP.NET MVC application that is primarily composed of a hierarchical grid and custom edit templates. I want to display a simple error page to indicate a failed database operation to the user.

I tried a standard approach adding the following to the Web.Config file: 

<customErrors mode="On"></customErrors>

I also added the following attribute at the beginning of my controller classes:

[HandleError(ExceptionType = typeof(DbUpdateException), View = "Error")]

The error page, Error.cshtml is located in the Views/Shared directory of the application.

I cannot get this to work. I can't even view the error page in the browser. I get a 404 error when I right click on the file and select view in browser.

Are there any general error handling guidelines for Telerik UI for ASP.NET MVC? I looked, but couldn't find anything fairly recent. If any such guidelines / documentation exists, where would I find it?

Thanks

5 Answers, 1 is accepted

Sort by
0
Marcab
Top achievements
Rank 1
Veteran
answered on 11 May 2020, 10:59 PM

For some reason, my grid doesn't have the Error event available. When  I tried to reference it, I got the following message: GridEvent builder does not contain a definition for "Error" and no accessible extension method Error accepting a first argument type
of GridEventBuilder. I'm using Visual Studio 2019 with the latest version of Kendo  UI for ASP.NET MVC.

My grid code isn't anything special.

@(Html.Kendo().Grid<DonationManagement2019.Models.Donor>()
                    .Name("donors")
                    .Columns(columns =>
                    {
                        columns.Bound(c => c.DonorName).Width(600);
                        columns.Bound(c => c.Address).Width(600);
                        columns.Bound(c => c.City).Width(175);
                        columns.Bound(c => c.State).Width(85);
                        columns.Bound(c => c.ZipCode).Width(120);
                        columns.Bound(c => c.Email).Width(390);
                        columns.Bound(c => c.PrimaryPhone).Width(150);
                        columns.Bound(c => c.PhoneExt).Width(75);
                        columns.Bound(c => c.DonorType).Width(175);
                        columns.Bound(c => c.DonorCategory).Width(160);
                        columns.Command(command => { command.Edit(); command.Destroy(); }).Width(200);
                    })
                    //.HtmlAttributes(new { style = "width: 1500px;" })
                    .ToolBar(toolbar =>
                    {
                        toolbar.Create();
                    })
                    .Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateName("Donor"))
                    .Pageable()
                    .Sortable(sortable =>
                    {
                        sortable.SortMode(GridSortMode.SingleColumn);
                    })
                    .Filterable()
                    .Scrollable(scrollable => scrollable.Enabled(false))
                    .ClientDetailTemplateId("template")
                    .DataSource(dataSource => dataSource
                        .Ajax()
                        .Model(model => model.Id(p => p.DonorId))
                        .Read(read => read.Action("Donors_Read", "Home"))
                        .Create(create => create.Action("Donors_Create", "Home"))
                        .Update(update => update.Action("Donors_Update", "Home"))
                        .Destroy(destroy => destroy.Action("Donors_Destroy", "Home"))
                    )
                  .Events(events => events.DataBound("dataBound"))
)

<script id="template" type="text/kendo-tmpl">
    @(Html.Kendo().TabStrip()
                          .Name("tabStrip_#=DonorId#")
                          .SelectedIndex(0)
                          .Animation(animation => animation.Open(open => open.Fade(FadeDirection.In)))
                          .Items(items =>
                          {
                              items.Add().Text("Donations" +
                                   "").Content(@<text>
                                    @( Html.Kendo().Grid<DonationManagement2019.Models.Donation>()
                                                                   .Name("grid_#=DonorId#") // template expression, to be evaluated in the master context
                                                                   .Columns(columns =>
                                                                   {
                                                                       columns.Bound(d => d.DonationDate).Format("{0:MM/dd/yyyy}").Width(70);
                                                                       columns.Bound(d => d.FiscalYear).Width(110);
                                                                       columns.Bound(d => d.Campaign);
                                                                       columns.Bound(d => d.DonationAmount).Format("{0:C}").Width(200);
                                                                       columns.Bound(d => d.DonationMethod).Width(200);
                                                                       columns.Bound(d => d.Notes);
                                                                       columns.Bound(d => d.RecordedOn).Format("{0:MM/dd/yyyy}");
                                                                       columns.Bound(d => d.UpdatedOn).Format("{0:MM/dd/yyyy}");
                                                                       columns.Command(command => { command.Edit(); command.Destroy(); });
                                                                   })
                                                             .ToolBar(toolbar =>
                                                             {
                                                                 toolbar.Create();
                                                             })
                                                             .Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateName("Donation"))
                                                             .DataSource(dataSource => dataSource
                                                                     .Ajax()
                                                                     .Events(ev => ev.RequestEnd("onRequestEnd"))
                                                                     .Model(model => model.Id(d => d.DonationId))
                                                                     .PageSize(10)
                                                                     .Read(read => read.Action("Donations_Read", "Donations", new { parentID = "#=DonorId#" }))
                                                                     .Create(create => create.Action("Donations_Create", "Donations", new { parentID = "#=DonorId#" }))
                                                                     .Update(update => update.Action("Donations_Update", "Donations", new { parentID = "#=DonorId#" }))
                                                                     .Destroy(destroy => destroy.Action("Donations_Destroy", "Donations"))
                                                                   )
                                                                   .Pageable()
                                                                   .Sortable()
                                                                   .Filterable()
                                                                   .ClientDetailTemplateId("customtemplate")
                                                                   .ToClientTemplate())
                                </text>
                        );
                         items.Add().Text("Notes ").Content(
         "<div class='donor-details'>" +
         "<ul>" +
         "<li><label>Notes:</label>#= Notes#</li>" +
         "</ul>" +
         "</div>"
         );
                     })
                              .ToClientTemplate())
</script>
<script id="customtemplate" type="text/kendo-tmpl">
    @(Html.Kendo().TabStrip()
                                                    .Name("tabStrip_#=DonationId#")
                                                    .SelectedIndex(0)
                                                    .Animation(animation => animation.Open(open => open.Fade(FadeDirection.In)))
                                                        //.Items(items =>
                                                        //{
                                                        //    items.Add().Text("Donation Notes").Content(
                                                        //        "<div class='donor-details'>" +
                                                        //        "<ul>" +
                                                        //        "<li><label>Notes:</label>#= Notes#</li>" +
                                                        //        "</ul>" +
                                                        //        "</div>"
                                                        //        );
                                                        //})
                                                        .ToClientTemplate())
</script>
<script>
  function dataBound() {
    this.expandRow(this.tbody.find("tr.k-master-row").first());
  }

  var detailExportPromises = [];

  function employees_detailInit(e) {
    var deferred = $.Deferred();   /

    // get the index of the master row
    var masterRowIndex = e.masterRow.index(".k-master-row");

    // add the deferred to the list of promises
    detailExportPromises.push(deferred);

   

   
  }

    (function () {
        window.onRequestEnd = function (e) {
            if (e.response.Data && e.response.Data.length) {
                var data = e.response.Data;
                if (this.group().length && e.type == "read") {
                    handleGroups(data);
                } else {
                    loopRecords(data);
                }
            }
        }
        function handleGroups(groups) {
            for (var i = 0; i < groups.length; i++) {
                var gr = groups[i];
                offsetDateFields(gr); //handle the Key variable as well
                if (gr.HasSubgroups) {
                    handleGroups(gr.Items)
                } else {
                    loopRecords(gr.Items);
                }
            }
        }
        function loopRecords(donations) {
            for (var i = 0; i < donations.length; i++) {
                var donation = donations[i];
                offsetDateFields(donation);
            }
        }


        function offsetDateFields(obj) {
            for (var name in obj) {
                var prop = obj[name];
                if (typeof (prop) === "string" && prop.indexOf("/Date(") == 0) {
                    obj[name] = prop.replace(/\d+/, function (n) {
                        var offsetMiliseconds = new Date(parseInt(n)).getTimezoneOffset() * 60000;
                        return parseInt(n) + offsetMiliseconds
                    });
                }
            }
        }
    })();

    

    //function employees_excelExport(e) {
  //  // prevent saving the file because we will update the workbook
  //  e.preventDefault();

  //  var workbook = e.workbook;

  //  // Export all detail grids
  //  $("[data-role=grid]", this.element).each(function () {
  //    $(this).data("kendoGrid").saveAsExcel();
  //  });

  //  // wait for all detail grids to finish exporting
  //  $.when.apply(null, detailExportPromises)
  //    .then(function () {
  //      // get the export results
  //      var detailExports = $.makeArray(arguments);

  //      // sort by masterRowIndex
  //      detailExports.sort(function (a, b) {
  //        return a.masterRowIndex - b.masterRowIndex;
  //      });

  //      // add an empty column
  //      workbook.sheets[0].columns.unshift({ width: 30 });

  //      // prepend an empty cell to each row
  //      for (var i = 0; i < workbook.sheets[0].rows.length; i++) {
  //        workbook.sheets[0].rows[i].cells.unshift({});
  //      }

  //      // merge the detail export sheet rows with the master sheet rows
  //      // loop backwards so the masterRowIndex doesn't need to be updated
  //      for (var i = detailExports.length - 1; i >= 0; i--) {
  //        var masterRowIndex = detailExports[i].masterRowIndex + 1;

  //        var sheet = detailExports[i].sheet;

  //        // prepend an empty cell to each row
  //        for (var ci = 0; ci < sheet.rows.length; ci++) {
  //          if (sheet.rows[ci].cells[0].value) {
  //            sheet.rows[ci].cells.unshift({});
  //          }
  //        }

  //        // insert the detail sheet rows after the master row
  //        [].splice.apply(workbook.sheets[0].rows, [masterRowIndex + 1, 0].concat(sheet.rows));
  //      }

  //      // save the workbook
  //      kendo.saveAs({
  //        dataURI: new kendo.ooxml.Workbook(workbook).toDataURL(),
  //        fileName: "Export.xlsx"
  //      });
  //    });
  //}
</script>

<style>
    .k-detail-cell .k-tabstrip .k-content {
        padding: 0.2em;
    }

    .donor-details ul {
        list-style: none;
        font-style: italic;
        margin: 15px;
        padding: 0;
    }

        .donor-details ul li {
            margin: 0;
            line-height: 1.7em;
        }

    .donor-details label {
        display: inline-block;
        width: 150px;
        padding-right: 10px;
        text-align: right;
        font-style: normal;
        font-weight: bold;
    }
</style>

 

0
Marcab
Top achievements
Rank 1
Veteran
answered on 11 May 2020, 11:12 PM

This is the example I tried to use. The grid in the example has an Error event available, my grid does not. 

// Omitted for brevity..

.DataSource(dataSource => dataSource.Ajax()

.Events(events => events.Error("onError"))

// Omitted for brevity.

<script>

function onError(e, status) {

alert("A server error has occurred!");

}

</script>

Example source: https://docs.telerik.com/aspnet-mvc/html-helpers/data-management/grid/faq

0
Ianko
Telerik team
answered on 13 May 2020, 11:10 AM

Hi Sheila,

The example in the documentation might not showing where the Error event is available. You should search for this event in the Events method of the DataSource, not the Grid. Here you are a code example that might shed more light on the case: 

        @(Html.Kendo().Grid<TelerikMvcApp3.Models.OrderViewModel>()
            .Name("grid")
            .Columns(columns =>
            {
                columns.Bound(p => p.OrderID).Filterable(false);
                columns.Bound(p => p.Freight);
                columns.Bound(p => p.OrderDate).Format("{0:MM/dd/yyyy}");
                columns.Bound(p => p.ShipName);
                columns.Bound(p => p.ShipCity);
            })
            .Pageable()
            .Sortable()
            .Scrollable()
            .Filterable()
            .HtmlAttributes(new { style = "height:550px;" })
            .DataSource(dataSource => dataSource
                .Ajax()
                .PageSize(20)
                .Read(read => read.Action("Orders_Read", "Grid"))
                .Events(events => events.Error("onError")) // DataSource events
            )
            .Events(events => events.DataBound("onDataBound")) // Grid events
        )

I hope that helps.

Regards,
Ianko
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
0
Marcab
Top achievements
Rank 1
Veteran
answered on 13 May 2020, 02:53 PM

Thanks for the example Ianko.

I'll give it a try.

 

 

0
Ianko
Telerik team
answered on 14 May 2020, 09:23 AM

Hi Sheila,

Let me know if you need any further assistance on the case. 

Regards,
Ianko
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
Tags
General Discussions
Asked by
Marcab
Top achievements
Rank 1
Veteran
Answers by
Marcab
Top achievements
Rank 1
Veteran
Ianko
Telerik team
Share this question
or