简体   繁体   English

如何在Aspnet.core Razor中的foreach循环中使用Model动态填充HTML?

[英]How to populate HTML dynamically with Model in a foreach loop in Aspnet.core Razor?

i am actually try to populate dynamically html code in Asp.Net Core Razor and i want to use something like this: 我实际上是尝试在Asp.Net Core Razor中动态填充html代码,并且我想使用如下代码:

@model Aktienverwaltung.Models.ProtokollDividenden

foreach (var item in Model)
{
   <div class="form-group row">
       <label asp-for="@item" class="col-lg-3 control-label text-lg-right pt-2" for="inputRounded"></label>
       <div class="col-lg-6">
           <input asp-for="@item" class="form-control input-rounded" id="inputRounded" />
       </div>
       <span asp-validation-for="@item" class="text-danger"></span>
   </div>
}

this is the part of my Controller: 这是我的控制器的一部分:

public async Task<IActionResult> Edit(Guid? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var protokollDividenden = await _context.ProtokollDividenden.FindAsync(id);
    if (protokollDividenden == null)
    {
        return NotFound();
    }
    // return View(await _context.ProtokollDividenden.ToListAsync());
    return View(protokollDividenden);
}

and the Model: 和模型:

public partial class ProtokollDividenden
    {
        public Guid Id { get; set; }
        public string Aktie { get; set; }
        public string Depotname { get; set; }
        public string Wkn { get; set; }
        public string Kuerzel { get; set; }
        public double Dividende { get; set; }
        public DateTime Datum { get; set; }
        public bool BereitsVerarbeitet { get; set; }
    }

Everything i tried goes wrong because i cant enumerate the Model or something else. 我尝试的所有内容都出错了,因为我无法枚举模型或其他内容。 I tried it as List too (see uncommented area in Controller), but i can`t get the foreach loop to work - did anyone have an idea ? 我也尝试将其作为List使用(请参阅Controller中未注释的区域),但是我无法使foreach循环正常工作-有人有想法吗?

First, you can only enumerate an enumerable , ie IEnumerable<T> , List<T> , etc. Right now, you have just a single item as your model, so the foreach will obviously fail. 首先,您只能枚举一个枚举 ,即IEnumerable<T>List<T>等。现在,您只有一个项目作为模型,因此foreach 显然会失败。

Assuming you do return an enumerable model, then your next issue is model binding. 假设您确实返回了可枚举的模型,那么下一个问题是模型绑定。 In order to properly bind the data you post back to a param on your action, list types must be named according to the format of CollectionProperty[N].Property , where N is an index. 为了正确地将您发布的数据绑定到操作上的参数,列表类型必须根据CollectionProperty[N].Property的格式命名,其中N是索引。 In order for things like tag helpers to generate the right name attributes on your form inputs, they need a full model expression. 为了使诸如标签助手之类的东西能够在表单输入中生成正确的name属性,它们需要完整的模型表达式。 You can think of a model expression as a map to a particular property you're trying to bind to. 您可以将模型表达式视为要绑定到的特定属性的映射。

Let's say you asked me for directions to a place. 假设您要我提供前往某个地方的路线。 You would ideally need the steps to begin from where you're at right now. 理想情况下,您需要从当前位置开始的步骤。 If I began my directions from some other place, that wouldn't be of much help, because then you would need directions to that place first , before you could follow my directions to your final destination. 如果我从其他地方开始我的路线,那将无济于事,因为在遵循我的路线到达最终目的地之前,您首先需要到达该位置的路线。

The concept is similar here. 这里的概念相似。 Using a foreach and creating an item variable, basically removes the first part of the directions. 使用foreach并创建item变量,基本上删除了指示的第一部分。 The tag helpers know how to get from item to the property you're binding to, but they don't know how to get to item . 标签助手知道如何从item到您要绑定的属性,但是他们不知道如何到达item As such, you'll end up with names like item.Foo , which will not be able to be bound to anything meaningful. 这样,您最终将获得诸如item.Foo类的item.Foo ,该名称将无法绑定到任何有意义的东西。 Instead, you need to use a for loop and the full model expression using the index in the loop: 相反,您需要在循环中使用for循环和使用索引的完整模型表达式:

@for (var i = 0; i < Model.Count; i++) // assuming `Model` is a list
{
    <input asp-for="@Model[i].Foo" />
}

It's worth noting that the value of asp-for above is a special construction required because Model itself is the list you're iterating over. 值得注意的是,上述asp-for的值是一种特殊的构造,因为Model本身就是您要迭代的列表。 If, instead it was a list property on model, you would simply use asp-for="ListProperty[i].Foo" . 相反,如果它是模型的list属性,则只需使用asp-for="ListProperty[i].Foo" The @Model part is there simply because some actual member must be used before the indexing notation. 之所以有@Model部分,是因为必须在索引符号之前使用一些实际的成员。 I've seen people get confused by this and start trying to affix @Model before everything, ie @Model.ListProperty[i].Foo . 我已经看到人们对此感到困惑,并开始尝试在所有内容之前贴上@Model ,即@Model.ListProperty[i].Foo

EDIT 编辑

OK. 好。 I think I know where you're going now, but your question was way off the mark in conveying that. 我想我知道你现在去,但你的问题是关闭的方式在传达该商标。 If you're looking for some way to automatically have inputs generated for you for every member of the model without having to go member by member, then the answer is, well, murky. 如果您正在寻找某种方法来自动为模型的每个成员生成输入,而不必逐个成员进行,那么答案很模糊。

There's Html.EditorFor and Html.EditorForModel (which I think still exists in ASP.NET Core... I don't use them personally). Html.EditorForHtml.EditorForModel (我认为它们仍存在于ASP.NET Core中……我个人不使用它们)。 Both are "templated helpers", which mean they rely on templates to determine how they handle what's passed into them. 两者都是“模板化助手”,这意味着它们依靠模板来确定如何处理传递给他们的内容。 Since you're working with your model directly here, you'd want Html.EditorForModel , which you'd use literally via the following in place of all your other current view code: 由于您是在这里直接使用模型,因此需要Html.EditorForModel ,您可以通过以下方式使用它代替所有其他当前视图代码:

@Html.EditorForModel()

Out of that box, that's going to look at each member and generate a set of inputs and labels for each, according to the specific types of the members, which will end up looking a little something like: 开箱即用,将根据成员的特定类型查看每个成员,并为每个成员生成一组输入和标签,最终看起来像:

<label for="Id">Id</label>
<input id="Id" name="Id" value="" />

<label for="Aktie">Aktie</label>
<input id="Aktie" name="Aktie" value="" />

<label for="Depotname">Depotname</label>
<input id="Depotname" name="Depotname" value="" />

...

There are some obvious issues with this. 这有一些明显的问题。 It doesn't have any of your Bootstrap classes or structure, so it's going to look awful. 它没有任何Bootstrap类或结构,因此看起来很糟糕。 It's very simple in it's interpretation of type to input mapping. 从类型到输入映射的解释非常简单。 For example, Id is something that should actually probably not be there at all or if it is present, it should be an a hidden input. 例如, Id是实际上可能根本不存在的东西,或者如果存在,则应该是隐藏的输入。 Aktie may be a long form text field, but you're always going to get an input, rather than something like textarea . Aktie可能是一个长格式的文本字段,但是您总会得到一个输入,而不是诸如textarea东西。 Maybe Depotname should be a select with some list of possible choices, but again, you're only ever going to get a basic text input. 也许Depotname应该是select有可能的选择一些名单,但同样,你永远只能会得到一个基本的文本输入。 The list goes on. 名单还在继续。

Some of these can be fixed easier than others. 其中一些可以比其他更容易修复。 To have a hidden input, apply the [HiddenInput] attribute to the property in your class. 若要具有隐藏的输入,请将[HiddenInput]属性应用于您的类中的属性。 The DataType attribute can be applied to give some more context. 可以应用DataType属性来提供更多上下文。 For example, if you want a textarea , you can apply [DataType(DataType.MultilineText)] to the property in your class. 例如,如果您需要textarea ,则可以将[DataType(DataType.MultilineText)]到类中的属性。 If you need to change the label text, you can do that with [Display(Name = "My Label Text")] . 如果需要更改标签文本,可以使用[Display(Name = "My Label Text")]进行更改。

For more complex things, that's where templates start to come in. For example, you can create a view like Views\\Shared\\EditorTemplates\\String.cshtml and inside add: 对于更复杂的事情,模板就是从这里开始的。例如,您可以创建一个诸如Views\\Shared\\EditorTemplates\\String.cshtml类的Views\\Shared\\EditorTemplates\\String.cshtml并在其中添加:

@model string

<div class="form-group row">
   <label asp-for="@Model" class="col-lg-3 control-label text-lg-right pt-2" for="inputRounded"></label>
   <div class="col-lg-6">
       <input asp-for="@Model" class="form-control input-rounded" id="inputRounded" />
   </div>
   <span asp-validation-for="@Model" class="text-danger"></span>

Then, this will be used for any string type member. 然后,它将用于任何string类型的成员。 As you might imagine, you can add other such views like DateTime.cshtml , Int32.cshtml , etc., which will each be used for their respective types. 就像您想象的那样,您可以添加其他诸如DateTime.cshtmlInt32.cshtml等的视图,这些视图将分别用于各自的类型。 You can also add templates for any of the members of that DataType enum, so you can have MultilineText.cshtml , EmailAddress.cshtml , etc. Finally, there is a UIHint attribute that can be applied to specify any template. 您还可以为该DataType枚举的任何成员添加模板,因此可以具有MultilineText.cshtmlEmailAddress.cshtml等。最后,有一个UIHint属性可用于指定任何模板。 For example, if you applied [UIHint("Foo")] to a property, then Foo.cshtml would be used. 例如,如果将[UIHint("Foo")]应用于属性,则将使用Foo.cshtml

You can also create templates for your own custom types. 您也可以为自己的自定义类型创建模板。 So, for example, you could have a ProtokollDividenden.cshtml and then this view would actually be used as the template for that class, which then means it would be used for your call to @Html.EditorForModel() . 因此,例如,您可能有一个ProtokollDividenden.cshtml ,然后此视图实际上将用作该类的模板,这意味着它将用于您对@Html.EditorForModel()调用。

However, with all of this, it's important to note that once you add a custom template, you are 100% responsible for that now. 但是,所有这些都需要注意,一旦添加了自定义模板,您现在就要100%负责。 In other words, if you were to add a view for your whole model, then that would take over, and Html.EditorForModel wouldn't actually generate the individual fields any more for you, basically bringing you back to the same problem you started with. 换句话说,如果您要为整个模型添加视图,则将接管该操作,而Html.EditorForModel实际上将不再为您生成单个字段,基本上使您回到了开始时遇到的相同问题。 Instead, it would simply dump your custom template and call it a day. 相反,它只会转储您的自定义模板并每天调用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将.NetFramework 中的MessageHandler 转换为AspNet.Core - How to convert MessageHandler in .NetFramework to AspNet.Core 如何在 AspNet.Core 中读取 EXIF 数据 - How can i read EXIF data in AspNet.Core 如何在aspnet.core web api中验证JWT令牌? - How to validate JWT Token in aspnet.core web api? 用于集成测试的ASPNet.Core HostingEnvironment? - ASPNet.Core HostingEnvironment for Integration Tests? 为什么 Aspnet.Core model 验证不会在 Nullable 属性上引发异常? - Why does not Aspnet.Core model validation throw an exception on Nullable properties? 如何在ASPNET.Core Web应用程序中使用CORS标头发送HTTP 4xx-5xx响应? - How to send an HTTP 4xx-5xx response with CORS headers in an ASPNET.Core web app? 如何使用[HttpGetAttribute]路由包括AspNet.Core WebApi应用程序中的查询字符串? - How to route using [HttpGetAttribute] including the query strings in AspNet.Core WebApi application? Aspnet.core 程序登录但考虑同一个表中的数据 - The Aspnet.core program logs in but considers the data in the same table 在As.net.Core 中,我们可以更改端口号吗? - In Aspnet.Core, can we change port number? 是否可以为ASPNET.Core OData声明多个路由 - Is it possible to declare multiple routes for ASPNET.Core OData
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM