为什么在这里绑定到ViewModel不起作用?

huangapple go评论61阅读模式
英文:

Why is binding to a ViewModel Not Working here?

问题

我有一个ViewModel,包含两个模型 - UserSystemPermissionsSystemModel。我想从视图中传递两个数据,并将其绑定到上述的ViewModel。

//UserSystemPermissionsViewModel
using NuGet.ProjectModel;
using SPLWeb.Models;
using SPLWeb.ViewModels;
using SPLWeb.Models.DB;

namespace SPLWeb.ViewModels
{
    public class UserSystemPermissionsViewModel
    {
        public UserSystemPermission? UserSystemPermission { get; set; }
        public SystemModel? SystemModel { get; set; }

    }
}

两个模型:

// SystemModel
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace SPLWeb.Models.DB
{
    public partial class SystemModel
    {
        [Key]
        public int SystemId { get; set; }
        public string? SystemName { get; set; }
        public string? Description { get; set; }
        public bool DisabledBit { get; set; }
        public string? ChangedBy { get; set; }
        public DateTime? ChangedDate { get; set; }
        public virtual ICollection<FacilitySystem> FacilitySystems { get; set; } = new List<FacilitySystem>();
        public virtual ICollection<SystemJob> SystemJobs { get; set; } = new List<SystemJob>();
        public virtual ICollection<SystemUser>? SystemUsers { get; set; }
        public virtual ICollection<SystemPermission> SystemPermissions { get; set; } = new List<SystemPermission>();
    }
}

// UserSystemPermission
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace SPLWeb.Models.DB
{
    public partial class UserSystemPermission
    {
        [Key]
        public int UserSystemPermissionId { get; set; }
        public int? UserId { get; set; }
        public int? SystemPermissionId { get; set; }
        public string? Notes { get; set; }
        public bool Active { get; set; }
        public string? AddedByUser { get; set; }
        public string? DeactivatedBy { get; set; }
        public string? ReactivatedBy { get; set; }
        public DateTime? LastModifiedDate { get; set; }
        public virtual SystemPermission? SystemPermission { get; set; }
        public virtual User? User { get; set; }
    }
}

传递数据的视图:

@model SPLWeb.ViewModels.UserSystemPermissionsViewModel

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>UserSystemPermission</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="PresentSystemPermissionSelect">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            
            <div class="form-group">
                <label for="UserSystemPermission.UserId" class="control-label"></label>
                <select for="UserSystemPermission.UserId" class ="form-control" required="required" asp-items="ViewBag.UserList"></select>
            </div>
            <div class="form-group">
                <label for="SystemModel.SystemId" class="control-label"></label>
                <select for="SystemModel.SystemId" class ="form-control" required="required" asp-items="ViewBag.SystemList"></select>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

最后,在控制器中尝试传递数据:

public async Task<IActionResult> PresentSystemPermissionSelect([Bind("UserSystemPermission.UserId", "SystemModel.SystemId")] UserSystemPermissionsViewModel userSystemPermissionsViewModel)
{
    // 传递选定系统的权限列表到下一个屏幕,允许用户选择权限

    var userSystemPermissionContext = _context.UserSystemPermissions
       .Include(u => u.SystemPermission)
       .Include(u => u.SystemPermission.SystemModel)
       .Include(u => u.User);

    // 获取所选系统的权限列表
    var systemPermisionList = (from s in _context.SystemPermissions
                               orderby s.Description
                               where s.SystemId == userSystemPermissionsViewModel.SystemModel.SystemId
                               select s).ToList();

    ViewData["UserList"] = new SelectList(_context.Users.OrderBy(s => s.NameLast).OrderBy(s => s.NameFirst), "UserId", "FullName", userSystemPermissionsViewModel.UserSystemPermission.UserId);
    ViewData["SystemList"] = new SelectList(_context.SystemModels.OrderBy(e => e.SystemName), "SystemId", "SystemName", userSystemPermissionsViewModel.SystemModel.SystemId);
    ViewData["SystemPermissionList"] = new SelectList(_context.SystemPermissions.OrderBy(e => e.Description), "SystemPermissionId", "Description");
    return View("SystemPermissionSelect", systemPermisionList);
}
英文:

I have a ViewModel with two Models - UserSystemPermissions and SystemModel
I want to pass two pieces of data from a view and bind it to the afforementioned ViewModel.

UserSystemPermissions.SystemID
SystemModel.SystemID

I can see the data coming over with Edge Network Tools in a browser window but the data is not binding to the ViewModel.

Here is the ViewModel, two models, controller, and view in question.

//UserSystemPermissionsViewModel
using NuGet.ProjectModel;
using SPLWeb.Models;
using SPLWeb.ViewModels;
using SPLWeb.Models.DB;

namespace SPLWeb.ViewModels
{
    public class UserSystemPermissionsViewModel
    {
        public UserSystemPermission? UserSystemPermission { get; set; }
        public SystemModel? SystemModel { get; set; }

    }
}

...and the two models

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace SPLWeb.Models.DB;

public partial class SystemModel
{
    [Key]
    public int SystemId { get; set; }
    public string? SystemName { get; set; }
    public string? Description { get; set; }
    public bool DisabledBit { get; set; }
    public string? ChangedBy { get; set; }
    public DateTime? ChangedDate { get; set; }
    public virtual ICollection&lt;FacilitySystem&gt; FacilitySystems { get; set; } = new List&lt;FacilitySystem&gt;();

    //public virtual ICollection&lt;JobSystemPermission&gt; JobSystemPermissions { get; set; } = new List&lt;JobSystemPermission&gt;();

    public virtual ICollection&lt;SystemJob&gt; SystemJobs { get; set; } = new List&lt;SystemJob&gt;();
    //public virtual ICollection&lt;User&gt; Users { get; set; } = new List&lt;User&gt;();
    public virtual ICollection&lt;SystemUser&gt;? SystemUsers { get; set; }
    //public virtual UserSystemPermission UserSystemPermission { get; set; }

    public virtual ICollection&lt;SystemPermission&gt; SystemPermissions { get; set; } = new List&lt;SystemPermission&gt;();
    //public virtual ICollection&lt;UserSystemPermission&gt; UserSystemPermissions { get; set; } = new List&lt;UserSystemPermission&gt;();
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace SPLWeb.Models.DB;

public partial class UserSystemPermission
{
    [Key]
    public int UserSystemPermissionId { get; set; }
    public int? UserId { get; set; }
    public int? SystemPermissionId { get; set; }
    public string? Notes { get; set; }
    public bool Active { get; set; }
    public string? AddedByUser { get; set; }
    public string? DeactivatedBy { get; set; }
    public string? ReactivatedBy { get; set; }
    public DateTime? LastModifiedDate { get; set; }
    public virtual SystemPermission? SystemPermission { get; set; }
    public virtual User? User { get; set; }
   // public virtual SystemModel? SystemModel { get; set; }
    //public virtual SystemUser? SystemUser { get; set; } 
}

View that is passing the data

@model SPLWeb.ViewModels.UserSystemPermissionsViewModel

@{
    ViewData[&quot;Title&quot;] = &quot;Create&quot;;
}

&lt;h1&gt;Create&lt;/h1&gt;

&lt;h4&gt;UserSystemPermission&lt;/h4&gt;
&lt;hr /&gt;
&lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-md-4&quot;&gt;
        &lt;form asp-action=&quot;PresentSystemPermissionSelect&quot; &gt;
            &lt;div asp-validation-summary=&quot;ModelOnly&quot; class=&quot;text-danger&quot;&gt;&lt;/div&gt;
            
            &lt;div class=&quot;form-group&quot;&gt;
                &lt;label for=&quot;UserSystemPermission.UserId&quot; class=&quot;control-label&quot;&gt;&lt;/label&gt;
                &lt;select for=&quot;UserSystemPermission.UserId&quot; class =&quot;form-control&quot; required=&quot;required&quot; asp-items=&quot;ViewBag.UserList&quot;&gt;&lt;/select&gt;
                @*&lt;input asp-for=&quot;User.FullName&quot; disabled class=&quot;form-control&quot; /&gt;*@
            &lt;/div&gt;
            &lt;div class=&quot;form-group&quot;&gt;
                &lt;label for=&quot;SystemModel.SystemId&quot; class=&quot;control-label&quot;&gt;&lt;/label&gt;
                &lt;select for=&quot;SystemModel.SystemId&quot; class =&quot;form-control&quot; required=&quot;required&quot; asp-items=&quot;ViewBag.SystemList&quot;&gt;&lt;/select&gt;
            &lt;/div&gt;
            &lt;div class=&quot;form-group&quot;&gt;
                &lt;input type=&quot;submit&quot; value=&quot;Create&quot; class=&quot;btn btn-primary&quot; /&gt;
            &lt;/div&gt;
        &lt;/form&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div&gt;
    &lt;a asp-action=&quot;Index&quot;&gt;Back to List&lt;/a&gt;
&lt;/div&gt;

@section Scripts {
    @{await Html.RenderPartialAsync(&quot;_ValidationScriptsPartial&quot;);}
}

And, finally, the controll task that I am passing the data too (or trying to 为什么在这里绑定到ViewModel不起作用?

public async Task&lt;IActionResult&gt; PresentSystemPermissionSelect([Bind(&quot;UserSystemPermission.UserId&quot;, &quot;SystemModel.SystemId&quot;)] UserSystemPermissionsViewModel userSystemPermissionsViewModel)
{
    // pass a list of permissions for the selected systems to the next screen which will allow
    //    the user to select a permission

    var userSystemPermissionContext = _context.UserSystemPermissions
       .Include(u =&gt; u.SystemPermission)
       .Include(u =&gt; u.SystemPermission.SystemModel)
       .Include(u =&gt; u.User);

   
    // Get a list of permissions for the chosen system
    var systemPermisionList = (from s in _context.SystemPermissions
                               orderby s.Description
                               where s.SystemId == userSystemPermissionsViewModel.SystemModel.SystemId
                               select s).ToList();

    ViewData[&quot;UserList&quot;] = new SelectList(_context.Users.OrderBy(s =&gt; s.NameLast).OrderBy(s =&gt; s.NameFirst), &quot;UserId&quot;, &quot;FullName&quot;, userSystemPermissionsViewModel.UserSystemPermission.UserId);
    ViewData[&quot;SystemList&quot;] = new SelectList(_context.SystemModels.OrderBy(e =&gt; e.SystemName), &quot;SystemId&quot;, &quot;SystemName&quot;, userSystemPermissionsViewModel.SystemModel.SystemId);
    ViewData[&quot;SystemPermissionList&quot;] = new SelectList(_context.SystemPermissions.OrderBy(e =&gt; e.Description), &quot;SystemPermissionId&quot;, &quot;Description&quot;);
    return View(&quot;SystemPermissionSelect&quot;, systemPermisionList);
}

I have tried "newing up" the ViewModel before using it, in which case, I have a ViewModel with two models but no data. If I don't create a ViewModel first I simply have two NULL models inside the ViewModel after the binding in the ActionResult header.

I have scoured the Internet - including SO and cannot seem to get this working.

I considered not using the ASP tag helpers and just passing in two pieces of data to the controller but I prefer to manage the lists with &lt;select asp-for ...&gt; tag because I've had much better results than just @Html.DropDown...

As mentioned earlier, I can see the data coming across the network in Edge Network Tools but the data is simply not binding.

答案1

得分: 1

如果您想将两个数据传递给控制器并使用<select asp-for ...>标记,

尝试删除[Bind("UserSystemPermission.UserId", "SystemModel.SystemId")]并按以下方式进行一些更改:

[HttpPost]
public async Task<IActionResult> PresentSystemPermissionSelect(int? UserId, int? SystemId)
{
    ...//进行您的操作
    return View();
}

在Create.cshtml中,使用name属性进行绑定:

<select name="UserId" class="form-control" required="required" asp-items="ViewBag.UserList"></select>
<select name="SystemId" class="form-control" required="required" asp-items="ViewBag.SystemList"></select>

结果:
为什么在这里绑定到ViewModel不起作用?

英文:

> I considered not using the ASP tag helpers and just passing in two
> pieces of data to the controller but I prefer to manage the lists with
> <select asp-for ...> tag

If you want to pass two pieces of data to the controller and with &lt;select asp-for ...&gt; tag

Try to remove [Bind(&quot;UserSystemPermission.UserId&quot;, &quot;SystemModel.SystemId&quot;)] and make some change as below :

       [HttpPost]
        public async Task&lt;IActionResult&gt; PresentSystemPermissionSelect(int? UserId, int? SystemId)
        {
             ...//do your staff
            return View();
        }

In Create.cshtml , use name attribute to bind:

&lt;select name=&quot;UserId&quot; class=&quot;form-control&quot; required=&quot;required&quot; asp-items=&quot;ViewBag.UserList&quot;&gt;&lt;/select&gt;
 &lt;select name=&quot;SystemId&quot; class=&quot;form-control&quot; required=&quot;required&quot; asp-items=&quot;ViewBag.SystemList&quot;&gt;&lt;/select&gt;

result:
为什么在这里绑定到ViewModel不起作用?

huangapple
  • 本文由 发表于 2023年6月8日 05:52:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76427326.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定