I have an ASP.NET MVC app. My app is passing a name to/from the database. I've recently discovered a bug associated with ampersands (&).
In my database, I see the name "A & W".
I am displaying this value in my UI using the following:
<input id="Name" name="Name" value="#Html.Raw(Model.Name)" />
When I view the source, I can see that the following HTML gets rendered in the browser.
<input id="Name" name="Name" value="A & W" />
So far, so good. However, when I click save, and I set a breakpoint in my controller action, I can see the Name property on my Model is now "A & W". What's worse is, everytime I save it, additional amp values get added.
How do I remedy this?
Thanks!
I had a similar problem, so I used the AllowHtml attribute on my property in my model.
[AllowHtml]
public string Name { get; set; }
If you aren't using Code First, you can apply this attribute on top of your action also:
[HttpPost]
[AllowHtml]
[ValidateAntiForgeryToken]
public ActionResult Modify(ModelClass model) {}
Related
My model:
public class VerifyModel
{
public string PIN { get; set; }
public int Attempts { get; set; }
}
My view:
#Html.HiddenFor(m => m.PIN)
#Html.HiddenFor(m => m.Attempts)
On entry into the view, I inspect Model.PIN and Model.Attempts and they contain the correct values passed from the controller, where Attempts is non-zero. The Html rendered is however:
<input id="PIN" name="PIN" type="hidden" value="xxxx" />
<input data-val="true" value="0" data-val-number="The field Attempts must be a number." data-val-required="The Attempts field is required." id="Attempts" name="Attempts" type="hidden"/>
The value of Attempts is always 0! And I did not specify anywhere that the Attempts field is mandatory.
How do I solve the problem of int properties in the model?
If I've understood your question correctly, you're having problems with Attempts not incrementing after the form is posted back with an incorrect PIN. If that assumption is correct then you're experiencing this problem because of the way ModelState works.
The short answer to the problem is simply to call ModelState.Remove from your action:
[HttpPost]
public ActionResult YourAction(VerifyModel model)
{
ModelState.Remove("Attempts");
model.Attempts++;
return View(model);
}
If you'd like a full explanation of why this is the case, see ASP.NET MVC’s Html Helpers Render the Wrong Value!. Excerpt:
Why?
ASP.NET MVC assumes that if you’re rendering a View in response to an HTTP POST, and you’re using the Html Helpers, then you are most likely to be redisplaying a form that has failed validation. Therefore, the Html Helpers actually check in ModelState for the value to display in a field before they look in the Model. This enables them to redisplay erroneous data that was entered by the user, and a matching error message if needed.
I am working with an asp.net mvc web application and i have a text input field to enter a search criteria, but my question is how i can define that this field is required incase the user click on the search button. i was thinking of manually adding the following data dash attributes, to simulate how the [Required] model data annotation works .
<input name="selectedUserNames" type="text" data-val="true" data-val-required= "Please enter a value." data-autocomplete-source= "#Url.Action("AutoComplete", "SecurityGroup")" />
<span class="field-validation-valid" data-valmsg-for="selectedUserNames" data-valmsg-replace="true"></span>
<input type="submit" value="Seach" />
What you are doing is not a clean solution, and it only works on the client side. You should create a SearchViewModel like below and pass it to your View:
public class SearchViewModel
{
[Required]
public string Search { get; set; }
}
And, in your View:
#Html.TextBoxFor(model => model.Search)
#Html.ValidationMessageFor(model => model.Search)
as noted in previous answer, enabling only client side validation is not a complete solution. what if the client has disable javascript on their browser? then your validation want fire.
best option you have is to use DataAnnotation [Required] attribute. In your view enable client side validation.
If the client has disable javascript on browser server side validation will fire.
I know similar questions have been asked regarding complex model binding in ASP.NET MVC, but I am having a problem binding because of a lack of a sufficient prefix coming back on the POST and wondered if there were an easy solution.
I have a view Model that looks something like this:
public class ViewModel<Survey, Contact>
{
public Survey Model { get; set; }
public Contact Model2 { get; set; }
}
I then have an action method like this that accepts the POSTed
public ActionResult Survey(
string id, string id2, SurveyViewModel<Survey, Contact> model)
{
// code goes here...
}
In my form, the first two id's are from the URL route and I then have form code (using #Html.EditorFor(x => x.Model.SurveyName) or similar), generated with names like this:
<input class="text-box single-line" id="Model_Email"
name="Model.Email" type="text" value="" />
A post works if I change the name from Model.Email to model.Model.Email, but I am trying to avoid having to create a custom model binder.
Is there
A setting I can make in the view to change the name for all fields rendered in a view using the #Html.EditorFor typed view helpers?
Something I can change using the Bind attribute on the action that would allow it to default binding to that object?
The answer may be "build a custom binder", but I just wanted to pose the question before biting that off.
Thanks for the help. Best Regards,
Hal
You can pass custom viewdata with custom HtmlFieldPrefix to view. Every control rendered with helper will have that prefix.
ViewData.TemplateInfo.HtmlFieldPrefix = "prefix here";
Take a look at this: Forcing EditorFor to prefix input items on view with Class Name?
In ASP.NET MVC, on [HttpPost] methods, the MVC runtime will automatically maps and transfers the data from the form fields in the front end into a View Model, based on field names.
How can I accomplish the same thing in ASP.NET WebForm?
e.g. I have an object called Person with FirstName and LastName properties.
I have a WebForm page with Textbox controls with FirstName and LastName respectively.
When pressing Submit on the form, is there a way to automatically bind FirstName and LastName to the Person object in the code-behind Button_Click event?
ASP.net 4.5 is actually going to have built in Web Forms model binding.
The Gu has a post on it and a few other things here...
http://weblogs.asp.net/scottgu/archive/2011/09/05/web-forms-model-binding-part-1-selecting-data-asp-net-vnext-series.aspx
You can do this in webforms v4.5 using model binding. It's a way we call as Ad-Hoc Model Binding where you can bind to controls without using data bound controls such as formview. I plan to blog about it but following code describes the blog in short
The following is how your markup will look.
My model has 2 properties: name and description
Name<input type="text" name="Name" value=" " id="Name" />
<br />
Description<input type="text" name="Description" value=" " id="Description" />
<br />
<asp:Button Text="Submit" runat="server" OnClick="Unnamed_Click" />
The following is the code in the button click handler.
category is my model. In this case the model binding system pulls in the value from the form value provider which looks in the form collection.
var category = new Category();
var formValueProvider = new FormValueProvider(ModelBindingExecutionContext);
TryUpdateModel(category, formValueProvider);
if (ModelState.IsValid)
{
// save changes to database
}
Perhaps the easiest way is to assign the values explicitly in the Page_Load event, whenever it is a postback. Something like this:
if (this.IsPostBack)
{
person.FirstName = FirstNameTextBox.Text;
person.LastName = LastNameTextBox.Text;
}
Or were you looking for a more declarative approach?
Take a look at Model Binder for ASP.NET Web Forms. It is doing what you want - maps postback data to class via custom attributes applied to its properties.
Does anyone know of any examples or tutorials of an MVC view that shows parent/child data all on one form, and allows all the child records to be editable?
For example, say I have a table of people and another containing the vehicles they own. One one form, I want to show every vehicle for a given person, and make the data elements editable (i.e. license plate number, car color, etc.) in case there are mistakes. I don't want to jump to a separate edit form for each vehicle.
My attempts thus far have gotten me to the point where I can display the data, but I can't get it to post back to the controller. I've tried to narrow down the problem as far as I could here, but I'm still not getting it, and I think a broader example may be in order. Any ideas?
You can try something like this.
Suppose you have this object :
public class Vehicle
{
public int VehicleID { get; set; }
public string LicencePlate { get; set; }
public string Color { get; set; }
}
And this is your controller action that you'll use to edit vehicle details (where you'll post the form) :
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditVehicles(int Owner, Vehicle[] vehicles)
{
//manipulate the data, then return back to the list
return RedirectToAction("YourAction");
}
Then you should set your form this way :
<!--have a form for each person, listing their vehicles-->
<form action="/EditVehicles" method="post">
<input type="hidden" name="Owner" value="25" />
<input type="hidden" name="Vehicles[0].VehicleID" value="10" />
<input type="text" name="Vehicles[0].LicencePlate" value="111-111" />
<input type="text" name="Vehicles[0].Color" value="Red" />
<input type="hidden" name="Vehicles[1].VehicleID" value="20" />
<input type="text" name="Vehicles[1].LicencePlate" value="222-222" />
<input type="text" name="Vehicles[1].Color" value="Blue" />
<input type="submit" value="Edit" />
</form>
This will help the DefaultModelBinder to correctly bind the form data to your model in your controller. Thus Response.Write(vehicles[1].Color); on your controller, will print "Blue".
This is a very simple example, but I'm sure you get the idea. For more examples about binding forms to arrays, lists, collections, dictionaries, take a look at here.
I think the best you can get around this is by using AJAX posts, Whenever the user clicks on the submit button, You can hook in that event, create a JSON array of the things you want to persist and send it across.
The other way of course is to get all the information from the "FormCollection" object in the POST action. You just need to iterate through all the keys parse the data and then process it.