You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在MVC中使用AJAX保存动态数据集(Razor动态生成控件场景)

Solution for Saving Dynamic DevExpress Controls via AJAX in MVC

Here's a practical, step-by-step implementation to handle saving your dynamically generated checkboxes (or any dynamic controls) using AJAX in an MVC Razor view:


1. Define a ViewModel for Clean Binding

First, create a viewmodel structure that mirrors the selection state of your document types. This makes server-side model binding seamless:

public class DocumentTypeSelection
{
    public int DocTypeId { get; set; }
    public bool IsChecked { get; set; }
}

// Main viewmodel to hold the collection of selections
public class DocumentTypesViewModel
{
    public List<DocumentTypeSelection> SelectedTypes { get; set; } = new List<DocumentTypeSelection>();
}

2. Update the Razor View to Bind Controls to the ViewModel

Modify your dynamic control generation to link each checkbox to the viewmodel collection. This ensures DevExpress generates the correct input names for automatic model binding:

@model DocumentTypesViewModel

@{
    var docTypes = MyProject.GetDocumentTypes();
    // Initialize the viewmodel collection if empty (for first load)
    if (Model.SelectedTypes.Count == 0)
    {
        foreach (var docType in docTypes)
        {
            Model.SelectedTypes.Add(new DocumentTypeSelection { DocTypeId = docType.Id });
        }
    }
}

@Html.DevExpress().FormLayout(settings => {
    settings.Name = "DocumentTypeForm";
    settings.Width = Unit.Percentage(100);

    var groupItem = settings.Items.AddGroupItem(g => {
        g.Caption = "Document Types";
    });

    for (int i = 0; i < docTypes.Count; i++)
    {
        var docType = docTypes[i];
        groupItem.Items.Add(m => m.SelectedTypes[i].IsChecked, item => {
            item.Name = $"checkDoc{docType.Id}";
            item.NestedExtensionType = FormLayoutNestedExtensionItemType.CheckBox;
            // Set checkbox label to the document type name
            ((CheckBoxSettings)item.NestedExtensionSettings).Text = docType.Name;
            // Add hidden field to track the DocTypeId for each selection
            item.NestedExtensionSettings.PreRender = (s, e) => {
                Html.DevExpress().HiddenField(hfSettings => {
                    hfSettings.Name = $"SelectedTypes[{i}].DocTypeId";
                    hfSettings.Value = docType.Id;
                }).Render();
            };
        });
    }
}).GetHtml()

<!-- Save button to trigger AJAX -->
@Html.DevExpress().Button(settings => {
    settings.Name = "SaveButton";
    settings.Text = "Save Selections";
    settings.ClientSideEvents.Click = "onSaveClick";
}).GetHtml()

3. Client-Side AJAX Logic

Write JavaScript to collect form data, serialize it, and send it to the controller. We'll use jQuery's built-in serialization for simplicity:

function onSaveClick(s, e) {
    // Serialize all form fields into a format the server can parse
    var formData = $("#DocumentTypeForm").serializeArray();
    
    // Send AJAX request to the controller
    $.ajax({
        url: '@Url.Action("SaveDocumentTypes", "YourController")',
        type: 'POST',
        data: formData,
        success: function(response) {
            if (response.success) {
                alert("Selections saved successfully!");
                // Optional: Refresh UI or show confirmation message
            } else {
                alert("Error saving: " + response.message);
            }
        },
        error: function(xhr, status, error) {
            alert("An unexpected error occurred: " + error);
        }
    });
}

4. Server-Side Controller Action

Create a controller action to accept the viewmodel, validate it, and persist the data to your database:

public class YourController : Controller
{
    [HttpPost]
    public JsonResult SaveDocumentTypes(DocumentTypesViewModel model)
    {
        try
        {
            if (!ModelState.IsValid)
            {
                return Json(new { success = false, message = "Invalid input detected." });
            }

            // Save logic: Update your database based on the selection state
            foreach (var selection in model.SelectedTypes)
            {
                // Example: Toggle active status for the document type
                // YourDbContext.DocumentTypes
                //     .Where(dt => dt.Id == selection.DocTypeId)
                //     .FirstOrDefault()
                //     .IsActive = selection.IsChecked;
            }
            // YourDbContext.SaveChanges();

            return Json(new { success = true, message = "Saved successfully." });
        }
        catch (Exception ex)
        {
            // Log the exception here for debugging
            return Json(new { success = false, message = ex.Message });
        }
    }
}

Key Takeaways

  • Model Binding: The SelectedTypes[{i}].DocTypeId and SelectedTypes[{i}].IsChecked naming convention is critical for ASP.NET MVC to correctly map form fields to your viewmodel.
  • DevExpress Specifics: The PreRender event adds hidden fields to track each document type's ID, ensuring you know which checkbox corresponds to which record.
  • Validation: Add data annotations to your viewmodel properties (e.g., [Required]) and extend the client-side code to validate before sending the request.
  • Error Handling: The AJAX handlers provide clear feedback to users, while server-side try/catch blocks handle unexpected issues gracefully.

内容的提问来源于stack exchange,提问作者Bcpouli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:39:22