Estou colocando parte das partes WebForms mais antigas do meu site, que ainda são executadas bare metal, no ASP.NET Core e nos Serviços de Aplicativo do Azure, e, enquanto faço isso, percebi que quero garantir que meus sites de armazenamento temporário não sejam indexado pelo Google / Bing.
Já tenho um robots.txt, mas quero um que seja específico para produção e outros que sejam específicos para desenvolvimento ou preparação. Pensei em várias maneiras de resolver isso. Eu poderia ter um robots.txt estático e outro robots-staging.txt e copiar condicionalmente um sobre o outro durante meu pipeline de CI / CD do Azure DevOps.
Então percebi que o mais simples possível seria tornar o robots.txt dinâmico. Pensei em escrever middleware personalizado, mas isso soou como um aborrecimento e mais código necessário. Eu queria ver o quão simples isso poderia ser.

- Você pode fazer isso como um único middleware em linha, e apenas lambda, func e linq, tudo isso em uma linha
- Você pode escrever seu próprio middleware e fazer muitas opções, e depois ativá-lo no env.IsStaging (), etc.
- Você pode criar uma única página do Razor com taghelpers de ambiente.
O último parecia mais fácil e também significaria que eu poderia alterar o cshtml sem uma recompilação completa, por isso criei uma página de navalha única RobotsTxt.cshtml. Nenhum modelo de página, nenhum código por trás. Em seguida, usei o auxiliar de marca de ambiente interno para gerar condicionalmente partes do arquivo. Observe também que forcei o tipo mime para texto / sem formatação e não uso uma página de layout, pois isso precisa ser independente.
@page @{ Layout = null; this.Response.ContentType = "text/plain"; } # /robots.txt file for http://www.hanselman.com/ User-agent: * <environment include="Development,Staging">Disallow: /</environment> <environment include="Production">Disallow: /blog/private Disallow: /blog/secret Disallow: /blog/somethingelse</environment>
Depois, certifico-me de que meus sistemas de armazenamento temporário e / ou produção tenham variáveis ASPNETCORE_ENVIRONMENT definidas adequadamente.

Também quero apontar o que pode parecer um espaçamento estranho e como algum texto é colocado contra os TagHelpers. Lembre-se de que a tag de um TagHelper às vezes "desaparece" (é elidida) quando é feita, mas o espaço em branco ao redor dela permanece. Então, eu quero que User-agent: * tenha uma linha e, em seguida, não permitir que apareça imediatamente na próxima linha. Embora possa ser um código-fonte mais bonito para começar em outra linha, não é um arquivo correto. Quero que o resultado seja firme e, acima de tudo, correto. Isto é para preparação:
User-agent: * Disallow: /
Isso agora me fornece um robots.txt em / robotstxt, mas não em /robots.txt. Veja o problema? Robots.txt é um arquivo (ou falso), portanto, preciso mapear uma rota da solicitação de /robots.txt para a página Razor chamada RobotsTxt.cshtml.
Aqui, adiciono um RazorPagesOptions em meu Startup.cs com um PageRoute personalizado que mapeia /robots.txt para / robotstxt. (Eu sempre achei essa API irritante, pois os parâmetros devem, IMHO, ser revertidos como ("de", "para"), então fique atento a isso, para que você não perca dez minutos como eu acabei de fazer.
public void ConfigureServices(IServiceCollection services) { services.AddMvc() .AddRazorPagesOptions(options => { options.Conventions.AddPageRoute("/robotstxt", "/Robots.Txt"); }); }
E é isso aí! Simples e limpo.
Você também pode adicionar o armazenamento em cache, se desejar, como um middleware maior ou mesmo na página cshtml, como
context.Response.Headers.Add("Cache-Control", $"max-age=SOMELARGENUMBEROFSECONDS");
mas deixarei essa pequena otimização como um exercício para o leitor.
ATUALIZAÇÃO: Depois que eu terminei, encontrei este middleware robots.txt e o NuGet no GitHub. Ainda estou feliz com meu código e não me importo de não ter uma dependência externa, mas é bom arquivar esse código para futuras necessidades e projetos mais sofisticados.
Como você lida com suas necessidades de robots.txt? Você ainda tem um?