MVC 4强类型视图不通过控制器模型

时间:2013-01-31 18:25:40

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

不久前,我在当前的MVC 4项目中构建了维护请求功能。它完美地完成了所以当我需要添加另一个类似的工具请求功能时,我只使用稍微修改过的表和模型属性等相同的组合。现在由于某种原因,在工具请求控制器中没有任何模型绑定似乎工作(每个httppost方法)收到正在传递的模型的空值。

对于该功能,我创建了3个模型。基本上一个包含所有请求的列表,一个是每个请求本身的模型,其中包含与之关联的注释列表,然后第三个是注释模型。

型号:

    namespace TeamPortal.Models
{
    public class ToolingRequestModels
    {
        public List<ToolingRequestModel> ToolingRequests { get; set; }
        public SelectList Sources { get; set; }
        public SelectList Assignees { get; set; }
        public SelectList DefectTypes { get; set; }

        public ToolingRequestModels()
        {
            TeamPortalService TPsvc = new TeamPortalService();

            Sources = new SelectList(TPsvc.GetToolingRequestSources(), "Text", "Value");
            Assignees = new SelectList(TPsvc.GetToolingRequestAssignees(), "Text", "Value");
            DefectTypes = new SelectList(TPsvc.GetToolingRequestDefectTypes(), "Text", "Value");
        }

        public ToolingRequestModels(string ListType)
        {
            ToolingRequestModels baseModel = new ToolingRequestModels();

            TeamPortalService TPsvc = new TeamPortalService();

            List<int> RequestIDList = TPsvc.GetToolingRequests(ListType);

            List<ToolingRequestModel> tempToolingRequests = new List<ToolingRequestModel>();
            foreach (int requestID in RequestIDList)
            {
                ToolingRequestModel tempToolingRequestModel = new ToolingRequestModel(requestID, baseModel.Sources, baseModel.Assignees, baseModel.DefectTypes);
                tempToolingRequests.Add(tempToolingRequestModel);
            }
            ToolingRequests = tempToolingRequests;
        }
    }

    public class ToolingRequestModel
    {
        public int RequestID { get; set; }
        public string Requester { get; set; }
        public DateTime RequestDate { get; set; }
        public string Summary { get; set; }

        public SelectList Sources { get; set; }
        public string Source { get; set; }

        public string Description { get; set; }

        public SelectList Assignees { get; set; }
        public string AssignedTo { get; set; }

        public SelectList DefectTypes { get; set; }
        public string DefectType { get; set; }

        public string Status { get; set; }
        public string Model { get; set; }
        public DateTime? CompletionDate { get; set; }
        public bool CloseRequest { get; set; }

        public string AddNote { get; set; }
        public List<ToolingNoteModel> Notes { get; set; }

        public ToolingRequestModel()
        {
            TeamPortalService TPsvc = new TeamPortalService();

            Sources = new SelectList(TPsvc.GetToolingRequestSources(), "Text", "Value");
            Assignees = new SelectList(TPsvc.GetToolingRequestAssignees(), "Text", "Value");
            DefectTypes = new SelectList(TPsvc.GetToolingRequestDefectTypes(), "Text", "Value");
        }

        public ToolingRequestModel(int requestID, SelectList slSources, SelectList slAssignees, SelectList slDefectTypes)
        {
            TeamPortalService TPsvc = new TeamPortalService();

            ToolingRequestModel modelDetails = TPsvc.GetToolingRequestDetails(requestID);

            RequestID = requestID;
            Requester = modelDetails.Requester;
            RequestDate = modelDetails.RequestDate;
            Summary = modelDetails.Summary;
            Sources = slSources;
            Source = modelDetails.Source;
            Description = modelDetails.Description;
            Assignees = slAssignees;
            AssignedTo = modelDetails.AssignedTo;
            DefectTypes = slDefectTypes;
            DefectType = modelDetails.DefectType;
            Status = modelDetails.Status;
            Model = modelDetails.Model;
            CompletionDate = modelDetails.CompletionDate;

            Notes = TPsvc.GetToolingRequestNotes(requestID);


        }
    }

    public class ToolingNoteModel
    {
        public int ToolingNoteID { get; set; }
        public int RequestID { get; set; }
        public string NoteText { get; set; }
        public string NoteAuthor { get; set; }
        public DateTime NoteCreateDate { get; set; }
    }
}

为了简化操作,我们可以查看控制器和视图以添加新请求,但是在尝试更新请求时模型绑定也会失败。相当简单的输入形式,它确实有一个检查,以验证我们有模型输入的记录,没有找到记录,控制器方法被调用错误信息。

控制器:

        [ValidateInput(false)]
    public virtual ActionResult ToolingRequestAdd(bool? requestAdd, bool? badModel)
    {
        ToolingRequestModel model = new ToolingRequestModel();

        if (requestAdd == true)
        {
            ViewBag.RequestAdd = true;
        }
        else
        {
            ViewBag.RequestAdd = false;
        }

        if (badModel == true)
        {
            ViewBag.BadModel = true;
        }
        else
        {
            ViewBag.BadModel = false;
        }

        return View(model);
    }

    [HttpPost]
    [ValidateInput(false)]
    public virtual ActionResult ToolingRequestAdd(ToolingRequestModel model)
    {
        TeamPortalService TPsvc = new TeamPortalService();
        GP10Service gp10svc = new GP10Service();

        model.Requester = User.Identity.Name;
        model.RequestDate = DateTime.Now;
        model.Status = "New";

        if (gp10svc.CheckModelCode(model.Model))
        {
            return RedirectToAction("ToolingRequestAdd", new
            {
                requestAdd = false,
                badModel = true
            });
        }

        TPsvc.SaveToolingRequest(model);

        return RedirectToAction("ToolingRequestAdd", new
        {
            requestAdd = true
        });
    }

以下是观点:

    <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/FixedColumn.Master" Inherits="System.Web.Mvc.ViewPage<TeamPortal.Models.ToolingRequestModel>" %>

<asp:Content ID="Content3" ContentPlaceHolderID="HeadContent" runat="server">
</asp:Content>

<asp:Content ID="Content4" ContentPlaceHolderID="LeftContent" runat="server">
        <% Html.RenderPartial("LocalNavToolingRequests"); %>
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="RightContent" runat="server">

<div class="box">
        <!-- box / title -->
        <div class="title">
            <h5>
                Add Tooling Request</h5>
        </div>
        <%if (ViewBag.RequestAdd)
          { %>
              <div class="messages"><div id="successes0" class="message message-success"><div class="image"><img height="32" src="/Content/images/icons/success.png"></div><div class="text"><h6>Success</h6><span>Tooling Request Saved Successfully.</span></div><div class="dismiss"><a href="#successes0"></a></div></div></div>
        <%  } %>
        <%if (ViewBag.BadModel)
          { %>
              <div class="messages"><div id="errors0" class="message message-error"><div class="image"><img height="32" src="/Content/images/icons/error.png"></div><div class="text"><h6>Error</h6><span>The Spa Model Code Entered Was Invalid.  Verify The Model Is Still Active And The 3 Digits Are Correct.</span></div><div class="dismiss"><a href="#errors0"></a></div></div></div>
        <%  } %>

        <% using (Html.BeginForm())
           { %>

           <div class="form">
            <div class="fields">

            <div class="field  field-first">
                <div class="label">
                    <label>Request Summary:</label>
                </div>
                <div class="textbox">
                    <%: Html.TextBoxFor(m=>m.Summary) %>
                </div>
            </div>

            <div class="field">
                <div class="label">
                    <label>Model:</label>
                </div>
                <div class="textbox">
                    <%: Html.TextBoxFor(m=>m.Model) %>
                </div>
            </div>

            <div class="field">
                <div class="label">
                    <label>Source:</label>
                </div>
                <div class="select">
                    <%: Html.DropDownListFor(m => m.Source, Model.Sources)%>
                </div>
            </div>

            <div class="field">
                <div class="label">
                    <label>Defect Type:</label>
                </div>
                <div class="select">
                    <%: Html.DropDownListFor(m => m.DefectType, Model.DefectTypes)%>
                </div>
            </div>

            <div class="field">
                <div class="label">
                    <label>Description:</label>
                </div>
                <div class="textarea textarea-editor">
                    <%: Html.TextAreaFor(m => m.Description, 12, 70, new { @class = "tinymce-simple" })%>
                </div>
            </div>

            <% if (HttpContext.Current.User.IsInRole("Tooling"))
               { %>
            <div class="field">
                <div class="label">
                    <label>Assign Request To:</label>
                </div>
                <div class="select">
                    <%: Html.DropDownListFor(m => m.AssignedTo, Model.Assignees)%>
                </div>
            </div>
            <%} %>

            </div>
           </div>
           <input id="submit" name="submit" type="submit" value="Submit Request" />
       <%} %>

</div>

</asp:Content>

作为一种解决方法,我可以使用FormCollection重新创建一个新模型并在保存或重定向之前填充所需的属性,但是我真的想知道我在哪里出错(加上FormCollection很痛苦)。

非常奇怪,这在维护请求正常工作的地方失败了。我以为复制我之前的过程会省时间......

希望这个问题不是“过于本地化”,似乎可能取决于解决方案,如果是这样的话我可以在其他地方重新发布。

任何帮助都会很棒,请告诉我是否包含了足够(或太多)的代码/信息。谢谢!

1 个答案:

答案 0 :(得分:2)

当无法解析要绑定到哪个控制器参数时,默认模型绑定器将无法绑定(返回null)。

从您的View代码中,您似乎还必须拥有一个名为Model的模型属性。我会说这是在默认模型绑定器中与model HttpPost控制器中的参数名称ToolingRequestAdd发生冲突。

如果您将参数名称从model更改为toolingRequestModel之类的其他内容,我猜这可以解决问题。

例如:

[HttpPost]
[ValidateInput(false)]
public virtual ActionResult ToolingRequestAdd(ToolingRequestModel toolingRequestModel)
{
    TeamPortalService TPsvc = new TeamPortalService();
    GP10Service gp10svc = new GP10Service();

    toolingRequestModel.Requester = User.Identity.Name;
                         .
                         .
                         .
相关问题