ASP.NET MVC 5 - redirect from view only once - asp.net-mvc

Hy,
I'm trying to redirect users which has deactivated javascript with following code in the main layout (_Layout.cshtml):
<noscript>
<meta http-equiv="refresh" content="0;url=/Error/NoJavascript" />
</noscript>
Rather it works, but it refreshes every time. How can I redirect only once instead of every time?
I've found this code sample, but it doesn't let me compile (error message: can't implicite convert from void to object) I use this code sample in my view (_Layout.cshtml):
#Response.Redirect("/Error/NoJavascript")
Thanks for help :)

Use a simple static HTML file for this special case which has not this meta data:
<meta http-equiv="refresh" content="0;url=#Url.Content("~/Content/NoScript.html")" />
Your returned view from the Error/NoJavascript action method has a reference to the layout page automatically or just set its layout to null.
#{
Layout = null;
}

Related

Partial file not found in mvc application

I am getting following error.
An exception of type 'System.InvalidOperationException' occurred in System.Web.Mvc.dll but was not handled in user code
Additional information: The partial view '../Shared/Partial/_ReferencePartial.cshtml' was not found or no view engine supports the searched locations. The following locations were searched:
I am having login controller in Area/Admin. In Login.cshtml view file, I am referencing Partial View file that contains references to script files. This file is in the folder, Solution/Project/Views/Shared/Partial.
Below is my Login.cshtml view file code.
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>#Messages.Login</title>
#Html.Partial("../Shared/Partial/_ReferencePartial.cshtml")
</head>
...
If you want to load the partial view directly inside the main view you could use the Html.Action helper:
#Html.Action("Load", "Home")
or if you don't want to go through the Load action use the HtmlPartial hepler:
#Html.Partial("_LoadView")
If you want to use Ajax.ActionLink, replace your Html.ActionLink with:
#Ajax.ActionLink(
"load partial view",
"Load",
"Home",
new AjaxOptions { UpdateTargetId = "result" }
)
and of course you need to include a holder in your page where the partial will be displayed:
<div id="result"></div>
Also don't forget to include:
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
in your main view in order to enable Ajax.* helpers. And make sure that unobtrusive javascript is enabled in your web.config (it should be by default):
<add key="UnobtrusiveJavaScriptEnabled" value="true" />

How do I get Custom Variables in Google Analytics to work using Async method?

So, I'm researching how to use Google Analytics by applying it to a test site I've built using VB.NET and MVC5. I'm using the Async method since that seems to be what the Google Developers site is recommending.
In my _Layout.vbhtml (which Visual Studio automatically generated for me) I have the following code between my <head> and </head> tags:
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title - My ASP.NET Application</title>
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
<script>
window.ga = window.ga || function () { (ga.q = ga.q || []).push(arguments) }; ga.l = +new Date;
ga('create', 'UA-75489237-2', 'auto');
ga('send', 'pageview');
</script>
<script async src='https://www.google-analytics.com/analytics.js'></script>
<script>
_gaq.push(['_setCustomVar',
5, // This custom var is set to slot #5. Required parameter.
'CusVarTest', // The top-level name for your online content categories. Required parameter.
'Successful', // Sets the value of "Section" to "Life & Style" for this particular aricle. Required parameter.
3 // Sets the scope to page-level. Optional parameter.
]);
</script>
</head>
Now, theoretically, this should be working, but when I go to the Google Analytics site, and go to "Reporting --> Audience --> Custom --> Custom Variables" I am seeing no sign of my variable.
Any thoughts?
A few things:
you are mixing older classic GA syntax (_gaq.push(['_setCustomVar', ...) with the new UA syntax (ga('create', 'UA-75489237-2', 'auto');). That's not going to work. I advise you to make sure you are using only UA code.
Custom Variables have been phased out of UA, so you will need to use the UA analogs called "Custom dimensions" (cf. https://support.google.com/analytics/answer/2709828?hl=en). This includes no longer using the Custom Variables in the reports.
data takes up to 24 hours to process, so you won't see things right away in your reports unless you wait a day, or you could try using GA Debugger or console tools to verify that your data is properly set and sent.

How can you redirect a user on page load and still have Twitter cards work

I am integrating Twitter Cards into my website, specifically the app install and deep linking feature. To do this, I added the required meta tags into the header section of my html page.
The feature in my app that posts to Twitter shares articles from other websites. In order to share a website url that is not on my domain but still have the twitter card show up, I made a simple short url that gets posted on Twitter that points to my html page with the meta tags and then redirects the user to the original site, but I am not getting the desired results.
First, I tried redirecting the user by returning a 301 response code in the headers. This redirects the user exactly as I want (keeps my redirect page out of the browser history), but the meta tags don't get picked up by Twitter so the card doesn't show up.
Next, I tried using a meta tag below the Twitter card meta tags like this:
<META http-equiv="refresh" content="0;URL=http://www.mywebsite.com">
With this method the Twitter card shows up properly, but now the back button is enabled in the browser. Also, I read that this method is not advised because search engines tend to remove sites that do this from there results due to security reasons.
Does anyone know how to redirect the user without having the back button in the browser be enabled and still allow the meta tags to be evaluated? I would prefer a method of doing this without using Javascript.
I found an interesting way around this issue.
I only need the Twitter meta tags available when Twitter is the the one looking at my site. So, when a user or bot makes a request to my website (which Twitter has to do to populate the card information from the meta tags) I check the user agent that made the request. If it was a Twitter bot (its user agent is currently Twitterbot/1.0) then I return the page with a 200 response code in my header and a meta tag redirect (just in case). Otherwise, I return with a 302 response code and the browser redirects my use there immediately.
This gets around the back button issue and the issue of the search engines not liking my site with the meta tag redirects (since there bots will never see them!).
UPDATE
I recently had someone ask for more details about how I did this, so I figured I would provide an example. I was using C# for my server, but the code is pretty simple to figure out if you are using a different language.
/// <summary>
/// Redirects a user to the location related to the given id.
/// </summary>
/// <param name="id"></param>
public ActionResult Index(Int32 id)
{
// Retrieve details about the short link id passed in
using (DataEntities context = new DataEntities())
{
ShortLink shortLink = context.ShortLinks.Single(s => s.Id == id);
// If the user agent is a twitter bot (currently Twitterbot/1.0), return the page with a meta redirect (just in case) so Twitter can still read the meta tags.
if (Request.UserAgent.ToString().ToLower().Contains("twitterbot"))
{
TwitterCardModel model = new TwitterCardModel
{
Id = id,
Site = "#YOUR_TWITTER_HANDLE",
Title = shortLink.Title,
Description = shortLink.Description,
RedirectUrl = shortLink.FullUrl,
ImageUrl = shortLink.ImageUrl
};
return View(model);
}
// Otherwise, redirect the user to the original page.
Response.Redirect(shortLink.FullUrl, true);
return null;
}
}
If the request was from a twitter bot, this was the HTML I returned:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
#* Twitter cards *#
<meta name="twitter:card" content="summary" />
<meta name="twitter:site" content="#Model.Site">
<meta name="twitter:title" content="#Model.Title" />
<meta name="twitter:description" content="#Model.Description" />
#if (!String.IsNullOrEmpty(Model.ImageUrl))
{
<meta name="twitter:image" content="#Model.ImageUrl">
}
<meta name="twitter:app:name:iphone" content="YOUR APP NAME"/>
<meta name="twitter:app:id:iphone" content="YOUR APPLE APP ID"/>
<meta name="twitter:app:url:iphone" content="YOUR DEEP LINK TO YOUR CONTENT IN YOUR APP"/>
#* Handle page redirect to the full article *#
<meta http-equiv="refresh" content="0;URL=#Model.RedirectUrl">
<title></title>
</head>
<body>
</body>

Encoding issue asp.net mvc 4

I´m trying to render a dynamic database title in asp.net mvc view. So I have something like this in my view.
#section meta {
<meta name="title" content="#Model.title" />
}
When model has special characters like Misión in spanish it shows in title something like
Misi&#243;n ... I´m using meta charset utf8 in my layout. Is there a special encoding I´m missing ?
How can I render Misión in title page ?
Using #someproperty will assume you're rendering out HTML and make sure it gets encoded to prevent things like cross site scripting. In this instance you want it to render the raw value, in which case you need to use Html.Raw(...) to render your content in it's raw form.
#section meta {
<meta name="title" content="#Html.Raw(Model.title)" />
}
However, just be aware that if the Model.title can come from user generated content (or some other untrusted source), you could be opening yourself up to security issues (for example if your Model.title's value was "test" /> <script ...etc...", a malicious user could use it to inject code into your pages.
Edit: Just including the content of my comment below for future googlers, since it appears that was the actual solution...
If you put the #Html.Raw(Model.title) directly in the page somewhere (i.e. not in the meta tag) and it works correctly there, you may be facing the same problem discussed here, in which case you could work around it by using the slightly uglier:
#section meta {
<meta name="title" #Html.Raw("content=\" + Model.title + "\"") />
}
Approach - 1
string value1 = "<html>"; // <html>
string value2 = HttpUtility.HtmlDecode(value1); // <html> //While getting
string value3 = HttpUtility.HtmlEncode(value2); // <html> //While saving
Approach - 2
Html.Raw("PKKG StackOverFlow"); // PKKG StackOverFlow

How to get at Header

I'm trying to pass the header object here:
<%=FileUtil.AddStylesheetToHeader(Header, "UsedItems.css") %>
In my Master page I have a <head runat="server">. And my aspx page definitely has a reference to my MasterPageFile in the page directive at the top of my MVC based .aspx.
I also have an import statement the namespace that the FileUtil class resides in :
<%# Import Namespace="xxxx.Web.Utilities" %>
In standard ASP.NET you could reference the header with this.Header but in MVC I'm not able to do this...or I'm missing some kind of Imports or something.
for some reason though at runtime, with that call to AddStylesheetToHeader, I get the following error:
The best overloaded method match for 'System.IO.TextWriter.Write(char)' has some invalid arguments.
I'm not sure why it's looking at a .NET type as I know when I mouseover my FileUtil at compile time it's definitely referencing xxxx.Web.Utilities.FileUtil.
In that method I'm using HtmlLink styleSheet = new HtmlLink(); I may not be able to use this as it's an ASP.NET Web control? Here's that method:
public static void AddStylesheetToHeader(HtmlHead header, string cssFilename)
{
HtmlLink styleSheet = new HtmlLink();
styleSheet.Href = "content/css/" + cssFilename;
styleSheet.Attributes.Add("rel", "stylesheet");
styleSheet.Attributes.Add("type", "text/css");
header.Controls.Add(styleSheet);
}
I don't think I can use conrols that stem from System.Web.Controls since this is an ASP.NET application? If so, the how can I add a control to the header controls collection? Would I need to do this differently in MVC?
There may be a way to do it the way you're attempting, but it's more common in ASP.NET MVC to create a content placeholder in the <head> rather than accessing it programmatically. For example, your master view could look something like this:
<html>
<head>
<asp:ContentPlaceHolder ID="HeadContent" runat="server" />
</head>
</html>
And your view could look like this:
<asp:Content runat="server" ContentPlaceHolderID="HeadContent">
<link href="/content/css/UsedItems.css" rel="Stylesheet" type="text/css" />
</asp:Content>
have you tried this.Request.Header?
You can use JavaScript to dynamically add content to your HEAD section as shown in the code below:
<script language="javascript" type="text/javascript">
$(document).ready(function() {
$("head").append("<link href='Content/Site.css' rel='stylesheet' type='text/css' />");
});
</script>

Resources