【问题标题】:Fail to call Update action method on Kendo Grid in ASP MVC无法在 ASP MVC 中调用 Kendo Grid 上的更新操作方法
【发布时间】:2016-09-01 15:46:03
【问题描述】:

我有两个网格,其中第二个网格根据在第一个网格上选择的行显示详细数据。第二个网格允许内联编辑,并且在允许上传多个文件的列之一中具有上传控件。我添加了一些自定义代码 (based on Damien article),以便在编辑模式期间在上传小部件中显示预上传的文件。问题是如果该行有预先上传的文件并且如果该行被修改(例如删除以前上传的文件或上传的新文件),并且单击“更新”命令按钮,更新操作方法不会被触发。但是,如果该行没有预先上传的文件并且进行了任何编辑,例如上传新文件并单击“更新”命令按钮,更新操作方法被触发。 谁能告诉我为什么更新操作方法没有被触发并且我的代码出现 500 错误?

Here is the project code to download

任何建议将不胜感激。

谢谢。

这是我的代码:

CertificationViewModel.cs:

public class Certification
{
    public string SupplierNumber      { get; set; }
    public string CustomerItemNumber  { get; set; }
}

public class CertificationDetail
{
    public string CertificationName                { get; set; }
    public bool Value                              { get; set; }
    public List<UploadInitialFile> Attachments     { get; set; }

    public CertificationDetail()
    {
        Attachments = new List<UploadInitialFile>();
    }
}

public class UploadInitialFile
{
    public UploadInitialFile(string fileName, int contentLength, string fileExtension)
    {
        Name = fileName;
        Size = contentLength;
        Extension = fileExtension;
    }

    public string Name      { get; set; }
    public int Size         { get; set; }
    public string Extension { get; set; }
}

HomeController.cs

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Message = "Welcome to ASP.NET MVC!";

        return View();
    }
    public JsonResult GetTestData([DataSourceRequest] DataSourceRequest request)
    {
        var certificationList = new List<Certification>();
        certificationList.Add(new Certification {SupplierNumber = "4343", CustomerItemNumber = "123344"});
        certificationList.Add(new Certification {SupplierNumber = "4242", CustomerItemNumber = "23453"});
        return Json(certificationList.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
    }

    public JsonResult GetDetailTestData([DataSourceRequest] DataSourceRequest request, Certification model)
    {
        var certificationDetailLists = new List<CertificationDetail>();

        if (model.SupplierNumber == "4343")
        {
            certificationDetailLists.Add(new CertificationDetail {CertificationName = "ROHS", Value = true, Attachments = GetAttachments()});
            certificationDetailLists.Add(new CertificationDetail {CertificationName = "REACH", Value = false});
        }
        else
        {
            certificationDetailLists.Add(new CertificationDetail { CertificationName = "RLIM", Value = false });
            certificationDetailLists.Add(new CertificationDetail { CertificationName = "RETIM", Value = true });
        }
        return Json(certificationDetailLists.ToDataSourceResult(request));
    }

    public List<UploadInitialFile> GetAttachments()
    {
        return (List<UploadInitialFile>) Session["Upload"];
    }

    public ActionResult SaveAttachments(IEnumerable<HttpPostedFileBase> files)
    {
        if (files != null)
        {
            foreach (var file in files)
            {
                // Some browsers send file names with full path.
                // We are only interested in the file name.
                var fileName = Path.GetFileName(file.FileName);
                var physicalPath = Path.Combine(Server.MapPath("~/App_Data"), fileName);
                var fileExtension = Path.GetExtension(file.FileName);

                SaveUploadedFileInSession(new UploadInitialFile(fileName, file.ContentLength, fileExtension));

                // The files are not actually saved in this demo
                file.SaveAs(physicalPath);
            }
        }

        // Return an empty string to signify success
        return Content("");
    }

    public ActionResult RemoveAttachments(string[] fileNames)
    {
        if (fileNames != null)
        {
            foreach (var fullName in fileNames)
            {
                var fileName = Path.GetFileName(fullName);
                var physicalPath = Path.Combine(Server.MapPath("~/App_Data"), fileName);

                RemoveUploadedFileInSession(fileName);

                if (System.IO.File.Exists(physicalPath))
                {
                    // The files are not actually removed in this demo
                    System.IO.File.Delete(physicalPath);
                }
            }
        }

        // Return an empty string to signify success
        return Content("");
    }

    public void SaveUploadedFileInSession(UploadInitialFile uploadInitialFile)
    {
        List<UploadInitialFile> files;
        if (Session["Upload"] != null)
        {
            files = (List<UploadInitialFile>) Session["Upload"];
        }
        else
        {
            files = new List<UploadInitialFile>();
        }
        files.Add(uploadInitialFile);
        Session["Upload"] = files;
    }

    public void RemoveUploadedFileInSession(string fileName)
    {
        if (Session["Upload"] != null)
        {
            var files = (List<UploadInitialFile>)Session["Upload"];
            var updatedFiles = new List<UploadInitialFile>();

            foreach (var file in files)
            {
                if (file.Name != fileName)
                {
                    updatedFiles.Add(file);
                }
            }

            if (updatedFiles.Count > 0)
            {
                Session["Upload"] = updatedFiles;
            }
        }
    }

    [HttpPost]
    public JsonResult SaveCertificationDetail([DataSourceRequest] DataSourceRequest request, CertificationDetail model)
    {
        if (Session["Upload"] != null)
        {
            model.Attachments = (List<UploadInitialFile>) Session["Upload"];
        }

        return Json(new[] { model }.ToDataSourceResult(request, ModelState));
    }
}

Index.cshtml

<input id="btnSearch" type="button" value="Search" class="btn btn-default icon-btn-input" />

<div class="col-sm-12">
    @(Html.Kendo().Grid<KendoUIApp3.Models.Certification>()
          .Name("Grid1")
          .Columns(columns =>
          {
              columns.Bound(e => e.SupplierNumber).Width("170px");
              columns.Bound(e => e.CustomerItemNumber).Width("170px");
          })
          .Editable(editable => editable.Mode(GridEditMode.InLine))
          .Pageable(x => x.PageSizes(new object[] { 10, 20, 50, 100, "All" }))
          .Reorderable(reorder => reorder.Columns(true))
          .AutoBind(false)
          .Selectable()
          .Sortable(sortable => sortable
              .AllowUnsort(true)
              .SortMode(GridSortMode.MultipleColumn))
          .Scrollable(scr => scr.Height(322))
          .Filterable(filterable => filterable
              .Extra(false)
              .Operators(operators => operators
                  .ForString(str => str.Clear()
                      .Contains("Contains")
                      .StartsWith("Starts with")
                      .IsEqualTo("Is equal to")
                      .IsNotEqualTo("Is not equal to"))))
          .Resizable(resize => resize.Columns(true))
          .DataSource(dataSource => dataSource
              .Ajax()
              .PageSize(10)
              .ServerOperation(false)
              .Read(read => read.Action("GetTestData", "Home"))
              .Model(model =>
              {
                  model.Id(p => p.SupplierNumber);
              }))
              .Events(events => events.Change("onRowSelect"))
    )
</div>
<br /><br />


<div class="col-sm-12">
    @(Html.Kendo().Grid<KendoUIApp3.Models.CertificationDetail>()
          .Name("Grid2")
          .Columns(columns =>
          {
              columns.Command(command =>
              {
                  command.Edit().Text("Edit").HtmlAttributes(new { title = "Edit" });
              }).Width(180).Title("Action");
              columns.Bound(e => e.CertificationName).Width("170px");
              columns.Bound(e => e.Value).ClientTemplate("<input type='checkbox' disabled #=Value == true ? checked='checked' : '' # />").Width("170px");
              columns.Bound(e => e.Attachments).Width("300px").ClientTemplate("#= getAttachments(Attachments)#").EditorTemplateName("_UploadAttachment");
          })
          .Editable(editable => editable.Mode(GridEditMode.InLine))
          .Pageable(x => x.PageSizes(new object[] { 10, 20, 50, 100, "All" }))
          .Reorderable(reorder => reorder.Columns(true))
          .AutoBind(false)
          .Selectable()
          .Sortable(sortable => sortable
              .AllowUnsort(true)
              .SortMode(GridSortMode.MultipleColumn))
          .Scrollable(scr => scr.Height(322))
          .Filterable(filterable => filterable
              .Extra(false)
              .Operators(operators => operators
                  .ForString(str => str.Clear()
                      .Contains("Contains")
                      .StartsWith("Starts with")
                      .IsEqualTo("Is equal to")
                      .IsNotEqualTo("Is not equal to"))))
          .Resizable(resize => resize.Columns(true))
          .DataSource(dataSource => dataSource
              .Ajax()
              .PageSize(10)
              .ServerOperation(false)
              .Read(read => read.Action("GetDetailTestData", "Home").Data("selectedRow"))
              .Model(model =>
              {
                  model.Id(p => p.CertificationName);
                  model.Field(p => p.CertificationName).Editable(false);
              })
              .Update(update => update.Action("SaveCertificationDetail", "Home")))
              .Events(e => e.Edit("onEdit"))
    )
</div>

<script>
    $('#btnSearch').click(function(e) {
        $('#Grid1').data('kendoGrid').dataSource.read();
    });

    function selectedRow() {
        var grid = $("#Grid1").data("kendoGrid");
        var selectedItem = grid.dataItem(grid.select());
        var data = selectedItem ? selectedItem.toJSON() : {};

        return { model: data }
    }

    function onRowSelect() {
        $('#Grid2').data('kendoGrid').dataSource.read();
    }

    function getAttachments(attachments) {
        var links = "";
        if (attachments!= null) {
            for (var i = 0; i < attachments.length; i++) {
                links += "<a href=" + attachments[i].Name + " target='_blank' class='btn-success'>View Attachment</a><br/>";
            }
        }
        return links;
    }

    function onUploadSuccess(e) {
        if (e.response !== 'error') {
            var grid = $('#Grid2').data('kendoGrid');

            var item = grid.dataItem(this.element.closest("tr"));
            item.dirty = true;
        }
    }

    function onEdit(e) {
        $('.k-upload-empty').removeClass('k-upload-empty'); //need to do this to get border back in upload widget

        //add existing files in the upload widget
        if (e.model != null && e.model.Attachments != null) {
            var uniqueDataId = 1;
            var htmlCode ='';
            htmlCode += '<ul id="existing-files" class="k-upload-files k-reset">';

            for (var i = 0; i < e.model.Attachments.length; i++) {
                uniqueDataId++;
                var fileName = e.model.Attachments[i].Name;
                htmlCode +=
                    '<li class="k-file k-file-success" data-att-id="' +fileName + '">\
                    <span class="k-icon k-i-rtf">uploaded</span>\
                    <span class="k-filename" title="'+fileName +'">'+fileName +'</span>\
                    <strong class="k-upload-status">\
                    <span class="k-upload-pct"></span>\
                    </strong>\
                    <button type="button" class="k-button k-button-bare k-upload-action">\
                    <span class="k-icon k-i-close k-delete" title="Remove"></span>\
                    </button>\
                </li>';
            }
            htmlCode += '</ul>';

            var $files, item, _fn, _i, _len;
            if (htmlCode.length > 0) {
                $(".k-upload").append(htmlCode);
                $files = $(".k-file");
                _fn = function (item) {
                    var $item, fileId, filenames;
                    $item = $(item);
                    fileId = $item.data("att-id");
                    filenames = [
                      {
                          name: fileId
                      }
                    ];
                    return $item.data("fileNames", filenames);
                };
                for (_i = 0, _len = $files.length; _i < _len; _i++) {
                    item = $files[_i];
                    _fn(item);
                }
            }
        }
    }
</script>

_UploadAttachment.cshtml

@using Kendo.Mvc.UI

@(Html.Kendo().Upload()
        .Name("files")
        .Async(a => a
            .Save("SaveAttachments", "Home")
            .Remove("RemoveAttachments", "Home")
            .AutoUpload(true)
        )
        .Events(e => e.Success("onUploadSuccess"))
)

【问题讨论】:

    标签: c# jquery asp.net-mvc kendo-ui kendo-grid


    【解决方案1】:

    错误是没有为此对象定义无参数构造函数。

    这就是我没有被叫到的原因。

    您需要为 UploadInitialFile 添加一个无参数构造函数

    应该是:

    public class UploadInitialFile
        {
            public UploadInitialFile(){
    
            }
    
            public UploadInitialFile(string fileName, int contentLength, string fileExtension)
            {
                Name = fileName;
                Size = contentLength;
                Extension = fileExtension;
            }
    
            public string Name      { get; set; }
            public int Size         { get; set; }
            public string Extension { get; set; }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-09
      • 1970-01-01
      • 2012-10-08
      • 1970-01-01
      • 2017-11-21
      • 1970-01-01
      • 1970-01-01
      • 2016-12-25
      相关资源
      最近更新 更多