Good day friends! Carefully prepared before asking a question. And so.

The task is this - there is often repeated layout code (the code itself is specially simplified, in fact, there are a lot of things because of which, in fact, the question of a more competent implementation arose). I want to make a similar Partial View:

<div id="{IDENT}"> @RenderBody </div> 

We have an IDENT (identifier) ​​and some kind of body. To further in some other View call something like this:

 @using(Html.DrawMyCustomSection("ident12345")) { <b>Передать в тело</b> } 

To have the output:

 <div id="ident12345"> <b>Передать в тело</b> </div> 

The question is in the very "elegance" of the decision. The easiest way is to refuse from Partial View in general and render everything using MvcHtmlString . But this, it seems to me, moveton and I do not see it as a worthy option.

The second way is to use a custom helper with IDisposable implementation and PartialView rendering with replacing control lines {IDENT} and {BODY} with your own. This option seems to be better, but not much :)

The third way is the strictly typed model for PartialView, in which everything is transmitted. A good way, as for me. But I can’t understand how to properly transfer the body itself to PartialView and how to deploy it there.

You can also wind the implementation with ViewBag / ViewData , but this is really bad.

Hence the question: How do you correctly , correctly and beautifully transfer the parameters to PartialView and render the body into the main view? Use a strongly typed model, whereas how to write (receive) into it what was in the main view is indicated in the body?

I will be glad to any answer and / or example. Thank!

  • one
    I do not work with ASP , but it's nice to see well-formed questions. Keep it up! - user207618
  • @Other thanks! I just know how they can be annoyed by the questions whose answers lie on the first page of Google :) It’s a pity that so far there are no answers ( - GRUNGER

2 answers 2

As I understand it, you need to create an analogue @using(Html.BegibForm()) . So it will be possible to wrap another razor markup in a div with a given id .

To do this, you will need to create a class or add a new html helper to the existing one (depending on how you store them).

Further an example for a separate class:

 using System; using System.IO; using System.Web.Mvc; namespace MyWebApplication.Helpers { public static class UserIdentityHelper { private const string TagName = "div"; private class UserIdentityContainer : IDisposable { private readonly TextWriter _writer; public UserIdentityContainer(TextWriter writer) { _writer = writer; } public void Dispose() { var builder = new TagBuilder(TagName); _writer.WriteLine(builder.ToString(TagRenderMode.EndTag)); } } public static IDisposable UserIdentity(this HtmlHelper htmlHelper, string userIdentifier) { var builder = new TagBuilder(TagName); builder.Attributes.Add("id", userIdentifier); var writer = htmlHelper.ViewContext.Writer; writer.WriteLine(builder.ToString(TagRenderMode.StartTag)); return new UserIdentityContainer(writer); } } } 

Do not forget to add a new namespace to web.config (if not added yet):

 <namespaces> ... <add namespace="MyWebApplication.Helpers" /> ... </namespaces> 

The call will look like this, for example.

 @using (Html.UserIdentity("ident12345")) { <h1>Hello ident12345!</h1> } 

As a result, the following markup will be obtained:

 <div id="ident12345"> <h1>Hello ident12345!</h1> </div> 

Note that the call to UserIdentity returns a class that implements IDisposable , and the closing tag is created with the TagRenderMode.EndTag parameter TagRenderMode.EndTag

  • Thank you very much for your reply and the time I take from you. But the question is precisely in the insertion of razor into another PartialView . Those. do not generate a tag through TagBuilder , but take PartialView and insert our body + id into it. Your method is great, but I would like to stop generating HTML code and use PartialView as a template. Is it possible? - GRUNGER
  • I apologize for not fully understanding the question. I have not yet met such a task, you need to think about how to implement it. - Andrew B

It seems to me that View Component was created for such purposes.

  1. Create a class with the name of the new component.

     [ViewComponent] public class ShowIdent { public string Invoke(string idParam, string textParam) { return $"<div id=\"{idParam}\"><b>{textParam}</b></div>"; } } 
  2. Call in the desired view

     @await Component.InvokeAsync("ShowIdent", new { idParam = "ident12345", textParam = "Передать в тело"}) 

For more information about View Component here: https://metanit.com/sharp/aspnet5/7.6.php