I am implementing a KendoGrid with server side paging. For some reason, 'pageSize' and 'skip' parameters are not being sent to my remote service. I have serverPaging: true set in the dataSource of the grid. Is there any other setting that is overriding this, making these two parameters unavailable?
Be sure that your controller action have the DataSourceRequest parameter ...
public ActionResult yourAction([DataSourceRequest] DataSourceRequest request)
and your return like that
return Json(yourlist.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
Related
I am using a rich text editor to type formatted text, as shown below:
I can get the HTML formatted text, which would look like this:
<p>This is my rich HTML Text</p>
Now I want to pass this HTML formatted text to my controller and my controller would put the text in an email and send it to the receiver.
The problem is HTML string is considered unsafe, so in order to pass it to my controller, I need to add [ValidateInput(false)] attribute to my Action method, like below:
[ValidateInput(false)] // <-- not able to hit the action method without this
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<JsonResult> Contact(string message)
{
if (!HttpContext.User.Identity.IsAuthenticated)
{
return Json(new { Authorize = "false" });
}
// email message to receiver
}
And this is the Ajax method which contacts the controller:
$('#contactBtn').click(function () {
var form = $('#__AjaxAntiForgeryForm');
var token = $('input[name="__RequestVerificationToken"]', form).val();
var message = quill.root.innerHTML; // <-- HTML formatted message
$.ajax({
url: "/Communication/Contact",
data: { __RequestVerificationToken: token, message: message },
dataType: 'json',
type: "POST"
});
});
So the above code works, but I am not sure if this is the right thing to do? Is there any security issue with the above code? Is there any encoding that I need to do on the HTML?
Actually ValidateInput attribute is related to XSS (Cross Site Security) issue.
XSS(Cross Site Security) is a security attack where the attacker injects malicious code while doing data entry. This code can be a javascript, vbscript or any other scripting code. Once the code is injected in end user’s browser. This code can run and gain access to cookies, sessions, local files and so on.
Now the good news is that XSS is by default prevented in ASP.NET MVC. So if any one tries to post JavaScript or HTML code with input he lands with the following error.
A potentially dangerous Request.Form value was detected from the client.....
But in real life there are scenarios where HTML has to be allowed, like HTML editors. So for those kind of scenarios we decorate our action method with ValidateInput attribute as follows:
[ValidateInput(false)]
public async Task<JsonResult> Contact(string message)
{
}
But there is problem of doing this. We are allowing HTML and script on the complete action which can be dangerous. Suppose the form we are posting have five input text fields, now the all five text fields can contain HTML and scripts.
Instead this Microsoft article suggest:
For ASP.NET MVC 3 or greater applications, when you need to post HTML back to your model, don’t use ValidateInput(false) to turn off Request Validation. Simply add [AllowHtml] to your model property, like so:
public class BlogEntry
{
public int UserId {get;set;}
[AllowHtml]
public string BlogText {get;set;}
}
So bottom line is that ValidateInput allows scripts and HTML to be posted on the whole action level while AllowHTML is on a more granular level.
For more details you can read ASP.NET Security - Securing Your ASP.NET Applications
Using [ValidateInput(false)] on the action method is not a good approach, as there could be other input parameters that don't get validated... using [AllowHtml] works if we are passing in a Model...
For this scenario, we could do what is explained in this this tutorial:
My solution is based on the tutorial above, except I have added sanitization logic to model binder, which means we allow the HTML input, but use HTMLSanitizer to sanitize the input.
Defined a custom model binder:
public class AllowHtmlBinder: IModelBinder
{
// use HtmlSanitizer to remove unsafe HTML/JS from input
private HtmlSanitizer _htmlSanitizer = new HtmlSanitizer();
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var request = controllerContext.HttpContext.Request;
var name = bindingContext.ModelName;
var unvalidatedInputMessage = request.Unvalidated[name]; // get the unvalidated input
var sanitizedMessage = _htmlSanitizer.Sanitize(unvalidatedInputMessage); // removed script or any XSS thread from user input
return sanitizedMessage;
}
}
And used it on the specific parameter:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<JsonResult> Contact([ModelBinder(typeof(AllowHtmlBinder))] string message)
{
if (!HttpContext.User.Identity.IsAuthenticated)
{
return Json(new { Authorize = "false" });
}
// email message to receiver
}
I am using Kendo UI with ASP.NET MVC. I am tying to use the Scheduler control. The Scheduler control is not posting the DataSourceRquest object back to the controller when I am writing
dataSouce.filter(criteria);
The criteria in this case is the filters populated using AND operator. The above line is not posting any filters back to the controller.
Also, even the scheduler's next date and previous date button are also not posting any date filters.
Is this expected behavior or am I missing something?
Conroller
public ActionResult GetList([DataSourceRequest] DataSourceRequest request)
{
return Json(_service.GetList(request), JsonRequestBehavior.AllowGet);
}
Javascript
dataSouce.filter(criteria); // Where dataSource is Kendo Scheduler dataSource
And criteria object in console looks like this --> Object{ logic: "and", filters: Array[1] }
But nothing is posted back to the MVC action method??
I'm new to ASP.NET MVC 5(MVC and Web API in general), I'm looking for a good approach to creating my viewmodel in the MVC controller based on data I get back from making a Web API call.
The web api call method returns data like this
public ActionResult GetConfigTable([DataSourceRequest] DataSourceRequest request)
{
var emp = new fpECMEntities();
IQueryable<Models.MyTable> empSecurity = emp.MyTable;
DataSourceResult result = empSecurity.ToDataSourceResult(request);
return Json(result, JsonRequestBehavior.AllowGet);
}
my views controller method looks like this
public ActionResult Config_Read([DataSourceRequest] DataSourceRequest request)
{
var configTable = Json(MySolution.API.Controllers.HomeController.GetConfigTable());
// fill in the code
return Json(result, JsonRequestBehavior.AllowGet);
}
Where the API is a separate project within the solution which keeps all the Models and acts as a DAL. So, here I need to add additional columns to the JSON data I get back from API before I send it off to the Grid in the view.
My questions is
Is this the right approach to create the viewmodel in my MVC controller by massaging the data here
Is it better to create a method within the API that generates all the data required for my ViewModel?
If #1 is ok, then what is the code to massage the data? do I have to deserialize the JSON data into Dataset and then add columns and return it as JSON again?
Any and all advice is greatly appreciated. BTW, I'm using the Kendo UI grid at the client, the types DataSourceRequest and DataSourceResult are from Kendo.UI.DataSourceRequest library.
Thanks
I've got a requirement to keep and display an incorrect entry on the view. It isn't possible to go to the next page without passing all validation.
For example, the use has to enter a date in text field in a certain format. Currently if the model binding fails it doesn't keep the invalid date text entry. I'd like to keep t and display it back to user with a vanadium failed message.
I'd like to know if this is achievable without creating a data holder type which temporarily hold the entered game and parsed value.
Yes, it is possible. Because you haven't posted any code, I'll just give you an example of how this can be achieved using server side validation.
Here is the [HttpGet] action method that serves up the form allowing the user to enter data.
[HttpGet]
public ActionResult Create()
{
// The CreateViewModel holds the properties and data annotations for the form
CreateViewModel model = new CreateViewModel();
return View(model);
}
Here is the [HttpPost] action method that receives and validates the form.
[HttpPost]
public ActionResult Create(CreateViewModel model)
{
if (!ModelState.IsValid)
{
return Create(); // This will return the form with the invalid data
}
// Data is valid, process the form and redirect to whichever action method you want
return RedirectToAction("Index");
}
You can also use return View(model); in the [HttpPost] action method instead of return Create();.
I'm looking to enable "saving" of form data prior to submission.
I want users to be able to save form progress, even when the form is in an invalid state, and then come back to it at a later time.
Now, my only problem is that I want to be able to use UpdateModel method to update my model. However, as the form is potentially invalid or just partially complete, this will throw an error.
Is there a way to annotate the following method such that validation is ignored in the SAVE instance?
[HttpPost]
public ActionResult Save(Model values)
{
var model = new Model();
UpdateModel(model);
}
I want to save having to write a 1-1 mapping for the elements being saved - which is my fallback option, but isn't very maintainable.
Give TryUpdateModel(model) a try, should fit your needs.
This won't throw an exception, and it will update the model and then return false if there are validation errors.
If you care about the errors, you check the ModelState in the false instance.
Hence, you can use it as so to always save changes:
[HttpPost]
public ActionResult Save(Model values)
{
var model = new Model();
TryUpdateModel(model);
model.saveChanges();
}