RickStrahl/Westwind.AspNetCore.Markdown

Please add default document support

haacked opened this issue · 9 comments

Great library! I'd like index.md to be treated similarly to index.html.

Repro setps

Here's my setup.

config.AddMarkdownProcessingFolder(
    "/about/",
    "~/Pages/__MarkdownPageTemplate.cshtml");

Then I add index.md into /wwwroot/about/

I would like to be able to visit localhost:5001/about and see index.md get rendered. I plan to have other files in the about folder so I can't name the file about.md and put it in the wwwroot. That won't work if I also have an about folder.

Thanks for considering it.

If you can read the existing default document settings and honor those, that would be great. Or just make this as a config setting.

Wouldn’t adding index.md to default documents do it?

I tried that.

app.UseDefaultFiles(new DefaultFilesOptions
            {
                DefaultFileNames = new List<string> { "index.md", "index.htm", "index.html" }
            });

I think to support this would require a change in the middleware. Look at this line. If the path doesn't have an extension, the code tries to append .md to the end.

But in the case of:

wwwroot\
   \about
      \policies
          \index.md

If I set index.md to be a default document, the the request path will be /about/policies. The current logic will try to locate the file by appending .md and look for /about/policies.md. It doesn't also try to look for /about/policies/index.md.

Hmmm... I would think that Default Files is re-writing the URL path internally. Make sure that the default file middleware is registered before the Markdown middleware to ensure the path is re-written beforehand.

Then again I remember that there was some trickery to get to the routing as part of the middleware so there maybe other timing issues involved.

Sorry - I'm not in the office to check right now, will check later when I get back.

Hmmm... I would think that Default Files is re-writing the URL path internally.

Yeah, but that wouldn't affect Request.Path which reflects the path of the request. So if I request /about/policies ASP.NET Core serves up /about/policies/index.md (if I set index.md as a default document), but it doesn't do an HTTP redirect to that URL (nor would anyone want that). And the HttpRequest.Path property thus would reflect /about/policies.

Make sure that the default file middleware is registered before the Markdown middleware to ensure the path is re-written beforehand.

That doesn't change anything per the point I made. Looking at your code, you're not relying on url rewriting anyways. Your code looks at the request Path and if it doesn't end in .md it appends the .md and tries to find the file to serve.

I think the adjustment needed is if it still doesn't find a file, to append an /index.md and see if that exists and serve that up if it does.

So I finally had some time to try this out. It looks to me like this works as expected with the default document middleware rewriting the request path as I would expect. If defined before the Markdown middleware the Default Document MW rewrites the path at the beginning of the request looking for a physical file if it exists.

Here's what I did to make this work:

app.UseDefaultFiles(new DefaultFilesOptions()
{
    DefaultFileNames = new List<string> { "index.md", "index.html" }
});

app.UseMarkdown();

I think it's critical that the default file middleware is installed before the Markdown module so it processes the path before the Markdown handler fires, because the Markdown middleware internally dismisses physical folder Urls.

I dropped in an in-between app.Use() to check the path and sure enough the path is rewritten at the beginning of the request and the updated path is passed into the Markdown Module.

End result is that the index.md displays if it exists on the /docs/ path.

image

Added some additional information to the Readme re: default documents. Also added a sample that demonstrates that this works in the sample Web project.

I think it's critical that the default file middleware is installed before the Markdown module

Which is what I had, but I also had the StaticFiles middleware before Markdown, and that ended up being my problem in the end.

So it's important that the markdown middleware must be between UseDefaultFiles and UseStaticFiles

Thanks for following up on this!

If UseStaticFiles() comes before the Markdown middleware what I see is that physical Markdown files render as text which is more of a general behavior. IAC you're correct it looks like it needs to sit in between the two - I'll update the docs.

Thanks for bringing this up though - I hadn't thought about this and just assumed this would work - as it does with some caveats.