MVC Html data attribute rendering difference - c#

I have experienced a very strange issue which I cannot find the cause of.
In my Asp.Net MVC app (.net4.0/MVC4) I am rending html data attributes within some html element to then be used within the JavaScript.
So in the app I have a Model, e.g.
public class MyModel{
public bool MyFlag { get; set; }
}
I am then passing this model through onto a simple MVC view page and rendering the boolean value into the html data attribute, e.g.
#model MyProject.MyModel
Click Me
Now when running the project locally the html is rendered as:
Click Me
However when running on the server, the html is rendered as:
Click Me
At first I thought that maybe the boolean was not being set somehow, so I added this to the element Click Me #Model.MyFlag which renders as Click Me True. Now I suspected that this has maybe something to do with Debug vs Release mode, however after playing about with this it made no difference.
My fix to this was to change the code to output the boolean value as a string value, e.g. data-is-flagged="#Model.MyFlag.ToString()" which then renders the same locally and on the server.
Any ideas what is the cause of this?

I quote the answer from another website:
This is a result of Conditional Attributes that was introduced into
Web Pages 2 (MVC 4):
http://www.mikesdotnetting.com/Article/201/Cleaner-Conditional-HTML-Attributes-In-Razor-Web-Pages
Two options: revert back to Web Pages 1 (MVC 3) or edit all the
affected files.
If the value applied to an attribute is true, the result is that the attribute is repeated (this is useful for the tags option inside a select for instance). If the value set is false, nothing is rendered (not event attribute name).
So, as the comments by #Jamie and #Peter, you may have a different version of the Razor engine in your development enviroment.

Related

ASP.Net MVC Generate DNS Prefetch Tags

Is there a way to find all the src="" urls when rendering a ASP.net MVC page in the view to then generate DNS prefetch tags on the fly?
https://www.chromium.org/developers/design-documents/dns-prefetching
If I understood correctly I can tell you the following:
Option #1: (Not a pretty solution but would work.)
NOTE: for this try to use simple Javascript and not rely on JQuery or other (since then you still need to "load" the .JS file for that and that is ruining the point of your question.
Process your src/href or some other predefined property tag with some kind of "OwnLogic" to define the "base target",
but in a way that the browser would not be able to initiate the request to obtain that image or other file.
Example:
<img url="" class="DNS_BaseTarget" DNS_BaseTarget="smiley.gif||myCDNPointerInfo" alt="">
Then, with javascript, get a list of all elements that uses the class DNS_BaseTarget and then read the property value and update the "src" tag.
At the same time you can inject by javascript inject all the '<link rel="dns-prefetch" href="https://cdn.yourTargetDomain.com">' that you will use based on the information you just processed.
I did not tested this concept, so "lag" or some sort of delay in the client might be expected (but maybe not noticeble by the user).
Option #2:
The View Result Execution Process (in MVC life cycle) tell us that the method 'Render()' is the last one to be executed.
With this being said, you can create your own custom override logic
Example: intercept view rendering to add HTML/JS on all partial views?
How to intercept view rendering to add HTML/JS on all partial views?
With this concept of trying to "process" the final html before sending it to the user, you could somehow "parse" the file.... try to get all the 'src/href' and then
inject all the '<link rel="dns-prefetch" href="https://cdn.yourTargetDomain.com">' that you will use.

Why has Html.DisplayTextFor stopped showing the text as HTML?

I have an ASP.NET MVC3 web page which used to nicely display a C# string of HTML nicely. My server code programmatically loads the string with HTML tags for a nice table. The following cshtml has been showing this nice table as a nice table for years:
<h3>Nice Table:</h3>
#Html.DisplayTextFor( model => model.sNiceTable )
But today we notice browsers (Firefox & IE) are instead displaying it as a pile of text showing the HTML tag text:
<table><tr><th>...
rather than rendering it visually as a table, the way it did for years until now. The "Nice Table" header still displays properly.
Looking at the text in Firefox's developer Inspector shows HTML that looks like it should render as HTML, but (after showing the <h3> tag in color) it too has those tags from my string in black, even though when I paste the same string into an HTML file and load it, it shows the nice table. That is, Inspector shows the code as if it should work, but my string is in black for some reason that doesn't show in its code view.
Trying to use "view source" in Firefox or IE seems to be unusable for this, because the view part doesn't even show up there for some reason.
I see there are various other methods such as Display() and DisplayFor(), but they seem to do the same thing.
I haven't really touched this page since it last worked. The only thing I suspect that changed was applying some MS updates that had some other annoying side-effects on my projects.
What can I do to get this text to render again, rather than spew the HTML tags in the string as text?
Edit: model.sNiceTable is a C# string data member of the viewmodel, where the interface is:
public interface IMemberStatsViewModel
{
string sNiceTable { get; set; }
// other properties...
}
Its value gets assembled in my code which is called in the view model's constructor:
public MemberStatsViewModel()
: base(new DataLayer.DataLayer(), ClientInterfaceTypeEnum.Web)
{
InitializeMe();
}
InitializeMe() calls a data layer function which returns the C# string and assigns it to sNiceTable. The string is built based on stuff I look up in the data layer.
You can use Html.Raw
<h3>Nice Table:</h3>
#Html.Raw(model.sNiceTable)

mvc razor allow users to select there own theme css

I am using MVC/Razor/.Net/C# and i would like to allow users to change the theme of the site just like you can change the theme in microsoft windows.
Does anyone know how to, or, can point me in the direction of some good tutorials/examples.
Cheers
This is a very, very broad question with any number of correct approaches.
You could create a base controller that loads the user's selected CSS theme name from a database during each request. Then you can put that value into the ViewBag (or ViewData) and reference it in your view:
<head>
#{
var themeName = ViewBag.ThemeName;
}
#if (String.IsNullOrWhiteSpace(themeName)) {
themeName = "default";
}
<link href="#Url.Content(String.Format("~/themes/{0}.css", themeName))" type="text/stylesheet" />
</head>
Usually this functionality is achieved with multiple CSS files and has little (or nothing to do with .NET).
You should design your HTML in a semantic way so that by changing the CSS files the entire output is different with each CSS applied.
This link gives a more explanatory intro into the subject -> http://www.thesitewizard.com/css/switch-alternate-css-styles.shtml
After you do that, what you need to do in your application is to store the user preference (of what skin) in a session or something like that and change the CSS file accordingly.
Asp.Net WebForms use to have the Skin/Theme feature, but I think that it was deprecated (it is not very good) and I also saw an implementation where instead of HTML the developer used XML and XSLT files to render the views (which is also too complicated for my taste).

ASP.Net - A potentially dangerous Request from submitting HTML data

I'm working on a web form which works in a following way.
Read email template from database
Display email template on a web form in HTML format
User adds additional information to the web form and clicks on submit button
Before I get to a method which will process that request, I get A potentially dangerous Request.Form
I have looked at few articles that advise using .Net 2.0 in one of the web.config sections - that didn't work. I have set requestValidation = "false" for that page and it didn't work either.
My gut feeling is that I'm doing something fundamentally wrong...
HTML template is stored as VarChar(4000) in a database.
I have tried encoding text in a method before I send an email, but that didn't work either because the web form never got to executing that method.
What other options do I have? I have tried storing plain text in database, but then I have issue of tabs and returns etc.
Thank you
The remedy is in two parts and you MUST action both:
To disable request validation on a page add the following directive to the existing "page" directive in the file (you will need to switch to the HTML view for this):
ValidateRequest="false"
for example if you already have:
<%# Page Language="vb" AutoEventWireup="false"
Codebehind="MyForm.aspx.vb"
Inherits="Proj.MyForm"%>
then this should become:
<%# Page Language="vb" AutoEventWireup="false"
Codebehind="MyForm.aspx.vb"
Inherits="Proj.MyForm"
ValidateRequest="false"%>
In later versions of Visual Studio the value of this property is available via the page properties, so simply set "ValidateRequest" to "False". Either method of setting this achieves the same result.
Alternately, you can globally turn request validation off (but in which case be sure to implement item two below). To globally turn request validation off add the following to your web.config file:
<pages validateRequest="false" />
From: http://www.cryer.co.uk/brian/mswinswdev/ms_vbnet_server_error_potentially_dangerous.htm
As a first security lesson, never trust user input,so if you setting request validation to false then always HTML encode the input.
In basic either use: OnClientClick on submit and replace, < with & lt; and > with & gt; (no space with & and gt/lt)
or on submit method, use Server.HTMLEncode(inputtext)..or however you process it.

Why does it make a difference where I include the jQuery script file?

On my master page (for all pages in my site) I have a ToolkitScriptManager.
On my content page, there are a series of hyperlinks and divs for collapsible functionality.
The code to show/hide the panels work like the following:
$(document).ready(function() {
// Hookup event handlers and execute HTML DOM-related code
$('#nameHyperLink').click(function() {
var div = $('#nameDiv');
var link = $('#nameHyperLink');
if (div.css('display') == 'none') {
link.text('Hide Data');
div.show('100');
}
else {
link.text('Show Data');
div.hide('100');
}
});
});
If I include a ScriptReference to the jQuery 1.4.2 file in the toolkitscriptmanager, the javascript code is executed incorrectly on the page (only the text for the hyperlink is changed, the div is not actually shown.) However, if I don't include the jQuery file in the ToolkitScriptManager and instead include it in the content page, it works correctly.
I'm a Javascript/jQuery newbie, and this makes no sense at all. What's going on here?
Positioning of the script include is important for the jQuery ref. If you look at your generated source I would bet the tag is below the script function(). You should make sure that the jQuery reference comes as early as you can get it in the page source.
Try moving the jQuery library reference into the head of your master page, that should work. Otherwise post up some source!
Like Tj says... should probably be in the head section of your master page. Also, it's nice to link to Google's version of this library, because chances are your users will already have it cached. For instance, look at the source for this very page.
The two most probable causes here are $ not being defined yet (see Tj's answer) and $ getting defined by another library, such as prototype.
I would highly suggest you look into using Firebug's javascript debugger, or at least take a look at Firefox's built in error console (Tools -> Error console). That will give you a much better clue what is going on other than "it's not working."

Categories