How to check a single item in a list

I have a model that has this form:

public class GlobalSettingsViewModel { public List<SettingViewModel> Settings{ get;set;} } public class SettingViewModel { public string Name{ get;set;} [Range(0,100)] public decimal SettingValue{ get;set;} } 

My view calls Html.RenderPartial("SettingView") for each SettingViewModel parameter.

 <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<SettingViewModel>" %> <% using (Html.BeginForm("Save", "GlobalSettings", FormMethod.Post)) { %> <table> <tr> <td width="150px"> <%= Html.DisplayFor(m=>m.Name) %> </td> <td> <%= Html.TextBoxFor(m=>m.SettingValue) %> </td> <td> <input type="submit" value="Save" class="uiButton" /> <%=Html.ValidationMessageFor(m=>m.SettingValue) %> </td> </tr> </table> <%} %> 

Each SettingView displays a form that returns to the Save action.

SettingViewModel correctly rehydrated from the form, and validation determines when an out or range value is generated.

I returned the original Index view with the full GlobalSettingsViewModel that it requires.

However, when the page displays each Validator for SettingValue shows this error message instead of the text field with the wrong value?

What is the correct way to do server side validation on PartialView when it is a page of a collection of items?


UPDATE

So, here's what I have .... seems a little strange, but it seems to work.

I can save one setting at a time and show validation errors when they occur. But the strange way that I preserve using the partial model seems a little strange.

index.aspx

 <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/MVC.Master" Inherits="System.Web.Mvc.ViewPage<GlobalSettingsViewModel>" %> <fieldset style="margin: 5px; width: 350px;"> <legend>Global System Settings</legend> <div> <%= Html.EditorFor(m => Model.Settings)%> </div> </fieldset> 

SettingViewModel.ascx

 <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<SettingViewModel>" %> <% using (Html.BeginForm("Save", "GlobalSettings", FormMethod.Post)) { %> <table> <tr> <td width="150px"> <%= Model.Name %> </td> <td> <%= Html.TextBoxFor(m => m.SettingValue) %> </td> <td> <input type="submit" value="Save" class="uiButton" /> </td> </tr> <tr> <td colspan="3"> <%=Html.ValidationMessageFor(m=>m.SettingValue) %> </td> </tr> </table> <%= Html.HiddenFor(m => m.SettingName)%> <%= Html.HiddenFor(m => m.Name)%> <%} %> 

GlobalSettingsController.cs

 public ActionResult Index() { var settings = GetSettings(); if (TempData["Message"] != null) { settings.Message = TempData["Message"].ToString(); settings.HasMessage = true; } return View(settings); } [AuthorizationFilter(true, null)] [HttpPost] public ActionResult Save(GlobalSettingsViewModel model) { if (ModelState.IsValid) { GlobalSettings.SetGlobalSetting(model.Settings[0].SettingName, model.Settings[0].SettingValue); TempData["Message"] = "Saved " + model.Settings[0].Name; return RedirectToAction("Index"); } var settings = GetSettings(); return View("Index", settings); } 
+4
source share
2 answers

One possibility is to use AJAX, so you do not need to refresh the whole page. Thus, your Save action will return a partial transfer of it only to the current setting:

 [HttpPost] public ActionResult Save(SettingViewModel model) { // TODO: do some processing return PartialView("SettingView", model); } 

then wrap the forms in some div container so that we can more easily find out which section will be updated after a successful AJAX call:

 <% foreach (var item in Model.Settings) { %> <div class="setting"> <%= Html.Partial("SettingView", item) %> </div> <% } %> 

and finally AJAXify these forms in a separate javascript file:

 $(function () { $('.setting').delegate('form', 'submit', function() { $.ajax({ url: this.action, type: this.method, data: $(this).serialize(), context: this, success: function (result) { $(this).closest('.setting').html(result); } }); return false; }); }); 
+2
source

Your problem is that RenderPartial generates the same identifier for each SettingsViewModel parameter. If you look at your visualized code, you will see a duplicate identifier on the page and this invalid HTML.

You may need to use the EditorTemplate for SettingsViewModel and this will have the logic needed to create unique identifiers.

+1
source

Source: https://habr.com/ru/post/1386565/


All Articles