My web application's implementation of the Upload widget does data validation through the component itself (max file size, allowed file types, etc.) as well as some extra validation through the Async.Save() handler's controller action (image validity, checking for animated images, etc.). It's my understanding that there are three potential results from the handler:
During the non-client side validation in my controller, should one of the checks fail we call "return Content(<string>)" and for the most part, this works as intended if the string contains any non-numeric characters. Initially I was simply returning a reference to a resource string defining the error and displaying it to the user in an alert describing what went wrong with the upload (via XMLHttpRequest.responseText); however, in the case of an undefined (by me) error this would result in an alert showing server response details that I don't wish to be displayed to the user. Thus I decided to send error codes and translate those client-side. This made it much easier to check for the error messages I mean to display to the user as well as have a default that displays for any unintended response. My problem is that if I return a string that is strictly numeric the handler doesn't result in an error.
Ex. return Content("Error: Bad File") would result in my error handler being called, and the text "Error: Bad File" being displayed in an alert.
But return Content("2") would result in a "successful" upload. The amount of numbers in the string doesn't matter, but if at any point a letter or symbol is included in the string it once again properly handles as an error.
I've already fixed my code to work by adding "error" into the string with the code number but I figured it was worth asking about since I would prefer to just use a numeric string. I'm puzzled as to what is causing the issue, as I don't believe strings containing only numbers are treated any differently than others unless they're being parsed. If I check the network response in the dev. console it shows the string as the response, which is what leads me to think it's something with the kendo widget.
Using .NET Framework 4.7.2, ASP.NET MVC 4 and Kendo.Mvc version 2021.2.616.545.
Hi,
I have used the tutorial https://demos.telerik.com/aspnet-mvc/grid/server-export in order to do a server export of a grid to excel. My grid has columns that contain text values, numerical values and date values.
I have set the formats accordingly on the .cshtml page, but it seems as though the exporter ignores this and it needs me to set the 'NumberFormat' to 'dd/mm/yyyy' in the SpreadCellFormat in order to show the date correctly. However that then applies the same format to every cell in the spreadsheet, meaning that the numerical columns turn to dates.
Has anyone else found this and have a solution?
Thanks
Becky
@(Html.Kendo().ScrollView()
.Name("svMessages")
//Afficher la pagination si plus d'un message.
.EnablePager(Model.NbMessages > 1)
.DataSource(d => d.Read(r => r.Action("AfficherMessagesAccueil", "Account")))) [AllowAnonymous]
[HttpGet]
public ActionResult AfficherMessagesAccueil([DataSourceRequest] DataSourceRequest request)
{
var messages = new List<MessageAccueil>();
return Json(messages.ToDataSourceResult(request));
} [AllowAnonymous]
[HttpPost]
public ActionResult AfficherMessagesAccueil([DataSourceRequest] DataSourceRequest request)
{
var messages = new List<MessageAccueil>();
return Json(messages.ToDataSourceResult(request));
}Hi,
I am trying to implement Kendo Captcha. I tried to implement same way as in this article.
ASP.NET MVC Captcha Component Validation - Telerik UI for ASP.NET MVC
But I am getting below error. what am I doing wrong?
My code is like this
@(Html.Kendo().Captcha()
.Name("Captcha")
.CaptchaImage((string)ViewData["Captcha"])
.CaptchaId((string)ViewData["CaptchaID"])
.DataCaptchaField("Captcha") // The field containing the Captcha from the server-side should be called Captcha.
.DataCaptchaIdField("CaptchaID") // The field containing the Captcha's ID from the server-side should be called CaptchaID.
.Handler(handler => handler.Action("Reset", "IUA"))
.ValidationHandler(handler => handler.Action("Validate", "IUA"))
.ValidateOnBlur(true)
)namespace Portal.Controllers
{
public class IuaController : Controller
{
// GET: Iua
public ActionResult Index ( string pin )
{
var model = portalServices.getExistingData();
if (string.IsNullOrEmpty(model.CaptchaID))
{
GenerateNewCaptcha();
}
else
{
CaptchaImage captchaImage = (CaptchaImage)Session["captcha" + model.CaptchaID];
if (captchaImage != null && CaptchaHelper.Validate(captchaImage, model.Captcha.ToUpperInvariant()))
{
ModelState.Clear();
GenerateNewCaptcha();
}
}
//return View();
return View(model);
}
private void GenerateNewCaptcha()
{
CaptchaImage captchaImage = CaptchaHelper.GetNewCaptcha();
Session["captcha" + captchaImage.UniqueId] = captchaImage;
ViewData["Captcha"] = GetCatchaImage(captchaImage.UniqueId);//Url.Action("image", "IUA", new { captchaId = captchaImage.UniqueId });
ViewData["CaptchaID"] = captchaImage.UniqueId;
}
public ActionResult Reset()
{
CaptchaImage newCaptcha = CaptchaHelper.GetNewCaptcha();
Session["captcha" + newCaptcha.UniqueId] = newCaptcha;
return Json(new
{
captcha = GetCatchaImage(newCaptcha.UniqueId),//Url.Action("image", "IUA", new { captchaId = newCaptcha.UniqueId }),
captchaId = newCaptcha.UniqueId
}, JsonRequestBehavior.AllowGet);
}
public ActionResult Image(string captchaId)
{
CaptchaImage captcha = (CaptchaImage)Session["captcha" + captchaId];
var image = CaptchaHelper.RenderCaptcha(captcha);
byte[] bmpBytes;
using (MemoryStream ms = new MemoryStream())
{
image.Save(ms, ImageFormat.Png);
bmpBytes = ms.ToArray();
}
return File(bmpBytes, "image/png");
}
public ActionResult GetCatchaImage(string captchaId)
{
CaptchaImage captcha = (CaptchaImage)Session["captcha" + captchaId];
var image = CaptchaHelper.RenderCaptcha(captcha);
byte[] bmpBytes;
using (MemoryStream ms = new MemoryStream())
{
image.Save(ms, ImageFormat.Png);
bmpBytes = ms.ToArray();
}
return File(bmpBytes, "image/png");
}
public ActionResult Audio(string captchaId)
{
CaptchaImage captcha = (CaptchaImage)Session["captcha" + captchaId];
byte[] bmpBytes;
using (MemoryStream audio = CaptchaHelper.SpeakText(captcha))
{
bmpBytes = audio.ToArray();
}
return File(bmpBytes, "audio/wav");
}
public ActionResult Validate(string captchaId, string captcha)
{
CaptchaImage captchaImage = (CaptchaImage)Session["captcha" + captchaId];
return Json(CaptchaHelper.Validate(captchaImage, captcha.ToUpperInvariant()), JsonRequestBehavior.AllowGet);
}
}
}
Model class
public class IuaModel
{
[Key]
public string Pin { get; set; }
[Display(Name = "Ticket #")]
public long Id { get; set; }
[Required]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Display(Name = "Middle Initial")]
public string MiddleInitial { get; set; }
[Required]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Display(Name = "Facility Name")]
public string FacilityName { get; set; }
private string _captchaValue;
public string Captcha
{
get
{
return string.IsNullOrEmpty(_captchaValue) ? "" : _captchaValue;
}
set
{
_captchaValue = value;
}
}
public string CaptchaID { get; set; }
}
I used the upgrade wizard to download the latest version and I'm getting this error message on pages that have the components:
Value column has an inline validation of max and min. On entering the correct values also I am getting this error.
I am using this JS code for custom input control. Please suggest me some approach to resolve this error.
if (e.model.UnitTypeCode === "UNIT_LOOKUP_FLOAT") {
Hello,
I am trying to understand the best way to update a submodel that is part of the composition of a grid's row model.
I tried to outline an example below. If I have a PersonViewModel that is part of a CompanyViewModel.
I want to be able to update the PersonViewModel's Name, Id and Email by querying using their email.
public class PersonViewModel
{
public string Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}public class CompanyViewModel
{
public string CompanyId { get; set; }
public string CompanyName { get; set; }
public PersonViewModel Owner { get; set; }
}
public IActionResult GetPersonByEmail([DataSourceRequest] DataSourceRequest request, string email)
{
PersonViewModel person = _userService.GetUserInfoByEmail(email);
return Json(person.ToDataSourceResult(request));
}@(Html.Kendo().Grid<CompanyViewModel>()
.Name("companyGrid")
.Columns(columns =>
{
columns.Command(command => { command.Edit();}).Locked(true);
columns.Bound(c => c.CompanyId );
columns.Bound(p => p.CompanyName );
columns.Bound(c => c.Owner.Name);
columns.Bound(c => c.Owner.Email).EditorTemplateName("PersonEditor");
})
.Scrollable(s => s.Height("auto"))
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("CompanyRead", "Company"))
.Model(model =>
{
model.Id(p => p.CompanyId);
model.Field(p => p.Owner).DefaultValue(new PersonViewModel() { Name = "", UserId = "", Id = "" });
})
)
)PersonEditor Template would look something like this?
@model PersonViewModel
@(Html.TextBoxFor(model => model))
@(Html.Kendo().Button()
.Name("PersonLookupButton")
.Content("Search")
.Events(ev => ev.Click("personLookupOnClick"))
)
I could get the dataItem from the grid and set the Id, Name, and Email values via jQuery, but that feels like it is working against the point of using composition in my viewmodel. Is there a way to get the PersonViewModel that is returned by GetPersonByEmail() and bind that directly to the row instead?
Thank you!

Hello
I currently have an kendo grid with PDF export functionality, I am trying to add in the facilities to add a line header text to the exported PDF and have tried using both a grid header text box and a javascript alert on button click, however when I try to do this either the application tries to export indefinitely, or the header text is not included. Can anyone suggest where I may be going wrong with this?
View code:
@(Html.Kendo().Grid<Planner.Models.GetTaskList_Result1>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(p => p.DateCreated).Title("Date Created").Format("{0:dd/MM/yy}").Width(120);
columns.Bound(p => p.TaskNo).Title("TaskNo").Width(90);
columns.Bound(p => p.TaskDescription).Title("Task").Width(200);
columns.Bound(p => p.PriorityText).Title("Priority").Width(90);
columns.Bound(p => p.AreaText).Title("Area").Width(140);
columns.Bound(p => p.QS1).Title("Quality Statement").Width(150);
columns.Bound(p => p.KA1).Title("KLOE Area 1").Width(150);
columns.Bound(p => p.KC1).Title("KLOE Characteristic 1").Width(200);
columns.Bound(p => p.KA2).Title("KLOE Area 2").Width(150).Hidden(true);
columns.Bound(p => p.KC2).Title("KLOE Characteristic 2").Width(150).Hidden(true);
columns.Bound(p => p.KA3).Title("KLOE Area 3").Width(150).Hidden(true);
columns.Bound(p => p.KC3).Title("KLOE Characteristic 3").Width(150).Hidden(true);
columns.Bound(p => p.KA4).Title("KLOE Area 4").Width(150).Hidden(true);
columns.Bound(p => p.KC4).Title("KLOE Characteristic 4").Width(150).Hidden(true);
columns.Bound(p => p.KA5).Title("KLOE Area 5").Width(150).Hidden(true);
columns.Bound(p => p.KC5).Title("KLOE Characteristic 5").Width(150).Hidden(true);
columns.Bound(p => p.LeadAssigned).Title("Lead Assigned").Width(120);
columns.Bound(p => p.SupportAssigned).Title("Support Assigned").Width(150);
columns.Bound(p => p.DateDue).Title("Date Due").Format("{0:dd/MM/yyyy}").Width(120);
columns.Bound(p => p.StatusText).Title("Status").Width(120);
})
.Resizable(resize => resize.Columns(true))
.Selectable(selectable => selectable.Mode(GridSelectionMode.Single).Type(GridSelectionType.Row))
.Events(events =>
{
events.Change("onChange");
events.PdfExport("GetHeaderText");
})
.Sortable()
.ToolBar(toolBar =>
{
toolBar.Template(
@<Text>
<b class="FloatRight SearchTopMarginExtra">Search by Task Description/Staff: </b>
<input type="search" id="searchbox" class="SearchRight SearchTopMargin" />
<b class="FloatRight">Date From:</b>
<input type="date" id="DateFrom" />
<b class="FloatRight">Date To:</b>
<input type="date" id="DateTo" />
<button id="clearFiltersButton" class="k-button">Clear Filters</button>
||
<a class="k-button k-button-icontext k-grid-pdf" href="\#"><span class="k-icon k-i-pdf"></span>Export to PDF</a>
<b class="float-right">Title on PDF:</b>
<input type="text" id="PDFTitle" />
</Text>);
})
.Pdf(pdf => pdf
.AllPages()
.AvoidLinks()
.PaperSize("A4")
.Scale(0.45)
.Landscape()
.Margin("2cm", "1cm", "1cm", "1cm")
.TemplateId("page-template")
.FileName("Active tasks " + DateTime.Today.ToString("d") + ".pdf")
.ProxyURL(Url.Action("Pdf_Export_Save", "Grid"))
)
.Scrollable(scrollable => scrollable.Enabled(true).Height("600px"))
.Filterable(ftb => ftb.Mode(GridFilterMode.Row))
.DataSource(datasource => datasource
.Ajax()
.Filter(filters =>
{
filters.Add(f => f.Completed).IsEqualTo(false);
})
.Sort(sort => sort.Add("DateDue").Ascending())
.Model(model => model.Id(p => p.TaskNo))
.Read(read => read.Action("Tasks_Read", "TaskList"))
)
.Pageable(pageable => pageable
.Enabled(false))
.Events(e => e.DataBound("onDataBound"))
)
Relevant javascript and template:
<script type="text/javascript">
$(document).ready(function () {
$("#PDFTitle").keyup(function SetViewData() {
var val = $("#PDFTitle").val();
var text = document.getElementById('customHeaderText');
text.val() = val.val();
})
});
</script>
<script type="x/kendo-template" id="page-template">
<div class="page-template">
<div class="header">
#: customHeader #
@Html.Label("", new { id = "customHeaderText" })
</div>
<div class="footer">
<div style="float: right">Page #: pageNum # of #: totalPages #</div>
</div>
</div>
</script>
<script type="text/javascript">
function GetHeaderText(e) {
var customHeader = prompt('Please enter a title for the PDF');
}
</script>
Greetings,
Im having trouble getting my grid to order the way i want. I thought that you could use .DataSource to setup sorting but nothing im seeing come up fits my situation. I want to sort my "haslinked" individuals to the bottom of the grid. Thanks!
Edit: i just realized my kendo grid is model vs server side. Thats what i dont get a .sort after datasource. Any idea how to sort a grid with this new finding? I believe it essentially means im trying to organize a grid with dynamic content.
@(Html.Kendo().Grid(Model)
.Name("grid")
.Columns(columns =>
{
columns.Bound(model => model.UserName).Title("UserName");
columns.Bound(model => model.RoleList).Title("Role(s)");
columns.Bound(model => model.HasLinkedDistilleries).Title("HasLink");
columns.Bound(b => b.Id).Template(@<text>@Html.ActionLink("Delete", "Delete", "Account", new { id = item.Id }, null)</text>).Title("");
columns.Bound(b => b.Id).Template(@<text>@Html.ActionLink("Edit", "Edit", "Account", new { id = item.Id }, null)</text>).Title("");
columns.Bound(b => b.Id).Template(@<text>@Html.ActionLink("Permissions", "Index", "UserPermissions", new { id = item.Id }, null)</text>).Title("").HtmlAttributes(new {@class="" });
})
.ToolBar(tools =>
{
tools.Template(@<text>@ToolbarTemplate()</text>);
})
.Sortable() // Enable sorting
.DataSource()d => d......Heres where im having trouble.)
.Filterable()
.Scrollable()
Hi there,
I recently updated our Kendo files inside our MVC application to version 2023.1.117. And I found an issue on Kendo Tabstrip: that when we setup the default index using .SelectedIndex(0), the tabstrip would setup k-state-active class into the targeted tab instead of the newer k-active class. The same thing happen if we set the .selected(True) at the tabitems.
This is causing problem with the styling and tab content display because of when we start navigating to another tab via clicking, the code won't clear up the k-state-active class. Thus there'll be always 2 active state. Is this a bug from the latest version or is there something that I missed?
Strangely enough, when I checked the MVC demo page of tabstrip, the code won't produce k-state-active class at all. I assume your demo is using the latest version of your code. Why the difference? Cheers.