Html encoding in MVC input - asp.net-mvc

I'm working through NerdDinner and I'm a bit confused about the following section...
First they've added a form for creating a new dinner, with a bunch of textboxes delcared like:
<%= Html.TextArea("Description") %>
They then show two ways of binding form input to the model:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create() {
Dinner dinner = new Dinner();
UpdateModel(dinner);
...
}
or:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Dinner dinner) { ... }
Ok, great, that all looks really easy so far.
Then a bit later on they say:
It is important to always be paranoid
about security when accepting any user
input, and this is also true when
binding objects to form input. You
should be careful to always HTML
encode any user-entered values to
avoid HTML and JavaScript injection
attacks
Huh? MVC is managing the data binding for us. Where/how are you supposed to do the HTML encoding?

You generally (but not always) want to HTML encode the values before writing them out, typically in your views, but possibly from the controller as well.
Some info here: http://weblogs.asp.net/scottgu/archive/2010/04/06/new-lt-gt-syntax-for-html-encoding-output-in-asp-net-4-and-asp-net-mvc-2.aspx

Related

Does MVC remember checkbox values after submit?

I'm a php head and getting to grips with ASP.NET MVC 5.
In php, after submitting checkbox fields, in order to post back the form with the checkboxes you checked initially set to true, you have to run a if isset on em.
However reading up on model binding in mvc, it seems that this is done automatically for you, i.e checkboxes are returned after form submit checked, if originally selected, using either the HTML.CheckBox or HTML.CheckBoxFor helpers.
Is this the case, or am I expecting too much of MVC?
No, ASP.NET MVC doesn't remember checkbox values after they're submitted. Being an HTTP application as soon as ASP.NET MVC has rendered the HTML it ends the request and forgets everything about what it's just done. Then upon submitting a form ASP.NET MVC processes the incoming HTTP request and maps it to your model via its model binding (more on how it does this in a moment).
Having come from a PHP background myself this is one of those questions I always had when starting with ASP.NET MVC.
With ASP.NET MVC you have to remember that you're working within the context of a complete framework, and in order to ensure you're as productive as possible ASP.NET MVC will take care of a lot of the mundane work for you - ASP.NET MVC's model binding is a perfect example of this.
When submitting a form, the ASP.NET MVC framework will parse all incoming post data and attempt to automatically map it to the values you're providing it via your controller action.
So where as in PHP you'd normally do something along the lines of:
if(isset($_POST['checkboxValue'])) {
$checkboxVal = $_POST['checkboxValue'];
}
ASP.NET MVC will automaltically bind the incoming post data to your action parameter like so:
[HttpPost]
public ActionResult Submit(bool checkboxValue){
}
It does this by checking the parameter name (checkboxValue) matches that of the post data array key, and that the type also matches up. For instance, if you were to change the above checkboxValue from a boolean to a string and change the name, then ASP.NET MVC's model binding will be unable to match the property to the post data and will not automatically set the value for you.
It's also worth noting that ASP.NET MVC's model binding doesn't know how you created the checkbox.
The HTML.CheckBox and HTML.CheckBoxFor html helpers are purely a means to make it easier for you to create the HTML. If you were to manually write the HTML yourself then the model binder will still successfully bind the submitted data.
Edit:
As #DrinkBird has quite rightly pointed out, you're also able to access all of your form's post data by using the FormCollection instance like so:
[HttpPost]
public ActionResult Submit(FormCollection postData){
}
This collection represents all of the data posted to the Submit action.
Yes, model-binding should allow you to retrieve the value of a checkbox on submission.
if your model looks like:
public class myModel
{
public bool myBool {get; set;}
}
and in your HTML, you've used the helper
#Html.CheckBoxFor(m => m.myBool)
Then in your post action to handle the submission:
[HttpPost]
public ActionResult MyAction(myModel model)
{
var whatsThis = model.myBool;
}
...whatsThis will be true if the checkbox was checked, false if not.
Part of why this works is that when you use #html.CheckBoxFor, it also places a hidden form field that will pass false if the box is unchecked, to aid with model binding -- if it didn't, per HTTP there would be no varibalbe 'myBool' submitted in the post-vars collection.
If you return this model back into the form (say, if it didn't validate), then the form will re-present the checkbox in whatever state it was in on submission:
[HttpPost]
public ActionResult MyAction(myModel model)
{
if(!ModelState.IsValid)
{
return View(model);
}
else
{
//do success
}
}

MVC, PartialView has what looks like postback data?

I'm new to MVC and I'm trying to make my first Ajax page, PartialView.
What I have is an action that looks like this
[HttpGet]
public PartialViewResult MainContent()
{
return PartialView(new ClockingModel());
}
[HttpPost]
public PartialViewResult MainContent(SingleClocking SingleClocking)
{
// update logic
return PartialView(myClockingModel);
}
What I'm finding is that the view renders, I enter some data and it posts back correctly. My partial view includes a select:
#Html.DropDownListFor(x => x.SingleClocking.InWhen, new SelectList(Model.DropDownValues, Model.DefaultValue))
The select shows the value that I changed on the GUI, not the new DefaultValue?
If this was plain Asp.Net I would assume this was because of postback data or viewstate but MVC doesn't use either of these?
I can see the view being returned via fiddler, it shows the select with the value as per the client, not the value I expected to see via the server.
I'm sure I'm just missing something simple here, any hints?
Also, could I look at the value of the View on the server? This won't work but something like: string viewText = PartialView(myClockingModel);
p.s. I don't think it's caching, I tried switching that off with an attribute
And even though I searched for a while before asking this I finally found the answer.
I feel a bit better knowing that Rick Strahl had the same confusion.
Posting as an answer for others to find
Long story short, this is by design, the blog is worth reading
http://weblog.west-wind.com/posts/2012/Apr/20/ASPNET-MVC-Postbacks-and-HtmlHelper-Controls-ignoring-Model-Changes

Why and when to use Ajax services and jQuery in ASP.NET MVC?

May be this sounds very stupid question but I'm a student who just came to know about MVC and I find it very interesting. Also, I have very little or no knowledge about Ajax and jQuery. I have been creating some basic applications like posting a comment or a blog post without using Ajax services or jquery. Now I've come to a part where I see Ajax services being called and custom jQuery code are being written.
Let us consider a small example where one can add comment on the main page and after the comment being written and submitted, it appears on main page.
Imagine a controller with following functions
public class CustomAjaxController : Controller
{
//
// GET: /CustomAjax/
private static readonly List<string> Comments = new List<string>();
public ActionResult Index()
{
return View(Comments);
}
[HttpPost]
public ActionResult AddComment(string comment)
{
Comments.Add(comment);
return RedirectToAction("Index");
}
}
I know using list of string to store the comments is not good idea but for the sake of simplicity and to explain my point I've used it. Also I don't have model but again for same reason.
#model IEnumerable<string>
<h4>comments</h4>
<ul id ="comments">
#foreach (var comment in Model)
{
<li>#comment</li>
}
</ul>
<form method="POST" id="commentsForm"
action = "#Url.Action("AddComment")">
#Html.TextArea("Comment", new{rows =5, cols =40})
<br/>
<input type ="submit" value="Add comment"/>
</form>
Now, I've seen same thing being done using jquery and ajax requests. But why should i do it to achieve same result, or how do I know this is the right place to use ajax requests.
But why should i do it to achieve same result, or how do I know this
is the right place to use ajax requests.
AJAX offers a couple of benefits:
It saves bandwidth because only the portion of the page that you want to be updated actually is sent over the wire. In your sample code you are reloading the entire HTML even if only one comment is added on a single place
It is asynchronous meaning that the user can do other things on the page while waiting for the server side processing
You can use it whenever you want to take advantage of one of those things.

What is "posted" in ASP.NET MVC applications?

As I review more code and blog posts from lots of MVC sources, I still haven't wrapped my mind around what is "posted" when a request is made. I realize MVC doesn't support post, but I'm having trouble finding resources that can explain it well enough to understand.
Inside the controller's public ActionResult nameOfAction(what the heck goes here?) { ... } what are my parameters?
Sometimes it looks like Visual Studio scaffolds (int id, MyObject myobject) for an Edit-style action--it includes something from my model, but not always.
Sometimes, it's (int id, FormCollection collection) for a delete-style action. Why not use the modeled object here? Is a FormCollection object always "posted"?
Sometimes, I see (RouteInfo routeInfo) which isn't recognized in my MVC2 Intellisense (is this MVC1 only or something?)
How can/do/should I establish these parameters? I think this will help me a lot at design time.
What gets post back from a form in MVC is the form data which includes each form element in a keyvalue pair.
If you only need this information then you would use:
public ActionResult nameOfAction(string name, string lastName, string etc)
MVC has some smart data model binding which takes the form data and automatically creates an object which is part of you domain model. For instance it could automatically create a Person object with the provided form data.
I believe there is a security concern with this as a user of your site may post data which is not part of your form and guess what your models are to inject their own data.
I dont think this is a massive issue though and this is the way I would go.
I think you can use the anti-forgery helper to prevent users from posting back data which is not allowed in a form. anti-forgery
Use strongly typed views with a view-model and the strongly typed helpers. Then when you POST, you should get an instance of that view-model out.

using dynamic as type of MVC strongly typed view

I have a page for creation of dynamic entities.
<%# Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
...
I have two actions:
public ActionResult Create()
{
dynamic model = ...
return View(model);
}
[HttpPost]
public ActionResult Create(dynamic(1) entity)
{
...
}
Well, the problem is that the entity comes empty from the page. If I change dynamic in (1) for the real type it works fine.
I'm not 100% on this, but I think the problem is that the default model binder has no idea what to do with a 'dynamic' type, since it doesn't have any defined properties to reflect over. You'd need to write your own model binder that would use the form input names instead, which is dangerous/unreliable because the form can be modified on the client side.
I've explored dynamically-typed ViewPages before (here on SO actually: Dynamic typed ViewPage), and I've come to the conclusion that it really doesn't give you anything in most situations. At least, not yet (MVC 3+ could be different story).
And here's some notes from Phil Haack on the matter: http://haacked.com/archive/2009/08/26/method-missing-csharp-4.aspx

Resources