CSHTML / Razor Views Documentation

I am working on documenting our display and editor templates (and as extensions, documenting all of our CSHTML would be helpful). Having said that, I have never seen any CSHTML Razor Views documentation methodology.

For example, I have this CSHTML EditorTemplate: MoneyPicker.cshtml

@model Decimal?
@{
    Layout = null;
}
<div class="money-picker" data-money-picker>
    <div class="form-control-wrapper">
        @Html.TextBox(
            "",
            ViewData.TemplateInfo.FormattedModelValue,
            new
            {
                type = "number",
                @class = "form-control money-control",
                placeholder = ViewData.ModelMetadata.Watermark ?? ViewData.ModelMetadata.DisplayName
            } )
    </div>
</div>

I know this is not C #, but is there any way to add XML documentation (or equivalent):

    /// <summary>
    /// Displays a text box wrapped with the money-picker wrappers, allowing javascript to show money buttons to pick the value.
    /// </summary>
    /// <param name="Model">A currency value</param>
    /// <remarks>
    /// The input is a text box that has the type "number"
    /// </remarks>

Or, if not, did anyone find a way to document editor / display templates that could be matched by some system similar to the Asp.Net WebApi api help page? Ideally, this will go even further and begin with the parent type and allow you to expand in each of the editors of the properties of this type, etc., but I just start from the beginning small.

EDIT: / , , .

+4
2

, - View, "" Controller:

/// <summary>
/// This is an example of documentation for the View.
/// </summary>
/// <returns>This is what I am returning.</returns>
public ActionResult CreateNewUser()
{
    return View();
}

, . SandCastle ( ) GhostDoc.


View .

@* This is a comment *@
+1

, .

MVC 5 MVC Core HtmlHelpers, MVC Core [:-(], MVC Core, .

, , MVC Core, Razor.

Catalog Final Review

ViewComponent, html, html.

HtmlHelper, .

HtmlHelpers html "ViewRole", , .

@model App.WebLib.AspNetCore.WebApp.Areas.AppHelpers.Models.AppHelpersViewModel

<div class="form-group">
    @Html.LabelTagFor(m => m.TextInput, 4)
    <div class="col-md-8">
        @Html.TextTagFor(Model.ViewRole, m => m.TextInput)
    </div>
</div>

@await Component.InvokeAsync("DisplaySource", new { executingViewPath = ViewContext.ExecutingFilePath, viewRole = Model.ViewRole })

@model App.WebLib.AspNetCore.WebApp.Areas.AppHelpers.Models.AppHelpersViewModel

@{
    var displayModel = Model.GetDisplayCopy();
}

<form class="form-horizontal">
    <div class="row">
        <div class="col-md-9">
            <h3>Estructura General de las Formas</h3>
            @Html.Partial("_FormLayout")

            <h3>Helper Básicos</h3>

            <h4>Campo de texto</h4>
            @Html.Partial("_TextInput")
            @Html.Partial("_TextInput", displayModel)

            <h4>Campo numérico</h4>
            @Html.Partial("_NumberInput")
            @Html.Partial("_NumberInput", displayModel)
        </div>
    </div>

</form>

Model

public class AppHelpersViewModel : ViewModelBase
{
    public AppHelpersViewModel()
    {
        ViewRole = ViewRole.Edit;
    }

    [Display(Name = "Text Display Name", Prompt = "Text Display Prompt")]
    public string TextInput { get; set; }

    [Display(Name = "Number Display Name")]
    public decimal NumberInput { get; set; }

    [Display(Name = "Date Display Name")]
    public DateTime? DateInput { get; set; }

    [Display(Name = "Bool Display Name", Prompt ="Bool Display Prompt")]
    public bool BoolInput { get; set; }

    [Display(Name = "Required Text Input Label", Prompt = "Placeholder Text")]
    [Required]
    public string RequiredTextInput { get; set; }


    public AppHelpersViewModel GetDisplayCopy()
    {
        var displayCopy = this.MemberwiseClone() as AppHelpersViewModel;

        displayCopy.ViewRole = ViewRole.Display;

        displayCopy.TextInput = "TextInput content";
        displayCopy.RequiredTextInput = "RequiredTextInput content";
        displayCopy.NumberInput = 45.4m;
        displayCopy.DateInput = new DateTime(2016, 10, 24);
        displayCopy.BoolInput = true;

        return displayCopy;
    }
}

ViewComponent

public class DisplaySourceViewComponent : ViewComponent
{
    public DisplaySourceViewComponent(IHostingEnvironment hostingEnvironment)
    {
        WebRootPath = hostingEnvironment.WebRootPath;
        ContentRootPath = hostingEnvironment.ContentRootPath;
    }

    public string ContentRootPath { get; set; }

    public string WebRootPath { get; set; }

    public async Task<IViewComponentResult> InvokeAsync(string executingViewPath, ViewRole viewRole)
    {
        if (viewRole != ViewRole.Display)
        {
            return new NullViewComponentResult();
        }

        IEnumerable<string> viewSource = await GetViewSourceAsync(executingViewPath);

        return View(viewSource);
    }

    private int GetLastContentIndex(List<string> lines)
    {
        for (int i = lines.Count - 1; i >= 0; i--)
        {
            if (!String.IsNullOrWhiteSpace(lines[i]))
            {
                return i;
            }
        }

        return -1;
    }

    private async Task<IEnumerable<string>> GetViewSourceAsync(string executingViewPath)
    {
        executingViewPath = executingViewPath.Substring(1).Replace('/', Path.DirectorySeparatorChar);

        string viewFilePath = Path.Combine(ContentRootPath, executingViewPath);

        var lines = new List<string>();

        using (var reader = new StreamReader(viewFilePath, Encoding.UTF8))
        {
            string line;

            while ((line = await reader.ReadLineAsync()) != null)
            {
                if (line.StartsWith("@model")) continue;
                if (line.StartsWith("@await") && line.Contains(@"InvokeAsync(""DisplaySource""")) continue;

                lines.Add(line);
            }
        }

        return Trim(lines);
    }

    private IEnumerable<string> Trim(List<string> lines)
    {
        var contentLines = new List<string>();

        int lastContentIndex = GetLastContentIndex(lines);

        for (int i = 0; i <= lastContentIndex; i++)
        {
            string line = lines[i];

            if (String.IsNullOrWhiteSpace(line) && contentLines.Count == 0) continue;

            contentLines.Add(line);
        }

        return contentLines;
    }
}

public class NullViewComponentResult : IViewComponentResult
{
    public void Execute(ViewComponentContext context)
    {
        return;
    }

    public Task ExecuteAsync(ViewComponentContext context)
    {
        return Task.CompletedTask;
    }
}

Todos

  • ViewComponent ( MVC Core 1.1) TagHelpers .
  • .
  • HtmlHelpers [ !; -)]

, .

0

Source: https://habr.com/ru/post/1660867/


All Articles