Ajax.ActionLink without href attribute for better SEO - ajax

I am using Ajax.ActionLink to display an hyperlink and when clicked make an ajax request (for example the flag hyperlink in this site, report, etc) and put the result in some div, this all can be easily done with this method, but the problems comes with SEO, because this hyperlink actually have and href attribute and the spider follow the url.
I want an anchor without href to make it SEO friendly and extension method to do all that, but with all the overloads of Ajax.ActionLink example:
Ajax.SEOFriendlyActionLink("my hyperlink", "action", "controller" ... more options)
this can generate something like this
<a urlForAjax="url here">my hyperlink</a>
Of course making the ajax callbacks.
Is there any thing like this out there?

The solution is as follows:
Ajax.ActionLink("my hyperlink", "", "" ... new AjaxOptions() { Url = Url.Action("action", "controller") ... })
It will generate something like this:
< a href="/" data-ajax-url="url here" ...> </a>

The solution given by #kyw is good but have one drawback. The link can be opened in newtab which is propably not the behaviour we are looking for.
We will change code a little :
Ajax.ActionLink("my hyperlink", "", "" ... new AjaxOptions() { Url = Url.Action("action", "controller") ... }, new { href = "!!"})
Now we need some jQuery :
$('a[href$="!!"]').each(function (index, element) {
element.removeAttribute("href");
});
From now on every link which href is ending on !! will have this attribute removed, thus it will disable option to open link in new tab.

Related

Fanycbox 1.3.4 ajax issue with ASP.NET MVC

I'm using Fancybox 1.3.4 with ASP.NET MVC 3.
I have following link :
<a id="various" href="Like/List/#feed.Id" class="petlikeCount liked">#feed.LikeCount</a>
and also jquery :
<script type="text/javascript">
$(document).ready(function () {
$("#various").fancybox({
type: 'ajax'
});
});
</script>
Controller action in Like controller :
public JsonResult List(int id)
{
return Json("success", JsonRequestBehavior.AllowGet);
}
My problem is that Like/List is never called (checked with the breakpoint) and fancybox just appears and show content of "parent" page....
I also tried with iframe content returning pure html back, but I'm getting same strange behavior as above.
Thank you in advance!
I'd recommend you using HTML helpers instead of hardcoding anchors:
#Html.ActionLink(
feed.LikeCount,
"List",
"Like",
new { id = feed.Id },
new { id = "various", #class = "petlikeCount liked" }
)
Another thing that you should make sure is that the feed.Id is actually an integer variable so that when the List action is invoked it is correctly passed this id.
So your url should look something like this: /List/Like/123. And then assuming tat you have kept the default route and haven't messed up with some custom routes, the List action should be called and passed the correct id as argument.
Also I would very strongly recommend you using a javascript debugging tool in your browser such as FireBug in which you will be able to see any potential errors with your scripts as well as the actual AJAX requests being sent which will allow you to more easily debug such problems.

Best way to create an Ajax Image ActionLink

I want to create in ASP.NET MVC 3 a link (in Ajax) with an image as background and no text. I'm using this method that creates an ajax link manually:
<div class="icon icon_like"></div>
The div tag calls the class "icon icon_like" of CSS that will import an image.
My question, is the following:
There is no other way (maybe a helper) to being able to do this easily?
UPDATE:
gdoron redirected me to a good link but it was not quite what I wanted (no Ajax support). For me, the first torm's answer is better, I only made some few changes to make it universal:
First in the helper it supports now a routeValues and changing the section that is to be updated
#helper AjaxImageLink(string action, Object routeValues, string icon_name, string sectionToUpdate = "#result"){
<div class="icon #icon_name"></div>
}
About the use of that helper I'm using for the example in question:
#AjaxImageLink("Like", new { controller = "Article", like = 1, id = Model.Item1.ID }, "icon_like")
And it works as it should.
To be compliant with DRY principle you can easily wrap your link structure in an inline helper like :
#helper AjaxLink(string action, string controller, string icon_name){
<div class="icon #icon_name"></div>
}
other way would be to take ajax portion to unobtrusive reusable jquery binding :
</div>
$('.ajaxLink').click(function (e) {
e.preventDefault();
$("#result").load($(this).attr("href");
});
You can see this question.
There are many others examples for it in the internet just google "asp.net mvc image action link"
use ajax.actionlink inside html.Raw and replace ajax.actionlink text with image tag.
simple one line code.
#Html.Raw(#Ajax.ActionLink("[replacetext]", "Action", "Controller", new AjaxOptions { HttpMethod="Post"}).ToHtmlString().Replace("[replacetext]", ""))

Issue with wrong controller being called in jquery ajax call

My issue is for some strange reason it seems stuck in the page controller so instead of getting out and going into the ajax controller I have it trying to go down that route in the page controller
1st try
http://localhost:2185/Alpha/Ajax/GetBlah_Name/?lname=Ge&fname=He
2nd try
http://localhost:2185/Patient/~/Ajax/GetBlah_Name/?lname=Ge&fname=He
Objective
http://localhost:2185/Ajax/GetBlah_Name/?lname=Ge&fname=He
Page button to call jquery
<a style="margin-left: 310px;" href="javascript:void(0)" onclick="getBlah()"
class="button"><span>Lookup</span></a>
Jquery code
1st try
{
$.getJSON(callbackURL + 'Ajax/GetBlah_Name/?lname=' + $('#Surname').val() + '&fname=' + $('#FirstName').val(), null, GetResults)
}
2nd try
{
$.getJSON(callbackURL + '~/Ajax/GetBlah_Name/?lname=' + $('#Surname').val() + '&fname=' + $('#FirstName').val(), null, GetResults)
}
In summary I don't know why it won't break out of the controller and go into the Ajax controller like it has done so in all the other projects I've done this in using the 1st try solution.
It seems you want to cal a controller at ~/Ajax. Is it? If yes, you should use this code:
$.getJSON(callbackURL + '/Ajax/GetBlah_Name/?lname=' + $('#Surname').val() + '&fname=' + $('#FirstName').val(), null, GetResults)
UPDATE:
This will work for your Q, but the complete solution is #Darin Dimitrov's answer. I suggest you to use that also.
UPDATE2
~ is a special character that just ASP.NET works with it! So http doesn't understand it. and if you start your url with a word -such as Ajax-, the url will be referenced from where are you now (my english is not good and I can't explain good, see example plz). For example, you are here:
http://localhost:2222/SomeController/SomeAction
when you create a link in this page, with this href:
href="Ajax/SomeAction"
that will be rendered as
http://localhost:2222/SomeController/Ajax/SomeAction
But, when url starts with /, you are referring it to root of site:
href="/Ajax/SomeAction"
will be:
http://localhost:2222/Ajax/SomeAction
Regards
There are a couple of issues with your AJAX call:
You are hardcoding routes
You are not encoding query string parameters
Here's how I would recommend you to improve your code:
// Always use url helpers when dealing with urls in an ASP.NET MVC application
var url = '#Url.Action("GetBlah_Name", "Ajax")';
// Always make sure that your values are properly encoded by using the data hash.
var data = { lname: $('#Surname').val(), fname: $('#FirstName').val() };
$.getJSON(url, data, GetResults);
Or even better. Replace your hardcoded anchor with one which will already contain the lookup url in its href property (which would of course be generated by an url helper):
<a id="lookup" href="Url.Action("GetBlah_Name", "Ajax")" class="button">
<span>Lookup</span>
</a>
and then in a separate javascript file unobtrusively AJAXify it:
$(function() {
$('#lookup').click(function() {
var data = { lname: $('#Surname').val(), fname: $('#FirstName').val() };
$.getJSON(this.href, data, GetResults);
return false;
});
});
Now how your urls will look like will totally depend on how you setup your routes in the Application_Start method. Your views and javascripts are now totally agnostic and if you decide to change your route patterns you won't need to touch jaavscript or views.

Getting raw text using #Html.ActionLink in Razor / MVC3?

Given the following Html.ActionLink:
#Html.ActionLink(Model.dsResults.Tables[0].Rows[i]["title"].ToString(), "ItemLinkClick",
new { itemListID = #Model.dsResults.Tables[0].Rows[i]["ItemListID"], itemPosNum = i+1 }, ...
Data from the model contains HTML in the title field. However, I am unable to display the HTML encoded values. ie. underlined text shows up with the <u>....</u> around it.
I've tried Html.Raw in the text part of the ActionLink, but no go.
Any suggestions?
If you still want to use a helper to create an action link with raw HTML for the link text then I don't believe you can use Html.ActionLink. However, the answer to this stackoverflow question describes creating a helper which does this.
I would write the link HTML manually though and use the Url.Action helper which creates the URL which Html.ActionLink would have created:
<a href="#Url.Action("ItemLinkClick", new { itemListID = #Model.dsResults.Tables[0].Rows[i]["ItemListID"], itemPosNum = i+1 })">
#Html.Raw(Model.dsResults.Tables[0].Rows[i]["title"].ToString())
</a>
MVCHtmlString.Create should do the trick.
Using the actionlink below you do not need to pass html in the model. Let the css class or inline style determine how the href is decorated.
#Html.ActionLink(Model.dsResults.Tables[0].Rows[i]["title"], "ItemLinkClick", "Controller", new { #class = "underline", style="text-decoration: underline" }, null)
those are the cases that you should take the other path
#{
string title = Model.dsResults.Tables[0].Rows[i]["title"].ToString(),
aHref = String.Format("/ItemLinkClick/itemListID={0}&itemPosNum={1}...",
Model.dsResults.Tables[0].Rows[i]["ItemListID"],
i+1);
}
#Html.Raw(title)
Remember that Razor helpers, help you, but you can still do things in the HTML way.
You could also use this:
<a class='btn btn-link'
href='/Mycontroler/MyAction/" + item.ID + "'
data-ajax='true'
data-ajax-method='Get'
data-ajax-mode='InsertionMode.Replace'
data-ajax-update='#Mymodal'>My Comments</a>

Encode dataview value in ASP.NET MVC Actionlink

I am using the Microsoft Ajax Template DataView to bind values to a template. I can do this and it works as you'd expect:
<h3>{{ID}}</h3>
<p>{{Address}}</p>
However I am trying to build an action link that has the ID in it.
<h2><%= Html.ActionLink(Html.AttributeEncode("{{Name}}"), "Index", "Restaurant", new { Id = Html.AttributeEncode("{{ID}}") }, null)%></h2>
The name is shown as the link text as I wanted but the link doesn't include the ID, instead it has %7B%7BID%7D%7D
How would I get the Id to be properly parsed and added to the link?
It's possible that the extra brackets are throwing it off. Try assigning the values to variables and using the variables in the ActionLink. You could do the assignment at the top of the view and then reuse them throughout the view as well. to keep from having to re-encode them everywhere.
<% var id = Html.AttributeEncode( "{{ID}}" );
var name = Html.AttributeEncode( "{{Name}}" );
%>
<h2><%= Html.ActionLink(name, "Index", "Restaurant", new { Id = id }, null)%></h2>
Finally got it to work, I don't know if I was being stupid or if it's the lack of documentation but here is how to bind the dataview value to a link.
<h2><a sys:href="{{'Restaurant/Index/' + ID}}">{{Name}}</a></h2>
The actual url route part needs to be in single quotes and you need to use sys:href instead of href.
Its good practice to include '<%= Url.Action("Index", "Restaurant")%>' when builing a manual url to avoid problems with the application name and conflicting urls.

Resources