MVC HTML helper wrapper for jqPlot - asp.net-mvc

I wish to create an MVC wrapper around jqPlot.
I want to have a helper object to render the required html container element and the required java scripts to draw the chart.
Something that will look like this:
#Html.jqPlot()
.ChartType(eChartTypes.PieChart)
.ChartData(someData)
.RenderChart();
Now I'm only at the initial design phase and I know what the jqPlot object should look like to achieve that, the problem I'm having is with the java script that suppose to be emitted to draw the actual chart using jqPlot.
Suppose I will render the following script in my .RenderChart() method
public string RenderChart()
{
string chartCode = string.format(#"
<script type="text/javascript" src="../src/plugins/jqplot.canvasTextRenderer.min.js"></script>
<script type="text/javascript" src="../src/plugins/jqplot.canvasAxisLabelRenderer.min.js"></script>
$(document).ready(function(){
var plot1 = $.jqplot ('{0}', [{1}]);
});
",this.ChartGuid, this.ChartData);
return chartCode;
}
The above is not actual code but just a general representation of the idea.
So the problem is that i don't want the Helper to emit the JS code into the body of the Html document, furthermore i cannot let it do that becuse some of the required scripts may be at the bottom of the html (as the best practice states).
Any suggestions ?
What would be the best way to emit JS code using an HTML helper if the situation requires it (like this one) ?

I think, listening to an even will be a possible solution, in this case the even of outputting or finishing the rendering of the footer. so maybe your code will give as an option to listen to an event and render at that moment, but this is of course platform dependent. I also worked on a php wrapper you can fork it here: https://github.com/oumsofiane1/jqplotPHPwrapper.git
and just implemented a helper, but of course you can extend that :-)
Hope this helps

Related

How to keep related Partial page/HtmlHelpers, scripts and css together and not separate references

I have a form that has a button next to person textbox that brings up a person Bootstrap Modal Search Window.
the html I put in a partial page and reference it
#{await Html.RenderPartialAsync("_PersonControlPartialHtml","PersonControl1");}
#{await Html.RenderPartialAsync("_PersonControlPartialHtml","PersonControl2");}
which adds a textbox and button.
Then I add a bootstrap modal html to the page that only has to appear once per page
#{await Html.RenderPartialAsync("_PersonControlModal");}
Then the javascript event code and css for the above.
#section Header {
<script src="~/css/personcontrolscript.css"></script>
}
and
#section Scripts {
<script src="~/js/personcontrolscript.js"></script>
}
The html I could put in an htmlhelper but I still need to add 3 references to the page if I want to add it to a page.
Is there not an easier way?
There are ways to reduce this but those ways come with trade offs. So it really depends on which approach best fits your needs.
So for example you could eliminate adding the .css reference in the header section via two different approaches:
1) you could place those styles in a global.css file that is already loaded for ever page; or
2) you could use inline styles on you html and eliminate these css classes.
Both of these solutions of course have downsides. Approach one means that the size of the global.css styles will be larger and take a bit more time to load even if the first page used on the site doesn't need them. Approach 2 seems to fly in the face of conventional wisdom that you should almost never use inline styles and it will make the markup more verbose. But either solution would allow you to eliminate the need for including a seperate ~/css/personcontrolscript.css reference every time you have a person control on the page.
As for the need to include ~/js/personcontrolscript.js, that could be solved one of two ways:
1) include the javascript code in a global.js file that is loaded for every page; or
2) put that javascript code inline in the _PersonControlPartialHtml and add code to it to make sure that it only gets injected the first time the partial is used on the page.
As for the bootstrapModel, I'm a little less clear on what that code looks like so I can't say for sure but probably it could leverage an approach similar to one mentioned for css or js.
With regard to rendering your partials, I don't think there is any way to eliminate that given that it's the primary representation of the functionality you are adding to the page.

ASP.NET MVC XSS protection

According to OWASP XSS page, one needs to use different XSS protection techniques for different contexts. However, in ASP.NET MVC Razor views, we only have the # sign to escape data in the context of HTML element inner content. What about HTML attributes, CSS, javascript contexts and others?
HTML element content
This is safe and will work as expected:
<div>#data</data>
HTML element attribute
This is not safe and can be exploited:
<div style="background: #color"></div>
JavaScript
While this is not safe:
<script>
var value = #value;
</script>
Safe solution is:
<script>
var value = #Json.Encode(value);
</script>
CSS
This is not safe and can be exploited:
<style>
.box { background : #color; }
</style>
A great thing about razor is that it does all the HTML encoding by default. Unless you use #Html.Raw(), it is pretty difficult to make your page vulnerable. You generally have to explicitly make variables render as html.
You also have Html.Encode() if you need it. There is also HttpUtility.JavaScriptStringEncode()
Regarding the updated vulnerable code:
#{var js = "alert(1);";}
<script>var value = #js</script>
I think you would be violating rule 0 with this code. You are inserting arbitrary strings into a script tag, and expecting it not to be executed. I actually get a syntax error (warning) with your example, but it will still run. If you wrapped it in quotes, you would be safe.
#{var js = "\"alert(1);";}
<script>var value = "#js"; alert(value);</script>
output:
"alert(1);
Notice that the quote that I put in the string gets escaped to ", making me unable to break out of the string, so I cannot inject js.
I'd be interested to see if someone has a way of sanitizing this without putting it in quotes, but I am skeptical.
update 2:
Dealing with CSS
The examples you give are not about escaping strings, it is more about inserting untrusted CSS into your page. To do that, you will need something that can parse CSS. For example, it is not that you want the value to be encoded, you just want it not to include the dangerous stuff like url(javascript:), behavior, binding, etc. You'll need a CSS filtering tool for that.
HTML attributes
you are safe if you do this:
<div data-color="#color"></div>
Since razor encodes quotes, you won't be able to terminate the string early. That's as simple as it is to prevent XSS (barring some unknown vulnerability in razor). Your Json.Encode() uses the same idea.
BUT, you are doing somehting risky if you do this:
<div #attribute></div>
Again, it's not that you need an escaped string here, you want something that filters your attributes on any dangerous content. The fact is, that doing things this way is really messy, and I would advise against it. It is bad design because it is screwing up your separation of concerns and making it hard to secure your app from XSS. What you should do instead is add CSS classes if you want to change the style. If you need to set an attribute based on a variable in razor, use something else rather than injecting it into your HTML and hoping to filter it.
ex:
#{
var disabled = isDivDisabled ? "disabled" : "";
}
<div #disabled><div>

Why moving the code from html into .js causes issue?

I have asp.net mvc project with knockout.js so my index page is getting really huge because of lots of javascript functionality.
I'd love to move js code into a separate file but it does not allow me to apply it to the most of the code because if I have something like
$.ajax({
url: "#Html.Raw(#Url.Action("Load"))",
Then it pops up a error if I move this part of the code into another file.
Please advise how can I resolve this issue?
Javascript files are not parsed by ASP.net, so the variables you have of #Html.Raw and #Url.Action("Load") will never be processed.
As #James Lai noted, server side code isn't parsed as such by ASP.Net. See this post for a workaround, or you can pick and choose which scripts can still stay on the page (with server-side code) instead of the "everything" - your choice as to which approach meets your requirements.
Javascript files are not parsed by ASP.NET MVC, thus #Html.Raw(#Url.Action("Load")) will not work in javascript file.
Heres workaround
Instead declare a variable in view.cshtml. In script section as
<script type="text/javascript">
var actionUrl = '#Url.Action("Load", "Controller")';
</script>
And use actionUrl in javascript file.

multi line tag in grails or html

With a grails app and from a local database, I'm returning some text in a xml format.
I can return it well formed in a <textarea></textarea> tag with the correct indenting (tabulation, line return,...etc.)
I want to go a bit further. In the text I'm returning, there are some <img/> tags and I'd like to replace those tag by the real images themselves.
I searched around and found no solution as of now. I understood that you can't add an image to a textarea (other then in a background), and if I choose a div tag, I won't have the indenting anymore (and therefore, harder to read)
I was wondering if using a <g:textField/> or an other tag from the grails library will do the trick. And if so, How can I append them to a page using jquery.
For example, how to append a <g:textField/> in jquery. It doesn't interpret it and I get this error
SyntaxError: missing ) after argument list [Break On This Error]...+doc).append("<input type="text" id="FTMAP_"+nb_sec+"" ...
And in my javascript file, I have
$("#FTM_"+doc).append("<g:textField id='FTMAP_"+nb_sec+"' ... />
Any possible solutions ?
EDIT
I did forget to mention that my final intentions are to be able to modify the text (tags included) and to have a nice and neat indentation so that it is the easiest possible for the end user.
You are asking a few different questions:
1. Can I use a single HTML tag to include images inside pre-formatted text.
No. You will have to parse the text and translate it into styled text yourself.
2. Is there a tag in the grails standard tags to accomplish this for me?
No.
3. How can I add grails tags from my javascript code.
Grails tags are processed on the server-side, and javascript is processed on the client. This means you cannot directly add grails tags via javascript.
There are a couple methods that can accomplish the same result, however:
You can set a javascript variable to the rendered content of a grails tag. This solution is good for data that is known at the time of the initial request.
var tagOutput = "${g.textField(/* etc */)}";
You can make an ajax request for the content to be added. Then your server-side grails code can render the tags you need. This is better for realtime data, or data that will be updated more than once on a single rendered page.

How to separate javascript libraries and calls in the Rails 3.1 asset pipeline

I'm trying to get the hang of the whole asset pipeline thing, and read the guide and several tutorials about them. But one thing that doesn't become quite clear is wether I should view my javascript asset files as a library or a place to put code that is actually run i.e. $(document).ready. Because by default all the javascript files are included, and it would be weird to have several $(document).ready's in there, not to mention that you don't want the $(document).ready function for every page to be run in the first place. What would be the way to go at this? Use my asset files as a library and put actual calls in my views (ugly)? Or is there a better way to do this?
I too ran into this issue. In a large project you can have somebody put code into document ready to, for example, add a click function to each li within a div with class container.
Now we could all argue that the above code would be too generic and of course may affect li tags in other parts of the application, but the bigger the project, the more likely it is that you will run into a conflict like this leading to unexpected behaviour.
I for one am uncomfortable with a whole bunch of document ready functions running for each and every page loaded. My solution is not necessarily the perfect one, but it's one that I have taken up and will share with you.
In the body tag of each page I add data elements signifying the controller and the action. I then have one document ready script that looks for a class named after the controller with the name Ready appended e.g. HomeReady. It will then call a method on this class (presuming it exists) named after the action. So in your asset coffee file you could write:
class #HomeReady
#index: ->
alert("Hello")
#show: ->
alert("Goodbye")
This allows control right down to the action level. When I came across your question I decided to package this solution into a gem as I have already used it in several projects. You can find it at: https://github.com/intrica/rails_document_ready
If you absolutely don't want a certain piece of initialization code to be run unless the current page is a specific controller/action, then you can try adding an empty element on the page with an id built from that info like "posts_index" using these two helpers:
"#{controller_name}_#{action_name}"
Then in your javascript you can wrap the code inside an if statement that checks for the existence of an element with the appropriate id.
edit: Here's an example of the js partial that I mentioned in the comments.
show.html.haml
= render 'map'
map.html.erb (I normally use haml but it's easier to write js in erb)
<script src='http://www.google.com/jsapi' type='text/javascript'></script>
<script type='text/javascript'>
...
</script>
It's probably not as clean as it could be and it doesn't get the benefits of being part of the asset pipeline but I don't mind because it's only something that gets included on a specific page.

Resources