how to restrict HTML elements while allowing others - asp.net-mvc-3

How to only allow certain html tags in a text box
Example:
<Strong>
<p>
The code below is where I have been trying to implement the solution in a class created.
[Required]
(Code)
Public string car { get; set; }
How would I go about implementing the solution and is it possible at the point where (code) is written above.

First, you would need to disable the validation for you action with [ValidateInput(false)] attribute but you will need to use that carefully as it will turn off validation for the whole method. You may also disable validation for a particular attribute like :
[Required]
[AllowHtml]
Public string article { get; set; }
ASP.NET MVC3 has built-in attribute to disable validation at property level - so putting [AllowHtml] attribute on properties in model or view model will disable request validation. This is not safe and puts your site at risk. Now it's up to you to ensure that proper data format is provided so you may wan't to give a try a with Regular Expressions to filter out all html code except for the tags you need. You may wan't to take a look at this answer Regex to match all HTML tags except <p> and </p> to get you going.
example from msdn on how to use regex validation with data annotations :
public class Customer
{
[Required]
[RegularExpression(#"^[a-zA-Z''-'\s]{1,40}$",
ErrorMessage="Numbers and special characters are not allowed in the last name.")]
public string LastName { get; set; }
}
http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.regularexpressionattribute(v=vs.95).aspx
you may also try the safer way - to implement BBCode like feature. So instead of html tags you use pseudo html tags like [b] instead of < b >
this is easy to accomplish with jQuery :
assuming #text is a field populated with bbcode like text (not visible) and text2 is formatted display - visible :
$(document).ready(function(){
var text = $('#text').html();
text = text.replace("[b]","<b>");
text = text.replace("[/b]","</b>");
$('#text2').html(text);
});
it's not the smartest code but it was a quick one to show you a direction you can take.

The following Regular Expression allows only the Html tags specified:
[RegularExpression(#"^([^<]|<p>|</p>|<strong>|</strong>|a z|A Z|1 9|(.\.))*$")}
This allows for the html <p> </p> <strong> </strong> to be entered while not allowing any other tags.
Add other tags if required.

use AllowHtml attribute and then validate the content using IValidatableObject and Regex,
or write a custom validation attribute to allow only some html tags with Regex, see Phil Haack article http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx

[RegularExpression("^[^<>,<|>]+$", ErrorMessage = "Invalid entry.")]
public string FirstName { get; set; }
To avoid mvc error.

Related

Link in validation summary message

Is it possible to put a HTML link in validation summary message? For example I want to put a link to another page in case there is validation error:
#Html.ValidationSummary(False, "read more")
or
#Html.ValidationSummary(False, "read " &
Html.ActionLink("more", "helpforerror").ToHtmlString)
But in the browser the tag is escaped so it doesn't form a link.
I know you have accepted an answer, but i think my solution is more simple and will require less rewriting if you want to add links to existing validation summaries.
You need to put a {0} type format item in your validation message like below, which will be replaced by your link.
ModelState.AddModelError("", "Some error message with a link here {0}.");
then in your view call your validation summary like so:
#string.Format(Html.ValidationSummary().ToString(), Html.ActionLink("Click Here", "Action_To_Link_To")).ToHtmlString()
In this case i have used an extension method I added to the string object .ToHtmlString() that basically just converts the string to an HtmlString preventing any of the markup being escaped. it looks like this:
public static HtmlString ToHtmlString(this String str)
{
return new HtmlString(str);
}
Finally I chose another way to do it: create a div containing the link etc. outside of validation summary, and add the div only if modelstate is not valid:
#If Not ViewData.ModelState.IsValid Then
#<div>read more</div>
End If
This is inspired by an answer to similar question.
The validation text is encoded before the ValidationSumary or ValidationFor, etc...
you just need tu decode the html, then create an MvcHtmlString ...
Exemple :
#HttpUtility.HtmlDecode(Html.ValidationSummary().ToString()).ToMvcHtmlString()
this is an extension i have made to make MvcHtmlString :
namespace System
{
public static class StringExtension
{
public static System.Web.Mvc.MvcHtmlString ToMvcHtmlString(this string value)
{
return System.Web.Mvc.MvcHtmlString.Create(value);
}
}
}
or you can create an HtmlHelper if you plan to reuse this:
namespace System.Web.Mvc.Html
{
public static class FormHelper
{
public static MvcHtmlString ValidationSummaryEx(this HtmlHelper htmlHelper, bool excludePropertyErrors)
{
var original = htmlHelper.ValidationSummary(excludePropertyErrors);
var decoded = HttpUtility.HtmlDecode(original.ToString());
return decoded.ToMvcHtmlString();
}
}
}
Hope it help you or future viewer.
Note: it work for all validations Summary and ValidationFor ...
No, the default behaviour doesn't allow it, but you can make your own. This is what you need: Html raw in validationsummary
You can check if form is valid by jquery and update div with link text:
<div id="divToUpdate">
</div>
$('form').submit(function(){
if(!this.valid())
$('#divToUpdate').html("read <a href='anotherpage.html'>more</a>");
});
If you're sending back HTML in the ModelStateError, you can use this one liner:
#Html.Raw(HttpUtility.HtmlDecode(Html.ValidationSummary().ToHtmlString()))
It's very similar to what #Benoit had suggested, just without needing the extension.

Display required attribute message as html text in mvc3

I has required field like this
[Required(ErrorMessageResourceName = "AddCategoryCodeRequiredError", ErrorMessageResourceType = typeof(Resources.Category.Category))]
public string CategoryCode { get; set; }
and the error message in the resource file like this
<b>Required Field Missing</b> A code is required.
when the error displayed in the page the message part
<b>Required Field Missing</b>
displayed as is not as bold text.
how can I display the message as html??
The Html.ValidationSummary helper is designed to HTML encode the error message. This basically means that you cannot use HTML tags inside your error messages. If you wanted to do so you will have to write a custom helper to display it which doesn't perform encoding. Here's an example with a custom validation summary helper. The same is true for the ValidationMessageFor helpers.

MV3 Duplicate Query String Values for CheckBox (true,false for boolean)

I've created a fairly straight forward page with a check box:
#using (Html.BeginForm("MyController", "MyAction", FormMethod.Get))
{
#Html.CheckBoxFor(x => x.MyCheckBox)
<input type="submit" value="Go!" />
}
The URL is populated with the MyCheckBox value twice!? As such:
MyAction?MyCheckBox=true&MyCheckBox=false
It only duplicates the value if the check box is true. If set to false it will only appear once in the query string.
The code above is simplified as I have a couple of drop downs and a textbox on the form which work fine. I don't think there's anything unusual about the code which I've left out from this question.
Has anyone had a similar issue with query string parameters being duplicated?
This behaviour is by design of the checkbox control. The standard HTML checkbox control passes no value if it is not checked. This is unintuitive. Instead, the ASP.Net checkbox control has 2 elements, the standard control which is visible and also a hidden control with a value of 'False'.
Therefore, if the checkbox is not checked, there will be one value passed: False.
If it is checked, there will be two values, True and False. You therefore need to use the following code to check for validity in your code:
bool checkboxChecked = Request.QueryString["MyCheckBox"].Contains("True");
Accepted answer is correct however in my case in a recent development the MVC behaviour is misleading.
The MVC Html.CheckBox(...) and Html.CheckBoxFor(...) generate an extra input of 'type=hidden' with the same ID as the checkbox control, leading to the duplicate URL parameters. I got around this problem by simply including the mark up desired as follows:
#if(checkTrue){
<input type="checkbox" id="MyCheckBox" name="MyCheckbox" checked="checked">
}else{
<input type="checkbox" id="MyCheckBox" name="MyCheckbox">
}
Would be better wrapped upin a helper to use in place of the MVC code so the value check is encapsulated.
As part of my application, the controller maintains sets of query parameters using both form injection and link injection using helpers in order to preserve state (of paging/filtering controls for example) when clicked to navigate within the same controller scope. As a result of this feature, the check box element is always set back to false if the standard MVC helpers are used. It's a good thing I noticed and did not waste much time on this bug.
In my model, I had a collection of checkboxes like so:
public class PrerequisitesViewModel
{
public List<StudentPrerequisiteStatusViewModel> PrerequisiteStatuses { get; set; }
}
public class StudentPrerequisiteStatusViewModel
{
public long Id { get; set; }
public string Name { get; set; }
public bool IsSelected { get; set; }
}
In order to get everything to bind correctly, I had to actually convert the values from the querystring and parse them manually with the following code:
// fix for how MVC binds checkboxes... it send "true,false" instead of just true, so we need to just get the true
for (int i = 0; i < model.PrerequisiteStatuses.Count(); i++)
{
model.PrerequisiteStatuses[i].IsSelected = bool.Parse((Request.QueryString[$"PrerequisiteStatuses[{i}].IsSelected"] ?? "false").Split(',')[0]);
}
Alas, it works, but I can't believe this is necessary in MVC! Hopefully, someone else knows of a better solution.
I solve this issue with use #Html.HiddenFor
<input id="checkboxId" type="checkbox" value="true" onchange="changeCheckboxValue()">
#Html.HiddenFor(m => m.MyCheckBox, new { #id = "hiddenId" } )
<script>
function changeCheckboxValue() {
document.getElementById("checkboxId").value = document.getElementById("hiddenId").checked;
}
</script>

MVC 3 - Change Html.TextBox to Html.TextBoxFor

I am using html.textbox for 2 of my datetime field because I need to format them in a specific format but i don't know how to do it by html.textboxfor.
However, I realise i need to have the textboxfor for the validation in my model class to work:
[Required(ErrorMessage = "Storage Date is required")]
[DataType(DataType.DateTime, ErrorMessage = "Please input a valid date")]
public DateTime StorageDate { get; set; }
Any idea how can I change my Html.Textbox below into Html.TextBoxFor with the same setting??
#Html.TextBox("expirydate", String.Format("{0:ddd, d MMM yyyy}", DateTime.Now), new { id = "expirydate" })
#Html.ValidationMessageFor(model => model.ExpiryDate)
Appreciate any help... Thanks...
You don't really need to use TextBoxFor() for validation to work. If your TextBox has the same id as a field in the model, the model binder will pick it up. If you're talking about to get the unobtrusive validation features, you can always manually add the data-* attributes to your TextBox.
However, in this case it sounds like what you really want is a custom editor, using EditorFor(). It's a bit more work, but it will allow you to actually enforce the date/time formatting by giving the user something like a date/time picker control. The basic idea is:
Create a partial view called DateTime.cshtml that is bound to model of type Nullable<DateTime>, and put it into the Shared/EditorTemplates view folder.
Use jQuery and jQueryUI to put an HTML textbox that is styled as a date/time picker into the partial view.
Decorate the property on your model with the [DataType(DataType.DateTime)] attribute
Use Html.EditorFor(model => model.WhateverProperty)
Fortunately, date/time pickers are probably the most popular custom MVC3 editor, so there are plenty of examples to pick from; the code from this question works fine, just make sure to note the suggestion in the answer and replace this line in the partial view:
#inherits System.Web.Mvc.WebViewPage<System.DateTime>
with this:
#model System.DateTime?

MVC3 - 3 decimal places on type double with leading zero

I have a field for weight in Kgs (type double or use something else??).
In edit view I would like the user to enter numbers to the thousandth place.
In display view I would like the Kgs to appear like 560.250
Trying to learn MVC3 + Razor.
Willing to explore JQuery, use of regular expressions, validators, view templates, view models...
The "magic" of MVC based on conventions takes getting used to. Confused as to which approach to use.
Thank you in advance for your help.
You could use data annotations on your view model:
[DisplayFormat(DataFormatString = "{0:#,##0.000#}", ApplyFormatInEditMode = true)]
public double? Weight { get; set; }
and in your view
#Html.EditorFor(x => x.Weight)
will properly format the value in the input field.
Another possibility is to write a custom editor template for the double type (~/Views/Shared/EditorTemplates/double.cshtml):
#model double?
#Html.TextBox("", Model.HasValue ? Model.Value.ToString("#,##0.000#") : "")
and then in your view:
#Html.EditorFor(x => x.Weight)
or if you don't want to override all templates for all double types in your application you could put this into some custom template location like ~/Views/Shared/EditorTemplates/MyFormattedDouble.cshtml and then in your view:
#Html.EditorFor(x => x.Weight, "MyFormattedDouble")
Personally I prefer the first approach which uses data annotations to control the format of the double values.
To format the number just use
#string.Format("{0:0.00}", Model.Weight);
or
#Html.DisplayFor(x => string.Format("{0:0.00}", x.Weight));
#Html.EditorFor(x => string.Format("{0:0.00}", x.Weight));
to Validate
public class Model
{
[Required]
public double Weight{ get; set; }
}
I wouldn't constrain the precision they put in, just make sure that it is a valid number using javascript. You might also constrain input to only include numbers and a period.
If the user puts in something wrong (i.e. not compatible with a double type), MVC will complain when it tries to bind to the model.
its very simple
follow this method
so you have to insert DataFormatString="{0:#,##0.000#Kg}" only on gridview

Resources