为什么我的输入值没有绑定到我的视图模型?

Why are my input values not binding to my viewmodel?

提问人:JavaFox 提问时间:6/7/2023 最后编辑:Md Farid Uddin KironJavaFox 更新时间:6/7/2023 访问量:50

问:

我正在尝试将输入值传递给我的视图模型中的数组。然后遍历这些值并保存每个值中的新更改,但是,每次我提交时,模型值都以 null 形式出现,除了一个值(持续时间)。我尝试更改名称和 ID,但无济于事。

视图

@{
    var SMs = ((List<Stage_Media>)ViewBag.Stage_Media);
}
<div class="col-lg-12">
<div class="card card-alt3">
    <div class="card-header">
        <h3><strong>Show Order</strong></h3>
    </div>
    <div class="card-body">
        <table class="dd table" id="show_list">
            <thead>
                <tr>
                    <th></th>
                    <th>Order</th>
                    <th>Name</th>
                    <th>Path</th>
                    <th>Upload Date</th>
                    <th>Duration (Min:Sec)</th>
                    <th></th>
                </tr>
            </thead>
            @if (SMs.Count() > 0)
            {
                <tbody class="dd-list">
                    @foreach (var sm in SMs.OrderBy(sm => sm.order))
                    {
                        <tr class="dd-item dd3-item" data-id="@sm.media.id" data-duration="@sm.duration">
                            <td class="dd-handle dd3-handle"></td>
                            <td class="dd3-content">@sm.order</td>
                            <td class="dd3-content">@sm.media.name</td>
                            <td class="dd3-content">@sm.media.ext</td>
                            <td class="dd3-content">@sm.media.uploaded</td>
                            <td class="dd3-content">
                                @if (sm.media.ext == "jpg" || sm.media.ext == "png")
                                {
                                    <input name="sm_duration" id="sm.duration" placeholder = "mm:ss"
                                        value = @(sm.duration != null ? TimeSpan.FromTicks((long)@sm.duration).ToString(@"m\:ss", null) : "00:10") />
                                }
                                <input name="sm_start_date" id="sm.start_date" type="date" />
                                <input name="sm_end_date" id="sm.end_date" type="date" />
                                <select name="sm_occurrence">
                                    <option default value=Everyday>Every day</option>
                                    <option value="Bi-Weekly">Bi-Weekly</option>
                                </select>
                            </td>
                            <td style="width: 15%">
                                <div class="row align-items-center align-middle" style="margin: 0; height: 6em; max-height: 6em">
                                    @if (sm.media.ext == "mp4" || sm.media.ext == "mov" || sm.media.ext == "mkv")
                                {
                                    <video id="video" src="/api/[email protected]" style="object-fit: cover; width: 100%; max-width: 100%; max-height: 100%;" autoplay muted playsinline loop></video>
                                }
                                else
                                {
                                    <img id="image" src="/api/[email protected]" style="width: 100%; height:100%; object-fit: contain;">
                                }
                                </div>
                            </td>
                        </tr>
                    }
                </tbody>
            }
            else
            {
                <tbody class="dd-empty">
                    <tr class="dd-placeholder">
                        <td></td>
                        <td></td>
                        <td></td>
                        <td></td>
                        <td></td>
                    </tr>
                </tbody>
            }
        </table>
    </div>
</div>
</div>
<div class="form-group row">
    <div class="col-3">
        <button type="button" name="Save" onclick="return saveStage(@ViewBag.Branch_id, 
             @ViewBag.Stage.id);" class="btn btn-alt1">Save Stage</button>
        <button type="button" name="Delete" onclick="return deleteStage(@ViewBag.Stage.id);" 
            class="btn btn-alt1">Delete Stage</button>
    <a name="View" href="/home/[email protected]" class="btn btn-alt1">View</a>
</div>

视图模型

public class SaveStage_ViewModel
{
    public int stage_id { get; set; }
    public string name { get; set; }
    public File[] ids { get; set; }

    public class File
    {
        public int id { get; set; }
        [DataType(DataType.Time)]
        [DisplayFormat(DataFormatString = "{mm\\:ss}")]
        [Display(Name = "Duration")]
        public string duration { get; set; }
        [Display(Name = "Start Date")]
        public DateTime? start_date { get; set; }
        [Display(Name = "End Date")]
        public DateTime? end_date { get; set; }
        [Display(Name = "Occurence")]
        public string occurrence { get; set; }
    }
}

public class Stage_Media
{
    [Key]
    public int id { get; set; }
    public int stage_id { get; set; }
    [ForeignKey("stage_id")]
    public Stage stage { get; set; }
    public int media_id { get; set; }
    public long? duration { get; set; }
    [ForeignKey("media_id")]
    public Media media { get; set; }
    public int order { get; set; }
    public DateTime? start_date { get; set; }
    public DateTime? end_date { get; set; }
    public string occurrence { get; set; }
}

控制器

    [HttpPost]
    public string SaveStage(SaveStage_ViewModel model)
    {
        using (var c = new Context())
        {
            var stage = c.Stage.Find(model.stage_id);
            stage.name = model.name;
            stage.modified = DateTime.Now;
            stage.modified_by = User.Identity.Name;

            var sml = new List<Stage_Media>();
            for (var i = 0; i < model.ids.Count(); i++)
            {
                var sm = new Stage_Media();
                sm.stage_id = model.stage_id;
                sm.media_id = model.ids[i].id;
                sm.start_date = model.ids[i].start_date;
                sm.end_date = model.ids[i].start_date;
                sm.occurrence = model.ids[i].occurrence;
                sm.order = i + 1;
                sm.duration = !string.IsNullOrWhiteSpace(model.ids[i].duration) ? (long?)TimeSpan.ParseExact(model.ids[i].duration, @"m\:ss", null).Ticks : null;

                sml.Add(sm);
            }

            c.Stage.Update(stage);
            c.Stage_Media.RemoveRange(c.Stage_Media.Where(smr => smr.stage_id == model.stage_id));
            c.Stage_Media.AddRange(sml);
            c.SaveChanges();
        }

        return $"Stage Save Successful";
    }
C# ASP.NET-CORE .NET-2.0

评论

0赞 David Tansey 6/7/2023
你把你的观点叫到哪里?你把你的财产放在哪里?ViewBag.*
0赞 Md Farid Uddin Kiron 6/26/2023
您好,您是否尝试过提供的解决方案?您能够解决问题吗?我还有什么可以帮你的吗?

答:

2赞 Md Farid Uddin Kiron 6/7/2023 #1

每次提交时,模型值都以 null 形式出现,但有一个除外 value(持续时间)。我尝试更改名称和 ID,但无济于事。

实际上,如果您共享了设置值的页面初始化代码片段,那会更方便,这是提交时空值的原因之一。@ViewBag.Branch_id

我试图模拟您的问题并按预期工作。以下是我如何测试该场景的示例供您参考。

演示模型:

public class SaveStage_ViewModel
    {
        public int stage_id { get; set; }
        public int Id { get; set; }

    }

    public class Stage_Media
    {
        public int Branch_id { get; set; }
        public int stage_id { get; set; }

    }

控制器:

public class NullViewModelController : Controller
    {
        public IActionResult Index()
        {
            Stage_Media stage_Media = new Stage_Media();
            stage_Media.Branch_id = 101;    
            stage_Media.stage_id = 404;
            ViewBag.Stage_Media = stage_Media;
            return View();
        }

        [HttpPost]
        public string SaveStage(SaveStage_ViewModel model)
        {
            return $"Stage Id:{model.stage_id} and branch Id : {model.Id} has been Saved Successfully";
        }
    }

注意:我在加载索引视图时在ViewBag.Stage_Media上分配了演示值。

视图:

@{
    var SMs = (Stage_Media)ViewBag.Stage_Media);
}

    <div class="form-group row">
        <div class="col-3">
            <button type="button" name="Save" onclick="return saveStage(@SMs.Branch_id,
                 @SMs.stage_id);" class="btn btn-success">
                Save Stage
            </button>
        </div>
    </div>
    <strong><span id="appendHere"></span></strong></>
    <script language="javascript" type="text/javascript">
        function saveStage(branchId, stageId) {
    
            var valueFromViewModel = {
                stage_id: stageId,
                Id: branchId
            }
    
            var requestUrl = '@Url.Action("SaveStage", "YourControllerName")';
    
            $.ajax({
                type: "POST",
                url: requestUrl,
                data: { model: valueFromViewModel },
                success: function (data) {
                    console.log(data);
                    $("#appendHere").html(data);
                },
                error: function (xhr, status, error) {
                    alert('Data was not sent to backend!');
                }
            });
    
        }
    </script>

注意:您可以使用以下方式传递值,或者两者都会相应地工作。我使用了单一模型,但您可以使用 List 并传递所需的索引值。saveStage(@SMs.Branch_id, @SMs.stage_id);saveStage(@ViewBag.Stage_Media.Branch_id, @@ViewBag.Stage_Media.stage_id);

输出:

enter image description here

enter image description here

enter image description here

采取方式:如果分配正确,请首先检查您的数据。最重要的是,仔细检查您的函数是否已按预期传递该值。您可以使用浏览器网络跟踪和控制台。您可以参考此官方链接获取调试帮助。此外,您可以查看此官方示例。@ViewbagsaveStage

评论

0赞 JavaFox 6/7/2023
很好,这是我试图添加一些功能的另一个开发人员工作。看完你的示例后,我回去找到了你提到的代码snipet,现在一切正常!
0赞 Md Farid Uddin Kiron 6/9/2023
感谢您的回复,我很高兴解决了您的问题。您还有什么需要帮助的吗?