I have recently have been reading a lot regarding using ASP.NET MVC5. One thing that I am not sure of is one of the books I read states that you should use HttpServerUtility. HtmlEncode in your views in order to prevent XSS attacks, however I then read something that said view items automatically use this unless you use the http raw method. When is it prudent to use HttpServerUtility.HtmlEncode in your views and how can you tell when it is needed and when it is not without having to test every piece of input for XSS injection?
You're some-what accurate. Properties on your Model that do not implement IHtmlString will be encoded by default (therefore preventing most XSS attacks). If they do implement that interface, they will be output as-is (as the interface assumes you are generating some form of markup).
To answer the primary question, "when is it prudent": When you are outputting user input to your page. If you have a custom helper written to deliver an IHtmlString, it's advisable within that method to encode it (as part of the final output). This holds true for any kind of data that may be output to the page and was originally generated (or modified thereafter) by a user.
Related
When creating an interactive form or other kind of web page, there are a couple of options with knockoutjs. One could create a strongly-typed view and pass a model to it from a controller. On the other hand, one could just as easily start with a plain old html document, and have it initialize itself by calling action methods (JsonResult or otherwise) after the initial load.
Also when starting out the page as an MVC view, you could use HtmlHelpers along with plain old html markup to initialize the view. Another option is to serialize the model state as json to a hidden field, and use that to initialize the view.
In my experience, during first load, there can be a delay when you let ko initialize the view. Whether you construct a viewmodel by passing json from a serialized hidden field, or rely on it to invoke various services to load the data, there is a moment before the page is "ready". These kinds of delays can be avoided by initializing the page with HtmlHelpers, etc, but such initialization could also incur additional costs (extra initialization logic in the controller, default content in the views, etc).
Which way of initializing a page is the most MVVM? Is it a bad idea to use HtmlHelpers in the views, or to use cshtml at all? If not, where do you draw the line between view and viewmodel?
"The most MVVM" is a hard question to answer, especially considering that we are already mixing patterns with MVC and Knockout.
I would think that letting Knockout do all the work of initilization would be "the most MVVM", but rigid adherance to a pattern when you are having issues is not a good idea. If KO setting values after the DOM is ready causes problems that you can fix by letting the HtmlHelpers initialize the page, then do what works. Since the HtmlHelpers will let you set the data-bind attributes at the same time, this feels like a good solution, and I have done this before with good results.
I would say that storing JSON in a hidden field is not a good idea though. You can directly encode your model into JSON by using this in your javascript:
var initialData = #Html.Raw(Json.Encode(Model));
This is a good solution since the page starts out with the data your controller sends it, without needing a second request.
You may have to think about what trade-offs you want to make. If you want purity and no code duplication, you might have to accept the issue of KO taking a little time to initialize the page. If you want a perfect User Experience, you may have to sacrifice a little purity.
I have a situation in an MVC3 app where I would like to be able to set the name attribute on some html being generated by a helper (DropDownList).
It appears this is not possible. Apparently the helpers silently override whatever value you may specify for the name attribute in the html attribute object that you pass to the helper.
I'd like to confirm that before I waste too much more time on trying to work with the existing helpers.
And, as an aside, if it is not possible by design...I think that's a foolish limitation in the MVC framework. Yes, I know that assigning the wrong name attribute can break the automatic model binding. But I should be able to do that when I need to. After all, I can always write the raw html using whatever name attribute I chose. The helpers should help, not be a straitjacket.
Edit to discuss whether editor templates maintain navigational context
Darin, I am using editor templates (I was using the term "partial" generically, since editor templates are a special kind of partial view).
Editor templates do modify the HtmlFieldPrefix -- that's how I noticed I had a problem :). I was using a call like this:
// call in higher level partial - context is 'eae'
#Html.EditorFor(m => m.Value)
...
// inside editor template for typeof(Value) context is 'eae:Value'
That context shift is needed to keep the default binding mechanism working properly. I'm using a different approach, where I want the context to stay fixed throughout a call chain of partials (i.e., as execution burrows down into deeper partials I want the context to stay the same).
This is by design. The HTML helpers do not allow you to override the name attribute. They generate the name based on your view model so that the default model binder is able to properly bind the values according to the well established conventions when the form is submitted.
And, as an aside, if it is not possible by design...I think that's a
foolish limitation in the MVC framework.
You could open a ticket on MS Connect and hope this could change in a future version of the framework. Until then you could also write your own custom helpers that will allow you to override the name attribute for the cases when you need such functionality. Personally I've never needed it so far but I am sure you have valid reasons. Another possibility is to write a custom model binder on the server.
It's easy to set our action not to validate the input just hooking up the attribute like
[HttpPost, ValidateInput(false)]
public ActionResult Signup(SignupModel model)
{
...
}
But I was wondering, is there a way to only do this in just one form field? and not all of them in the actual <form>
or, I have to use this and then worry about encoding properly all other fields?
You should not rely on ValidateInput to 'encode' your values. It doesn't encode values - it just rejects some values outright. And even if you use it, you still must encode all your values that are user-entered and displayed on the site in any way.
In fact, because of that - I've never used that validation myself. For example, if all I did was rely on that validation, people would not be able to enter some very basic things in forms like this one, such as trying to show example HTML.
But even the MSDN documentation and every book I've read said that the ASP.NET validation there does not protect you against every possible malicious input. So essentially, you can not rely on it to protect your users. You still must encode values you are displaying (and you should encode them only as you are displaying them, otherwise you'll end up with all sorts of display bugs where you've double-encoded things)
Using MVC3 , the attribute can be applied to Model by specifying SkipRequestValidation.
Assuming you wanted to develop your Controllers so that you use a ViewModel to contain data for the Views you render, should all data be contained within the ViewModel? What conditions would it be ok to bypass the ViewModel?
The reason I ask is I'm in a position where some of the code is using ViewData and some is using the ViewModel. I want to distribute a set of guidelines in the team on when it's right to use the ViewData, and when it's just taking shortcuts. I would like opinions from other developers who have dealt with this so that I know my guidelines aren't just me being biased.
Just to further Fabian's comment; you can explicitly ensure viewdata is never used by following the steps outlined in this article. There's really no excuse not to use models for everything.
If you have no choice but to use ViewData (say on an existing project); at the very least use string constants to resolve the names to avoid using 'magic strings'. Something along the lines of: ViewData[ViewDataKeys.MyKey] = myvalue; Infact, I use this for just about anything that needs to be "string-based" (Session Keys, Cache Keys, VaryByCustom output cache keys, etc).
One approach you may wish to consider as your views become more complex, is to reserve the use of Models for input fields, and use ViewData to support anything else the View needs to render.
There are at least a couple of arguments to support this:
You have a master-page that requires some data to be present (e.g. something like the StackOverflow user information in the header). Applying a site-wide ActionFilter makes it easy to populate this information in ViewData after every action. To put it in model would require that every other Model in the site then inherit from a base Model (this may not seem bad initially, but it can become complicated quickly).
When you are validating a posted form, if there are validation errors you are probably going to want to rebind the model (with the invalid fields) back to the view and display validation messages. This is fine, as data in input fields is posted back and will be bound to the model, but what about any other data your view requires to be re-populated? (e.g. drop-down list values, information messages, etc) These will not be posted back, and it can become messy re-populating these onto the model "around" the posted-back input values. It is often simpler to have a method which populates the ViewData with the..view data.
In my experience I have found this approach works well.
And, in MVC3, the dynamic ViewModels means no more string-indexing!
I personally never use ViewData, everything goes through the Model, except when im testing something and i quickly need to be able to see the value on the view. Strongtyping!
In terms of ASP.NET MVC 2, ViewModel pattern is the preferred approach. The approach takes full advantage of compile time static type checking. This in combination with compiling mvc views will make your development work-flow much faster and more productive since errors are detected during build/compile time as opposed to run time.
I have a simple web-site. Almost every action takes int toonId as an argument (toonId does not equate to the user: one user can own multiple toons).
At the moment I provide that value to every view from controller, and every link and submit button sends this value back to the controller.
This works. I am just looking for an easier way to accomplish this (AOP comes to mind).
I use cookies to persist "favorite/default toon", and this works fine (used with ActionAttribute, that takes toonId from cookie and passes is to the toonId argument, if toonId wasn't provided). But I want to support cookie-less sessions as well.
Question: What is an easy way to add ambient variable to the page, without passing it explicitly all over? Such that it would work with cookie-less browsers.
Is Viewstate a way to go (which isn't supposed to be in the MVC)?
Is server-side session a way to go?
This is exactly what session is meant for.
There is no page lifecycle in asp.net mvc, hence no viewstate.
I believe you can automatically pass query string parameters for use cookie-less browsers if you plug in your own implementation of IRouteHandler. I have not tried it though. I found an example of implementing IRouteHandler although it does not show how to implement the query string parameter functionality.
I'm not clear on what 'toonid' represents. If it's 'ambient per user session', then as womp stated, Session state would work well for this. However, if it's somethign that has a larger scope (e.g. a colleciton of toonids that are commonly accessed by all users) then teh Cache would be a better and more scalable strategy.