Using pagedlist with form parameters - asp.net-mvc

I am using asp.net MVC 5 and Was wondering if there were any solutions out there that allowed me to use the PAGEDLIST library that can pass back input variables from the controller ALONG with passing back the .ToPagedList(pagenumber, pagesize) in the return view from the controller.
Here is the code i am working with:
In my Controller:
return View(tags.OrderBy(i => i.entry_no).ToPagedList(page ?? 1, 5));
In my View:
<div class="container-fluid">
<div class="row">
<div class="col-xs-4 input-group input-daterange" id="datepicker" style="margin-right: 30px">
#Html.EditorFor(model => model.startDate, new { #class = "form-control" })
<div class="input-group-addon">to</div>
#Html.EditorFor(model => model.endDate, new { #class = "form-control" })
</div>
<div class="col-xs-1 input-group">
<span class="input-group-addon">Desk:</span>
#Html.DropDownListFor(model => model.SelectedDesk,
new SelectList(Model.DeskOptions, "Text", "Value", Model.SelectedDesk), new { #class = "selectpicker" })
</div>
</div>
</div>
[...]
Page #(Model.Tag.PageCount < Model.Tag.PageNumber ? 0 : Model.Tag.PageNumber) of #Model.Tag.PageCount
#Html.PagedListPager(Model.Tag, page => Url.Action("Index", new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
So what i was hoping for was a way to update those editorfor/displayfor variables above along with passing back a pagedlist for table pagination.

Related

ASP.NET MVC - A potentially dangerous Request.Form value was detected from the client

Am trying to click save button to update what I have in text editor using ckeditor but I got this error
A potentially dangerous Request.Form value was detected from the client (OPTION_VALUE="Welcome to the Na...").
The controller is shown below
Controller
public ActionResult EditRegistrationGuideline(long id)
{
OPTIONS options = _optionsService.GetOption(id);
return View(options);
}
//
// POST: /Product/Edit/5
[HttpPost]
public ActionResult EditRegistrationGuideline(long id, OPTIONS options)
{
try
{
// TODO: Add update logic here
if (ModelState.IsValid)
{
options.OPTION_ID = id;
options.ACTION_STATUS = 0;
options.CREATED_DATE = DateTime.Now;
_optionsService.AddOption(options);
return RedirectToAction("Index");
}
}
catch
{
//return View();
ModelState.AddModelError("", "We cannot edit this Option. Verify your data entries !");
}
return View();
}
and the view is here
View
#{
//ViewBag.Title = "CreateRegistrationGuideline";
}
<div class="content-header clearfix">
<h1 class="pull-left">
<i class="fa fa-plus"> </i> Edit Registration Guideline
</h1>
<div class="col-xs-3 pull-right">
<input type="button" class="btn btn-block btn-warning" value="Back" onclick="location.href='#Url.Action("IndexRegistrationGuideline", "Options")'" />
</div>
<div class=" box box-body box-primary">
#using (Html.BeginForm("EditRegistrationGuideline", "Options", FormMethod.Post, new { #class = "form-horizontal", #enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#*<h4>OPTIONS</h4>
<hr />*#
#*#Html.ValidationSummary(true)*#
#Html.ValidationSummary(false, null, new { #class = "text-danger" })
<div class="row .col">
<div style="margin-top:20px" class="mainbox col-md-12 col-md-offset-0 col-sm-8 col-sm-offset-2">
<div class="panel panel-info">
<div class="panel-heading">
<div class="panel-title">Edit Option</div>
</div>
<div class="panel-body">
#*<div class="form-group">
#Html.LabelFor(model => model.OPTION_NAME, new { #class = "control-label col-md-2" })
<div class="col-md-10">*#
#*#Html.LabelFor(model => model.OPTION_NAME, new { #class = "control-label col-md-2" })
<div class="col-md-10">*#
#*#Html.EditorFor(model => model.OPTION_NAME)*#
#*#Html.HiddenFor(model => model.faculty_activation_date, new { #Value = System.DateTime.Now })*#
#Html.HiddenFor(model => model.OPTION_NAME)
#Html.ValidationMessageFor(model => model.OPTION_NAME)
<div class="form-group">
#*#Html.LabelFor(model => model.OPTION_VALUE, new { #class = "control-label col-md-2" })*#
<div class="col-md-10">
#Html.LabelFor(model => model.OPTION_VALUE, "Option Value")
#*<textarea class="form-control" placeholder="Enter Option Value" name="OPTION_VALUE" id="editor1"></textarea>*#
#Html.TextAreaFor(model => model.OPTION_VALUE, new { #class = "form-control", #id = "editor1" })
#Html.ValidationMessageFor(model => model.OPTION_VALUE, "", new { #class = "text-danger" })
</div>
</div>
#*<div>
#Html.LabelFor(model => model.OPTION_VALUE, "Option Value")
#Html.TextAreaFor(model => model.OPTION_VALUE, new { #type = "textarea", #id="editor1", #class = "form-control", #placeholder = "Enter Option Value", #autocomplete = "on" })
#Html.ValidationMessageFor(model => model.OPTION_VALUE, null, new { #class = "text-danger" })
</div>*#
#*<div class="form-group">
#Html.LabelFor(model => model.ACTION_STATUS, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ACTION_STATUS)
#Html.ValidationMessageFor(model => model.ACTION_STATUS)
</div>
</div>*#
</div>
<div class="panel-footer">
<div class="panel-title">
<div class="form-actions no-color">
<input type="submit" value="Save" class="btn btn-success" />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
}
#*<div>
#Html.ActionLink("Back to List", "Index")
</div>*#
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script src="~/Scripts/jquery-3.1.1.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<script src="https://cdn.ckeditor.com/4.5.7/standard/ckeditor.js"></script>
<script>
$(function () {
CKEDITOR.replace('editor1');
});
</script>
}
Please what do I do.
I use CKEDITOR
XSS error ("A potentially dangerous Request.Form value was detected from the client(...)").
Solution:
[ValidateInput(false)]
Differnce b/w them
AllowHtml:
The AllowHtml attribute can be applied to a Model property and it will disable the validation by ASP.Net MVC only for that particular property
Advantages
The AllowHtml attribute is developed for Model class.
The Scope is limited to specific property of the Model class.
It is the safe and recommended solution.
ValidateInput
The ValidateInput attribute can be applied to a Controller’s Action method and it will disable the validation by ASP.Net MVC only for that particular Action method.
Advantages
The Scope is limited to specific Action method of the Controller class.
If you have multiple properties accepting HTML content, then this method will reduce redundancy.
When Model class is not used for designing Form elements then this attribute is needed.For complete details Link
Just place ValidateInput(false) attribute on controller's action.
[HttpPost]
[ValidateInput(false)]
public ActionResult EditRegistrationGuideline(long id, OPTIONS options)
The other option is to place [AllowHtml] attribute on Model Property, have a look on SO post to get difference between them
ValidateInput(false) vs AllowHtml
I was experiencing a similar issue with the following error message A potentially dangerous Request.Form value was detected from the client.
As an alternative to the previous answers, I found encoding the value passed back to the controller worked. CKEditor allows you to do this by setting the config config.htmlEncodeOutput = true;.
The documentation for this can be found at: https://docs-old.ckeditor.com/ckeditor_api/symbols/CKEDITOR.config.html#.htmlEncodeOutput
I got this error while testing XSS on my site.
This is a very good feature that the model gives us that prevents XSS, CSRF from penetrating your site.
Do not disable it as much as possible.

How do I post varied length list to controller?

MVC4. I have a dynamic list on a view, a new textbox is added with button click (which adds a partialView) so user can enter a list of stuff. That is contained in a form element with a submit button.
In the controller I have tried three different types:
[HttpPost]
public ActionResult Index(IEnumerable<AccessoryVM> form)
{
-- form is NULL
[HttpPost]
public ActionResult Index(AccessoryVM form)
{
-- form has only the first item in the list
[HttpPost]
public ActionResult Index(FormCollection form)
{
-- seems to receive the list, but having trouble getting the values
All the examples I have seen are using a for list to add an index to each item, but they aren't using a dynamic list (it has a fixed length).
What should the Controller receiving type be?
EDIT to add more detail:
Button click appends partial view:
$("#add-item").on("click", function () {
$.ajax({
url: '/Accessory/AddItem',
cache: false,
success: function (html) {
$("#form-body").append(html);
}
})
return false;
})
Partial View:
#model EmployeeHardwareRequest.Models.ViewModels.AccessoryVM
<div class="form-group col-md-3">
#Html.LabelFor(model => model.ItemDescription, htmlAttributes: new { #class = "control-label" })
<div>
#Html.DropDownListFor(model => model.AccessoryId, Model.AccessoryDdl, new { #class = "form-control" })
</div>
</div>
<div class="form-group col-md-9">
#Html.LabelFor(model => model.ProductLink, htmlAttributes: new { #class = "control-label" })
<div>
#Html.EditorFor(model => model.ProductLink, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ProductLink, "", new { #class = "text-danger" })
</div>
</div>
Main View - partial is appended to the #form-body:
#using (Html.BeginForm("Index", "Accessory", FormMethod.Post, new { #id="accessory-form", #class = "form-horizontal" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div id="form-body">
<div class="form-group col-md-3">
#Html.LabelFor(model => model.ItemDescription, htmlAttributes: new { #class = "control-label" })
<div>
#Html.DropDownListFor(model => model.SelectedAccessory, Model.AccessoryDdl, new { #class = "form-control" })
</div>
</div>
<div class="form-group col-md-9">
#Html.LabelFor(model => model.ProductLink, htmlAttributes: new { #class = "control-label" })
<div>
#Html.EditorFor(model => model.ProductLink, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ProductLink, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<button id="add-item" class="btn btn-primary">Add Another Item</button>
</div>
<div class="col-md-6">
<input type="submit" value="Select Software" class="btn btn-default pull-right" />
</div>
</div>
}
Most likely, you have a binding issue. Assuming all you're posting is a collection of AccessoryVM, then the parameter should be List<AccessoryVM> form. However, in order for the modelbinder properly bind the posted values, your input names must be in a specific format, namely either form[N].Foo or just [N].Foo.
You haven't given any detail about what's going on in your view, but since these are dynamically added, you must be using JavaScript to add additional inputs to the page. If you're doing it via AJAX (returning a partial view), you'll need to pass the index to your endpoint so that it can be utilized to generate the right input names. If you're using something like Knockout, Angular, etc., you should ensure that whatever template is being used to generate the inputs takes an index into account.

Angular JS on Refresh loosing CSS

So weird things are happening. I have an angular page with routing, repeat etc., and it works fine. But if I press F5 in it, it always looses the CSS. I'm refreshing a partial view which is tied to a _Layout. So whenever I browse thru my page and press F5 on any page which is a partial view ONLY the partial view is refreshed and I loose all my CSS and layout elements. Why is that?
I'm using MVC btw.
For routing I'm using:
$routeProvider
.when('/Account/PersonalInformation', {
templateUrl:
function (params) {
return "/Account/PersonalInformation/"
}
})
EDIT
as per request, PersonalInformation.cshtml, nothing special:
#using (Html.BeginForm("PersonalInformationJSON", "Account", FormMethod.Post, new { id = "editUserForm" }))
{
<div class="account_container">
<div class="user_data background_black">
<div class="panel panel-default width-470 no_border">
<div class="panel-body head_title_background no_padding"><h4 class="white margin-left30 bold">PERSONAL_DATA<h4></div>
</div>
<ul>
<li>
<div class="label">
#Html.Label(FIRSTNAME)
#Html.Label(":")
</div>
#Html.TextBoxFor(m => m.Edit.FirstName, new { #class = "textbox_disable", #readonly = "readonly" })
</li>
<li>
<div class="label">
#Html.Label("LASTNAME")
#Html.Label(":")
</div>
#Html.TextBoxFor(m => m.Edit.LastName, new { #class = "textbox_disable", #readonly = "readonly" })
</li>
<li>
<div class="label">
#Html.Label(.("USERNAME"))
#Html.Label(":")
</div>
#Html.TextBoxFor(m => m.Edit.UserName, new { #class = "textbox_disable", #readonly = "readonly" })
</li>
<li>
<div class="label">
#Html.Label("BIRTHDATE")
#Html.Label(":")
</div>
<label class="textbox_disable">#Model.Edit.BirthDate.ToString("dd.MM.yyyy")</label>
</li>
<li>
<div class="label">
#Html.Label("TYPE_OF_LICENSE")
#Html.Label(":")
#Html.ValidationMessageFor(m => m.Edit.WebTypeOfLicense, "", new { #class = "red" })
</div>
#Html.DropDownListFor(m => m.Edit.SelectLicenseId, Model.Edit.WebTypeOfLicense, "Choose type of license", new { #class = "textbox",id="type_of_license" })
</li>
<li>
<div class="label">
#Html.Label("LICENSE_NUMBER")
#Html.Label(":")
#Html.ValidationMessageFor(m => m.Edit.IdentificationNumber, "", new { #class = "red" })
</div>
#Html.TextBoxFor(m => m.Edit.IdentificationNumber, new { #class = "textbox", id="licence_number" })
</li>
</ul>
}
Controller:
public ActionResult PersonalInformation(ManageMessageId? message, IndexPageModel model)
{
model.Edit = new EditModel();
model.Edit.Country = new SelectList(CommonDbService.GetAllCountry(), "Id", "Name");
model.Edit.WebTypeOfLicense = new SelectList(CommonDbService.GetAllLicense(), "Id", "Name");
WebUser user = WebUser.FindByUsername(User.Identity.Name);
ViewBag.StatusMessage =
message == ManageMessageId.ChangeDataSuccess
? "Your data has been changed."
: "";
UserDebitInformation userDebitInformation = UserDebitInformation.FindDebitInfoByUserId(user.Id);
model.Edit.UserName = user.UserName;
model.Edit.FirstName = user.FirstName;
model.Edit.LastName = user.LastName;
model.Edit.BirthDate = user.BirthDate;
model.Edit.SelectLicenseId = user.TypeOfLicence.Id;
model.Edit.IdentificationNumber = user.IdentificationNumber;
return View(model);
}

</br> tag not working in MVC view

Not sure if this is a MVC or Razor problem. But I can't put a line break in my view. This is the code on the index.cshtml
#using (Html.BeginForm("Create", "Vacant", FormMethod.Post, new { role = "form" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary("", new { #class = "text-danger" })
<!--TITLE-->
<div class="form-group">
#Html.LabelFor(m => m.Title, new { #class = "col-md-3 control-label" })
<div class="col-md-12">
#Html.TextBoxFor(m => m.Title, new { #class = "form-control" })
</div>
</div>
<!--DESCRIPTION-->
<div class="form-group">
#Html.LabelFor(m => m.Description, new { #class = "col-md-3 control-label" })
<div class="col-md-10">
#Html.TextAreaFor(m => m.Description, new { #class = "form-control" })
</div>
</div>
<br /> ----> HERE
<!--TABS-->
<div class="form-group">
<div class="col-md-10">
As you can see I put the line break tag before to displayed the third field (Project) in my View.
The View is displayed without any error. However, the line break is not rendered between the 2nd and 3rd fields. Causing those two fields one after another with any space on them.
This is the screenshot
How could I put a line break between those two fields? Is there any #Html helper or Razor code to do that?
Thanks!
Try this
<div style="clear:both;margin-bottom:20px">
<!--TABS-->
<div class="form-group">
You can insert one more Div Between them.
OR
You can decorate the TAB Div with some STYLE like-
<div class="form-group" style="margin-top:20px">
OR
You can insert one more <P /> Between them.

Retrieving dropdown values from partial view during post method

I need to get the selected dropdown value from partial view and included in the CategoryID in the Book class...
[Authorize]
public PartialViewResult GetAllCategory()
{
ProcessSVC.Category newCategory = new ProcessSVC.Category();
newCategory.ChildCategories = obj1.GetAllCategories(String.Empty);
return PartialView(newCategory);
}
GetAllCategory.cshtml (PartialView)
#model MvcAdminTemplate.ProcessSVC.Category
#Html.DropDownListFor(m => m.ParentID, new SelectList(Model.ChildCategories, "ID", "DisplayName"), new { #class = "form-control" })
Create View:
[Authorize]
[HttpPost]
public ActionResult Create()
{
MvcAdminTemplate.ProcessSVC.Book oBook = new ProcessSVC.Book();
return View(oBook);
}
Create.cshtml
#model MvcAdminTemplate.ProcessSVC.Book
#{
ViewBag.Title = "Create";
}
#Html.Partial("_LeftMenu")
<!-- content -->
<h2>Create</h2>
<div class="col-md-10">
#using (Html.BeginForm("Create", "Books", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="row">
<div class="bootstrap-admin-no-table-panel-content bootstrap-admin-panel-content collapse in">
<form class="form-horizontal">
<fieldset>
<legend>Add Book</legend>
<div class="form-group">
<div class="col-lg-2">
#Html.LabelFor(m => m.BookName, new { #class = "control-label" })
</div>
<div class="col-lg-10">
#Html.TextBoxFor(m => m.BookName, new { #class = "form-control", type = "text" })
<p class="help-block"> </p>
</div>
</div>
<div class="form-group">
<div class="col-lg-2">
#Html.LabelFor(m => m.Description, new { #class = " control-label" })
</div>
<div class="col-lg-10">
#Html.TextBoxFor(m => m.Description, new { #class = "form-control ", type = "text" })
<p class="help-block"> </p>
</div>
</div>
<div class="form-group divCategory">
<div class="col-lg-2">
#Html.Label("Parent Category", new { #class = " control-label" })
</div>
<div class="col-lg-10">
#Html.HiddenFor(m => m.BookId, new { #class = "hdn-id" })
#Html.Action("GetAllCategory","Books")
<span class="help-block"> </span>
</div>
<button type="submit" class="btn btn-primary">Save changes</button>
<button type="reset" class="btn btn-default">Cancel</button>
</div>
</fieldset>
</form>
</div>
</div>
}
After submission of the above form i need to get Book attributes and Category "Selected Category".
[Authorize]
[HttpPost]
public ActionResult Create(ProcessSVC.Book oBook)
{
oBook.LanguageID = 1;
_service.AddBooks(oBook.ActualPrice,oBook.ActualPriceString, oBook.Author, oBook.BookId, oBook.BookName, oBook.CategoryID, oBook.Currency, oBook.CurrentPrice, oBook.CurrentPriceString,
oBook.Description, oBook.DiscountPercentage, oBook.DiscountValue, oBook.LanguageID,
oBook.NativeLanguageName, oBook.Publisher);
TempData.Add("SuccessMessage", " New book " + oBook.BookName + " Added !");
return RedirectToAction("Index");
}
Please suggest me.
To correctly bind your model, you need to create the dropdown in the main view. This line in you partial view
#Html.DropDownListFor(m => m.ParentID, ....
will render a select
<select name="ParentID" ...
but you model is expecting a property named CategoryID
In you Create() method, generate the SelectList and assign to a view model property or to ViewBag and then (instead or #Html.Action("GetAllCategory","Books") use
#Html.DropDownListFor(m => m.CategoryID, ....
use this line in your GetAllCategory.cshtml file
#Html.DropDownList("CategoryID", new SelectList(Model.ChildCategories, "ID", "DisplayName"), new { #class = "form-control" })

Resources