Verbatim string literal not interpreting html - c#

In my controller action, I am sending a message to a view -
model.Result = ex.Message;
model.Result = model.Result + #" If you would like to create one, please click here ";
So, I want the message to show up like so -
The member doesn't exist. If you would like to create one, please click here.
But what actually shows up is
The member doesn't exist. If you would like to create one, please <a href> click here </a>.
So, I have 2 questions -
1) Why is the verbatim string literal not evaluating the html.
2) Is there a better way of doing this? I don't like having html in my controllers, but I also don't want to over architect things for a line of html.

Razor automatically HTML-encodes strings for security (to prevent script injection). You need to use Html.Raw if you want the actual HTML.
#Html.Raw(Model.ResultMessage)

Related

How display data generated by Rich Text Editor in ASP.NET MVC? [duplicate]

I have a controller which generates a string containing html markup. When it displays on views, it is displayed as a simple string containing all tags.
I tried to use an Html helper to encode/decode to display it properly, but it is not working.
string str= "seeker has applied to Job floated by you.</br>";
On my views,
#Html.Encode(str)
You are close you want to use #Html.Raw(str)
#Html.Encode takes strings and ensures that all the special characters are handled properly. These include characters like spaces.
You should be using IHtmlString instead:
IHtmlString str = new HtmlString("seeker has applied to Job floated by you.</br>");
Whenever you have model properties or variables that need to hold HTML, I feel this is generally a better practice. First of all, it is a bit cleaner. For example:
#Html.Raw(str)
Compared to:
#str
Also, I also think it's a bit safer vs. using #Html.Raw(), as the concern of whether your data is HTML is kept in your controller. In an environment where you have front-end vs. back-end developers, your back-end developers may be more in tune with what data can hold HTML values, thus keeping this concern in the back-end (controller).
I generally try to avoid using Html.Raw() whenever possible.
One other thing worth noting, is I'm not sure where you're assigning str, but a few things that concern me with how you may be implementing this.
First, this should be done in a controller, regardless of your solution (IHtmlString or Html.Raw). You should avoid any logic like this in your view, as it doesn't really belong there.
Additionally, you should be using your ViewModel for getting values to your view (and again, ideally using IHtmlString as the property type). Seeing something like #Html.Encode(str) is a little concerning, unless you were doing this just to simplify your example.
you can use
#Html.Raw(str)
See MSDN for more
Returns markup that is not HTML encoded.
This method wraps HTML markup using the IHtmlString class, which
renders unencoded HTML.
I had a similar problem with HTML input fields in MVC. The web paged only showed the first keyword of the field.
Example: input field: "The quick brown fox" Displayed value: "The"
The resolution was to put the variable in quotes in the value statement as follows:
<input class="ParmInput" type="text" id="respondingRangerUnit" name="respondingRangerUnit"
onchange="validateInteger(this.value)" value="#ViewBag.respondingRangerUnit">
I had a similar problem recently, and google landed me here, so I put this answer here in case others land here as well, for completeness.
I noticed that when I had badly formatted html, I was actually having all my html tags stripped out, with just the non-tag content remaining. I particularly had a table with a missing opening table tag, and then all my html tags from the entire string where ripped out completely.
So, if the above doesn't work, and you're still scratching your head, then also check you html for being valid.
I notice even after I got it working, MVC was adding tbody tags where I had none. This tells me there is clean up happening (MVC 5), and that when it can't happen, it strips out all/some tags.

Validate Razor template

How can I validate Razor template, which is used to render mail template.
string template = #"
My template
#if (Model.Condition { <span>is true</spaM> }"
I made two mistakes: missing closing bracket and wrong closing tag.
I need to validate it and known what should I fix (the best is to known in which line). I would like to use native Razor methods.
If I understand correctly, you want to be notified that the code you've written in the Template is invalid HTML.
If so, I'm afraid there is no easy way. The Template is purely producing text that you specify to go out to the response.
It may not even be HTML - could be JavaScript or a number of other outputs - it's just a string of text.
You may have a Template that produces the start of a table, another that produces the body, and another that produces the footer and end table tags. Each of these would produce invalid HTML on their own, but output one after the other would produce a valid HTML table. (That's a lot of produces there - sorry).
What would make it invalid is the parser of the HTML - i.e. the browser. You would only be able to validate your Template output when it is in a complete document that can then be parsed.
You mean ?
#{
string template = Model.Condition ? "My template <span>is true</span>" : "";
}
string MyString = string.empty;
#if(Model.Condition)
{
MyString ="<span>"+ "is true"+"</span>";
}

Object to string using Razor?

Is there an Razor method that will allow to put "object to string" inside html like:
Anchor
Or do I have to use something like that and change my model?
c# object to string to display it in text format
Thanks
if the link you are passing from your model is a string the correct syntax would be
Anchor
or
<a href=#Html.Raw("http://www." + #Model.x.y))>Anchor</a>
This way you are correctly parsing any special characters which might occur in the link like & or =

Sanitize User Input in C# - Cleanest Way?

There's a gotcha when inserting img's dynamically via scripts.
Take the following code to insert a image for a place:
newPlace.find('.PlaceThumb').append('<img src="' + place.ThumbnailUrl + '" alt="' + place.Name + '" width="50px" style = "padding:2px;"/>');
Someone could name their place: " onload="alert('hi')" and the tag would get rendered as:
<img src="/item.aspx?id=123" alt="" onload="alert('hi')" width="50px" style = "padding:2px;"/>
When the image is loaded, the script will execute.
While only and tags support the onload attribute, this is a good lesson to never trust user input.
What is the "Correct" (nice, elegant, clean, general) way of doing this:
newPlace.find('.PlaceThumb').append('<img src="' + place.ThumbnailUrl + '" alt="' + place.Name.replace('"', '"') + '" width="50px" style = "padding:2px;"/>');
I was thinking maybe with templates you could define an operator on strings that would UUencode them - similar to how a string prefixed with # in C# has special meaning vis a vis backslashes. Is there a way to add this functionality to the standard .net string class?
Maybe you can use new Uri( yourUrlString ). I believe using that (alog with the methods IsWellFormedUriString and IsWellFormedOriginalString) will help you validate the input.
AntiXSS library is one possible solution. Be very carefull with encoding as your code seem to have large number of layers between data and rendered HTML (ASP.Net -> renders HTML template as part of rendered JavaScript -> Browser loads JavaScript -> something executes the scriot that in turn uses JQuery to create HTML based on the temeplate).
Note: Consider separating CSS (width and style attributes) from HTML layout as good HTML practice.
I can't tell if you're using jQuery or not. If you are, then you can do something like this:
newPlace.find('.PlaceThumb').append('<img>');
$('.PlaceThumb img').attr('src', place.ThumbnailUrl).attr('alt', place.Name);
That may not be valid, it's just off the top of my head, but should give you something to look into.

Remove anchor from URL in C#

I'm trying to pull in an src value from an XML document, and in one that I'm testing it with, the src is:
<content src="content/Orwell - 1984 - 0451524934_split_2.html#calibre_chapter_2"/>
That creates a problem when trying to open the file. I'm not sure what that #(stuff) suffix is called, so I had no luck searching for an answer. I'd just like a simple way to remove it if possible. I suppose I could write a function to search for a # and remove anything after, but that would break if the filename contained a # symbol (or can a file even have that symbol?)
Thanks!
If you had the src in a string you could use
srcstring.Substring(0,srcstring.LastIndexOf("#"));
Which would return the src without the #. If the values you are retreiving are all web urls then this should work, the # is a bookmark in a url that takes you to a specific part of the page.
You should be OK assuming that URLs won't contain a "#"
The character "#" is unsafe and should
always be encoded because it is used in World Wide Web and in other
systems to delimit a URL from a fragment/anchor identifier that might
follow it.
Source (search for "#" or "unsafe").
Therefore just use String.Split() with the "#" as the split character. This should give you 2 parts. In the highly unlikely event it gives more, just discard the last one and rejoin the remainder.
From Wikipedia:
# is used in a URL of a webpage or other resource to introduce a "fragment identifier" – an id which defines a position within that resource. For example, in the URL http://en.wikipedia.org/wiki/Number_sign#Other_uses the portion after the # (Other_uses) is the fragment identifier, in this case indicating that the display should be moved to show the tag marked by ... in the HTML
It's not safe to remove de anchor of the url. What I mean is that ajax like sites make use of the anchor to keep track of the context. For example gmail. If you go to http://www.gmail.com/#inbox, you go directly to your inbox, but if you go to http://www.gmail.com/#all, you'll go to all your mail.
The server can give a different response based on the anchor, even if the response is a file.

Categories