如何在ASP.NET MVC4中绑定INamingContainer控件?

时间:2014-07-15 12:19:06

标签: c# asp.net-mvc-4 html-helper model-binding

我正在创建自定义HtmlHelper,在我的网页上生成一些网页控件,例如Panel, Label, TextBox and DropDownList。我的面板是INamingContainer,因此我可以对页面上的元素进行分组。

以下是代码示例:

class MyPanel : Panel, INamingContainer
        {
        }

public static MvcHtmlString Panel(this HtmlHelper html)
        {
            Panel pnl = new MyPanel();
            pnl.ID = "mainPanel";
            pnl.BorderStyle = BorderStyle.Solid;
            pnl.BorderWidth = Unit.Pixel(1);
            pnl.BorderColor = System.Drawing.Color.Black;

            Label lblTitle = new Label();
            lblTitle.Text = "Title";
            TextBox txtTitle = new TextBox();
            txtTitle.ID = "txtTitle";
            lblTitle.Attributes.Add("for", "txtTitle");

            Label lblMessage = new Label();
            lblMessage.Text = "Message";
            TextBox txtMessage = new TextBox();
            txtMessage.TextMode = TextBoxMode.MultiLine;
            txtMessage.ID = "txtMessage";

            Label lblDepartment = new Label();
            lblDepartment.Text = "Department";
            DropDownList lstDepartment = new DropDownList();
            lstDepartment.ID = "lstDepartment";
            ListItemCollection collection = new ListItemCollection();
            collection.Add(new ListItem("Department1"));
            collection.Add(new ListItem("Department3"));
            collection.Add(new ListItem("NoDepartment"));

            lstDepartment.DataSource = collection;
            lstDepartment.DataBind();

            pnl.Controls.Add(lblTitle);
            pnl.Controls.Add(txtTitle);
            pnl.Controls.Add(lblMessage);
            pnl.Controls.Add(txtMessage);
            pnl.Controls.Add(lblDepartment);
            pnl.Controls.Add(lstDepartment);

            HtmlTextWriter writer = new HtmlTextWriter(new StringWriter());
            pnl.RenderControl(writer);

            return MvcHtmlString.Create(writer.InnerWriter.ToString());
        }

现在,我需要在控制器中绑定这些元素。我执行应用程序(从上面的代码)得到的(作为HTML代码)是这样的:

<div id="mainPanel" style="border-color:Black;border-width:1px;border-style:Solid;">
        <span for="txtTitle">Title</span>
        <input name="mainPanel$txtTitle" type="text" id="mainPanel_txtTitle">
        <span>Message</span>
        <textarea name="mainPanel$txtMessage" rows="2" cols="20" id="mainPanel_txtMessage"></textarea>
        <span>Department</span>
        <select name="mainPanel$lstDepartment" id="mainPanel_lstDepartment">
            <option value="Department1">Department1</option>
            <option value="Department3">Department3</option>
            <option value="NoDepartment">NoDepartment</option>
        </select>
</div>


我应该期待什么参数,以及如何绑定它们?

修改

我在Editor Templates文件夹中创建了一些部分Razor视图。

_TicketTitle.cshtml

@model TicketSystemMVC.Models.Ticket

@Html.EditorFor(m => m.Title)

之后在我的模型中,我这样做了:

namespace TicketSystemMVC.Models
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;

    public partial class Ticket
    {
        public Ticket()
        {
            this.Ticket_Message = new HashSet<Ticket_Message>();
        }

        public int TicketID { get; set; }

        [Required]
        [StringLength(50, MinimumLength = 5)]
        [UIHint("_TicketTitle")]
        public string Title { get; set; }

        [Required]
        [StringLength(400, MinimumLength = 5)]
        [UIHint("_TicketMessage")]
        public string Message { get; set; }

        [DisplayName("Active ticket?")]
        public bool IsActive { get; set; }

        [DisplayName("Created on")]
        public System.DateTime CreatedOn { get; set; }
        public int AccountID { get; set; }

        [Required]
        [UIHint("_TicketDepartment")]
        public int DepartmentID { get; set; }

        public virtual Account Account { get; set; }
        public virtual Department Department { get; set; }
        public virtual ICollection<Ticket_Message> Ticket_Message { get; set; }
    }
}

我在控制器中做的是这个(只是调试和检查值的简单代码)

[HttpPost]
        public ActionResult Create(Ticket ticket)
        {
            string title = ticket.Title;
            string message = ticket.Message;
            string dep = ticket.DepartmentID.ToString();

            return View();
        }

视图

@model TicketSystemMVC.Models.Ticket
@using TicketSystemMVC

@{
    ViewBag.Title = "Create new ticket";
}

<h2>Create</h2>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Ticket</legend>

        @Html.Panel()

        <p>
            <input type="submit" value="Submit" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Go back", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

1 个答案:

答案 0 :(得分:0)

认为(如果我错了,请告诉我,我删除了这个答案)你想要实现的目标可以通过editor templates轻松完成:

  1. 创建一个名为eg的局部视图ListItemPanel
  2. 中的Views/Shared/EditorTemplates
  3. 定义其模型,如@model string(或任何适合您的类型)
  4. &#34;填写模板&#34;像:

    <div id="mainPanel" style="border-color:Black;border-width:1px;border-style:Solid;"> <span for="txtTitle">@Html.LabelFor(m => m)</span> <input name="mainPanel$txtTitle" type="text" id="mainPanel_txtTitle"> <span>Message</span> <textarea name="mainPanel$txtMessage" rows="2" cols="20" id="mainPanel_txtMessage"></textarea> <span>Department</span> @Html.DropDownFor(m => m) </div>

  5. 在您看来,您可以执行以下操作:

    @Html.EditorFor(m => m.Department, "ListItemPanel")

  6. [HttpPost] public ActionResult Create(MODEL model)中,您可以获得正确映射的值,例如model.Department

    注意:这只是一种基本的方式&#34;示例而非&#34;生产准备好的副本&amp;粘贴代码&#34;!