返回的视图模型大多为null

时间:2017-09-29 14:26:10

标签: asp.net-mvc

我正在为从同事继承的ASP.NET MVC应用程序添加其他功能。由于某些原因,除SelectedPartyRole之外的所有属性在控制器上的null方法的视图模型参数中都是AddParticipant,尽管数据先前已从数据库返回。

型号:

public class AddParticipantViewModel
{
    public string ClaimNumber { get; set; }
    public string PolicyNumber { get; set; }
    public string PartyNumber { get; set; }
    public string PartyName { get; set; }
    public string TaxID { get; set; }
    public string SelectedPartyRole { get; set; }
    public Dictionary<string, string> ValidPartyRoles { get; set; }
}

查看:

@model TN_IntegrationDashboard.Web.Models.AddParticipantViewModel

@{
    ViewBag.Title = "AddClaimParticipant";
    Layout = "~/Views/Shared/_Layout.cshtml";
 }

<div id="sectionTitle">
    <h2>Add Claim Participant</h2>
</div>
<br /><br /><br />
<fieldset>
<legend></legend>

<div class="status">@ViewBag.Result</div>
<br /><br />
<table style="width: 100%;">
    <tr style="background-color:#3B4044;color:white;height:45px; vertical-align: central;font-weight:600;">
        <th>Claim Number</th>
        <th>Policy Number</th>
        <th>Party Number</th>
        <th>Party Name</th>
        <th>Tax ID</th>
    </tr>
    <tr>
        <td>@Html.DisplayFor(model => model.ClaimNumber)</td>
        <td>@Html.DisplayFor(model => model.PolicyNumber)</td>
        <td>@Html.DisplayFor(model => model.PartyNumber)</td>
        <td>@Html.DisplayFor(model => model.PartyName)</td>
        <td>@Html.DisplayFor(model => model.TaxID)</td>
    </tr>
</table>

<br /><br /><br />
<div>
    <button type="button" id="ShowHide">Select Role</button>
</div>


<br /><br /><br />

<div id="ShowHideUpdateControls" hidden="@(ViewBag.Success = true ? "" : "hidden")">

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

<table style="width: 100%;">
    <tr style="background-color:#3B4044;color:white;height:45px; vertical-align: central;font-weight:600;">
        <th>Valid Party Roles</th>
    </tr>
    <tr>
        <td>@Html.DropDownListFor(m => m.SelectedPartyRole,
                                  new SelectList(Model.ValidPartyRoles, "Key", "Value"),
                                  "")</td>
    </tr>
</table>
 <br /><br /><br />

 <input type="submit" value="Save" formaction='@Url.Action("AddParticipant")'>

 }

</div>
</fieldset>

控制器:

public class ClaimController : Controller
{
    [HttpGet]
    [AuthorizeByConfig(RolesAppSettingKey = "", UsersAppSettingKey = "ClaimUpdateAuthorizedUsers")]
    public ActionResult SearchForClaimParticipant()
    {
        return View();
    }

    [HttpPost]
    [AuthorizeByConfig(RolesAppSettingKey = "", UsersAppSettingKey = "ClaimUpdateAuthorizedUsers")]
    public ActionResult SearchForClaim(string claimNumber)
    {
        IClaimManager proxy = CreateClaimManagerProxy();
        var claim = proxy.GetClaim(claimNumber);

        if (claim == null)
        {
            ViewBag.Status = "Claim record not found. Please enter a different claim number.";
            return View("SearchForClaim");
        }
        else
        {
            var modifyClaimViewModel = new ClaimViewModel
            {
                ClaimNumber = claim.ClaimNumber,
                NotificationDate = claim.NotificationDate
            };
            return View("ModifyClaim", modifyClaimViewModel);
        }
    }

    [HttpPost]
    [AuthorizeByConfig(RolesAppSettingKey = "", UsersAppSettingKey = "ClaimUpdateAuthorizedUsers")]
    public ActionResult SearchForClaimParticipant(string claimNumber, string partyNumber)
    {
        IClaimManager claimProxy = CreateClaimManagerProxy();
        IPartyAdminManager partyProxy = CreatePartyAdminManagerProxy();

        var claim = claimProxy.GetClaim(claimNumber);
        var party = partyProxy.GetParty(partyNumber);

        var errorMessage = string.Empty;
        if (claim == null)
            string.Concat(errorMessage, "Claim record not found. Please enter a different claim number. ");
        if (party == null)
            string.Concat(errorMessage, "Party record not found. Please enter a different party number.");

        if (errorMessage.Length > 0)
        {
            ViewBag.Status = errorMessage;
            return View("SearchForClaimParticipant");
        }
        else
        {
            Dictionary<string, string> roles = partyProxy.GetPartyRoles();
            string partyName = string.Empty;

            if (party.BusinessName == null || party.BusinessName == string.Empty)
                partyName = string.Concat(party.FirstName, " ", string.Concat(party.MiddleName, " ") ?? string.Empty, party.LastName);
            else
                partyName = party.BusinessName;

            var addParticipantViewModel = new AddParticipantViewModel
            {
                ClaimNumber = claim.ClaimNumber,
                PolicyNumber = claim.PolicyNumber,
                PartyNumber = partyNumber,
                PartyName = partyName,
                TaxID = party.TaxID,
                ValidPartyRoles = roles
            };
            return View("AddClaimParticipant", addParticipantViewModel);
        }
    }

    [HttpPost]
    [AuthorizeByConfig(RolesAppSettingKey = "", UsersAppSettingKey = "ClaimUpdateAuthorizedUsers")]
    public ActionResult AddParticipant(AddParticipantViewModel viewModel)
    {
        if (ModelState.IsValid)
        {
            IClaimManager proxy = CreateClaimManagerProxy();
            string result = proxy.AddParticpant(viewModel.ClaimNumber, viewModel.PartyNumber, viewModel.SelectedPartyRole);
            ViewBag.Result = result;
        }
        return View("AddClaimParticipant");
    }

    private static IIntegrationDashboardManager CreateDashboardManagerProxy()
    {
        ChannelFactory<IIntegrationDashboardManager> _channelFactory;
        _channelFactory = new ChannelFactory<IIntegrationDashboardManager>("*");
        IIntegrationDashboardManager channel = _channelFactory.CreateChannel();
        return channel;
    }

    private static IClaimManager CreateClaimManagerProxy()
    {
        ChannelFactory<IClaimManager> _channelFactory;
        _channelFactory = new ChannelFactory<IClaimManager>("*");
        IClaimManager channel = _channelFactory.CreateChannel();
        return channel;
    }

    private static IPartyAdminManager CreatePartyAdminManagerProxy()
    {
        ChannelFactory<IPartyAdminManager> _channelFactory;
        _channelFactory = new ChannelFactory<IPartyAdminManager>("*");
        IPartyAdminManager channel = _channelFactory.CreateChannel();
        return channel;
    }
}

我已经将代码与我复制的代码进行了比较,并且在视图模型中使用Dictionary之外没有注意到任何不同之处。我还尝试在每个层中注释掉Dictionary并在调试时检查视图模型参数,但是所有内容仍然是null。我想我已经完成了我的MVC知识,所以非常感谢任何帮助。

1 个答案:

答案 0 :(得分:3)

因为您提交的表单中只有一个SELECT元素(对于SelectedPartyRole)。提交表单时,模型绑定器将读取提交表单的请求主体并绑定到您的操作方法参数视图模型属性。

如果要发送更多属性值,则需要将它们保存在表单内的表单输入元素中。如果您不希望用户看到它,您可以将它们保存在隐藏的输入字段中。

Html.HiddenFor辅助方法可用于生成隐藏的输入字段。

@using (Html.BeginForm("AddParticipant","Claim")) 
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    @Html.HiddenFor(s=>s.ClaimNumber)
    @Html.HiddenFor(s=>s.PolicyNumber)
    @Html.HiddenFor(s=>s.PartyNumber)

    @Html.DropDownListFor(m => m.SelectedPartyRole,
                                  new SelectList(Model.ValidPartyRoles, "Key", "Value"),
                                  "")
   <input type="submit" value="Save" />    
}

请记住,来自客户端的任何数据都可能是错误的数据。因此,经验法则是,永远不会信任来自客户端的数据,并始终根据需要对其进行验证。用户可以使用浏览器开发工具简单地更新隐藏的输入字段值,并向您发送错误的数据。所以在做重要事情之前总是在服务器端进行验证。

另一个选择是在表单和httppost操作中有一个唯一的id(此实体的主键),再次从db / any持久性机制获取实体,使用此id并使用它。这比依赖客户端数据更安全。