Как Asp.net Core отображает представление

Как MVC 6 отображает представление. Какой фактический метод в Razor ViewEngine генерирует вывод html? Также, если возможно, объясните процесс рендеринга вида.

Может быть, вы могли бы указать мне файл на источнике mvc на github. Благодарность!


person eadam    schedule 12.01.2015    source источник
comment
Я боюсь, что это слишком широко, чтобы ответить, но в основном ViewResult (return View()) компилирует соответствующее представление, используя компилятор C # на лету. Я не думаю, что это задокументировано где-либо, кроме как в самом источнике. Что мешает вам загрузить исходное дерево и найти то, что вы ищете? Что именно вы пытаетесь сделать, почему вы хотите знать?   -  person CodeCaster    schedule 12.01.2015
comment
Я пытаюсь создать свой собственный htmlHelper на лету через код, а затем визуализировать представление в зависимости от предоставленной модели. Я также изучаю исходный код, но его трудно найти без документации.   -  person eadam    schedule 12.01.2015
comment
Эта цель звучит немного наоборот. Конечно, контролер может/должен принять решение. Вы действительно имеете в виду частичные просмотры?   -  person Gone Coding    schedule 12.01.2015
comment
@Eilon Проверьте ответ ниже.   -  person Amete Blessed    schedule 25.01.2016


Ответы (2)


Вот полное решение того, что вы ищете. Я использовал внедрение зависимостей, чтобы получить HtmlHelper в контроллере. Вы также можете внедрить своего собственного помощника, если хотите.

using Microsoft.AspNet.Html.Abstractions;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Mvc.ViewEngines;
using Microsoft.AspNet.Mvc.ViewFeatures;
using Microsoft.AspNet.Mvc.ViewFeatures.Internal;
using Microsoft.Extensions.WebEncoders;
using System.ComponentModel.DataAnnotations;
using System;

 public class MyController : Controller
 {
    private readonly IHtmlGenerator htmlGenerator;
    ICompositeViewEngine viewEngine;
    IModelMetadataProvider metadataProvider;
    private readonly IHtmlHelper helper;
    IHtmlEncoder htmlEncoder;
    IUrlEncoder urlEncoder;
    IJavaScriptStringEncoder javaScriptStringEncoder;

    public MyController(IHtmlHelper helper, IHtmlGenerator htmlGenerator, ICompositeViewEngine viewEngine, IModelMetadataProvider metadataProvider, IHtmlEncoder htmlEncoder, IUrlEncoder urlEncoder, IJavaScriptStringEncoder javaScriptStringEncoder)
    {

        this.htmlGenerator = htmlGenerator;
        this.viewEngine = viewEngine;
        this.metadataProvider = metadataProvider;
        this.htmlEncoder = htmlEncoder;
        this.urlEncoder = urlEncoder;
        this.javaScriptStringEncoder = javaScriptStringEncoder;
        this.helper = helper;
    }

    [HttpGet]
    public IActionResult MyHtmlGenerator()
    {
        MyViewModel temp = new MyViewModel();


        var options = new HtmlHelperOptions();
        options.ClientValidationEnabled = true;

        ViewDataDictionary<MyViewModel> dic = new ViewDataDictionary<MyViewModel>(this.metadataProvider, new ModelStateDictionary());

        ViewContext cc = new ViewContext(ActionContext, new FakeView(), dic, TempData, TextWriter.Null, options);

        var type = typeof(MyViewModel);
        var metadata = this.metadataProvider.GetMetadataForType(type);


        ModelExplorer modelEx = new ModelExplorer(this.metadataProvider, metadata, temp);
        ViewData["Description"] = "test desc";
        ViewData["Id"] = 1;

        this.ViewData = new ViewDataDictionary(this.metadataProvider, new ModelStateDictionary());

        IHtmlHelper<MyViewModel> dd = new HtmlHelper<MyViewModel>(this.htmlGenerator, this.viewEngine, this.metadataProvider, this.htmlEncoder, this.urlEncoder, this.javaScriptStringEncoder);
        ((ICanHasViewContext)dd).Contextualize(cc);
        dd.ViewContext.ViewData = this.ViewData;

        var desc = GetString(dd.TextBoxFor(m => m.ID));
        var ID = GetString(dd.TextBoxFor(m => m.Description));

        // Do whatever you want with the ID and desc

        return new ContentResult() { Content = ID + desc };

    }

    public static string GetString(IHtmlContent content)
    {
        var writer = new System.IO.StringWriter();
        content.WriteTo(writer, new HtmlEncoder());
        return writer.ToString();
    }
}


public class MyViewModel : BaseAssetViewModel
{
    //  [RegularExpression(@"^-?\d{1,13}(\.\d{0,5})?$|^-?\.\d{1,5}$")]
    [Required]
    public int ID { get; set; }

    [MinLength(2)]
    public string Description { get; set; }

    // Property with no validation
    public string Other { get; set; }
}


public class FakeView : IView
{
    string IView.Path
    {
        get
        {
            throw new NotImplementedException();
        }
    }

    public Task RenderAsync(ViewContext viewContext)
    {
        throw new InvalidOperationException();
    }

    Task IView.RenderAsync(ViewContext context)
    {
        throw new NotImplementedException();
    }
}
person Amete Blessed    schedule 22.01.2016
comment
Спасибо, мне было интересно, как я могу создать ModelExplorer, чтобы иметь возможность использовать IHtmlGenerator для создания элементов htm. Хотя не слишком ли это много, так как он выполняется каждый раз? - person Haytam; 08.09.2018

Я не знаю, может ли это помочь, может быть, вам нужно начать смотреть на помощники тегов:

https://github.com/DamianEdwards/TagHelperStarterWeb

они работают над другим способом создания помощников, которые интегрируются на странице более естественным образом.

person Luca Morelli    schedule 13.01.2015