Penso che sia necessario generare dinamicamente un file robots.txt.
È necessario creare un RobotController per servire un file robots.txt.
Check Reference Here
correlati al link qui sopra era una domanda di permettere l'estensione .txt per essere servito da un'azione: https://stackoverflow.com/a/14084127/511438
public ActionResult Robots()
{
Response.ContentType = "text/plain";
//-- Here you should write a response with the list of
//areas/controllers/action for search engines not to follow.
return View();
}
Aggiungi un Robots.cshtml
Mappa un instradare in modo che una chiamata al file chiamerà invece l'azione sopra.
routes.MapRoute("Robots.txt",
"robots.txt",
new { controller = "Home", action = "Robots" });
Ecco l'attributo NoRobots con il codice per ottenere un elenco di aree/controllori/azioni che hanno l'attributo. Mi dispiace per l'interpretazione del testo completo del namespace. Mi piacerebbe che qualcuno guardasse il riflesso per risolvere meglio le cose.
public sealed class NoRobotsAttribute : System.Attribute
{
public static IEnumerable<MethodInfo> GetActions()
{
return Assembly.GetExecutingAssembly().GetTypes()
.Where(t => (typeof(Controller).IsAssignableFrom(t)))
.SelectMany(
type =>
type.GetMethods(BindingFlags.Public | BindingFlags.Instance)
.Where(a => a.ReturnType == typeof(ActionResult))
);
}
public static IEnumerable<Type> GetControllers()
{
return Assembly.GetExecutingAssembly().GetTypes()
.Where(t => (typeof(Controller).IsAssignableFrom(t)));
}
public static List<string> GetNoRobots()
{
var robotList = new List<string>();
foreach (var methodInfo in GetControllers().Where(w => w.DeclaringType != null))
{
var robotAttributes = methodInfo
.GetCustomAttributes(typeof(NoRobotsAttribute), false)
.Cast<NoRobotsAttribute>();
foreach (var robotAttribute in robotAttributes)
{
//-- run through any custom attributes on the norobots attribute. None currently specified.
}
List<string> namespaceSplit = methodInfo.DeclaringType.FullName.Split('.').ToList();
var controllersIndex = namespaceSplit.IndexOf("Controllers");
var controller = (controllersIndex > -1 ? "/" + namespaceSplit[controllersIndex + 1] : "");
robotList.Add(controller);
}
foreach (var methodInfo in GetActions())
{
var robotAttributes = methodInfo
.GetCustomAttributes(typeof(NoRobotsAttribute), false)
.Cast<NoRobotsAttribute>();
foreach (var robotAttribute in robotAttributes)
{
//-- run through any custom attributes on the norobots attribute. None currently specified.
}
List<string> namespaceSplit = methodInfo.DeclaringType.FullName.Split('.').ToList();
var areaIndex = namespaceSplit.IndexOf("Areas");
var area = (areaIndex > -1 ? "/" + namespaceSplit[areaIndex + 1] : "");
var controllersIndex = namespaceSplit.IndexOf("Controllers");
var controller = (controllersIndex > -1 ? "/" + namespaceSplit[controllersIndex + 1] : "");
var action = "/" + methodInfo.Name;
robotList.Add(area + controller + action);
}
return robotList;
}
}
Usage:
[NoRobots] //Can be applied at controller or action method level.
public class HomeController : Controller
{
[NoRobots]
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!";
List<string> x = NoRobotsAttribute.GetNoRobots();
//-- Just some test code that wrote the result to a webpage.
return View(x);
}
}
... e per aree.
namespace MVC.Temp.Areas.MyArea.Controllers
{
using MVC.Temp.Models.Home;
[NoRobots]
public class SubController : Controller
{
[NoRobots]
public ActionResult SomeAction()
{
return View();
}
}
}
Quindi, tenere a mente che la soluzione si basa su spazi dei nomi e sarebbe il benvenuto eventuali miglioramenti qualcuno può offrire.
Infine, è necessario scrivere correttamente il file del robot, comprese le informazioni di intestazione e il supporto di caratteri jolly.