当用户确认模型信息时,如何回发我的模型?

时间:2016-12-12 10:30:10

标签: c# asp.net-mvc excel razor

我们正在尝试为我们的网站创建Excel导入功能,我们提供一些用户可以填写的模板,然后我们过滤掉这些信息并最终将其发布到我们的数据库中。

首先,他们下载模板,填写然后将其上传到页面。然后我们转到控制器并在我们的模型中填写信息(这是有效的),然后我们将它作为格式化表格打印在页面上。然后当他们确认我们显示的表格与他们的Excel文档匹配时,他们点击" ConfirmCustomOrder" - 按钮。

问题: 我们如何从我们在控制器中发布的模型中获取信息?我们希望使用Model.CustomOrderList,就像在模型中一样,以便稍后验证信息并将其发布到我们的数据库中并完成导入。但是当我们按下" ConfirmCustomOrder" - 按钮时,我们得到的是我们的ExcelModel(控制器中的参数)为空。

模型

public class ExcelModel
{
    // Custom class with all Custom Order fields.
    public IEnumerable<CustomOrderRow> CustomOrderList { get; set; }
    // Custom class with all Purchase Order fields.
    public IEnumerable<PurchaseOrderRow> PurchaseOrderList { get; set; }
    public bool TriggerOnLoad { get; set; }
    public string TriggerOnLoadMessage { get; set; }
}

控制器

public class ExcelController : Controller
{
    // GET: Excel
    public ActionResult Excel()
    {
        if (Session["myID"] == null)
        {
            return ExpireSession();
        }

        var model = new ExcelModel
        {
            CustomOrderList = null,
            PurchaseOrderList = null,
            TriggerOnLoad = false,
            TriggerOnLoadMessage = string.Empty
        };

        return View(model);
    }

    [HttpPost]
    public ActionResult Excel(FormCollection formCollection, ExcelModel model)
    {
        if (Session["myID"] == null)
        {
            return ExpireSession();
        }

        if (!ModelState.IsValid)
            return View(model);

        // If the user confirmed the information displayed.
        if (Request.Form.AllKeys.Contains("ConfirmCustomOrder"))
        {
            return ConfirmExcelDocument(model);
        }

        // Otherwise assume the user is trying to upload a new file.
        model = new ExcelModel
        {
            CustomOrderList = null,
            PurchaseOrderList = null,
            TriggerOnLoad = false,
            TriggerOnLoadMessage = string.Empty
        };

        // Read excel file and create the list in the ExcelModel object.
        var file = Request?.Files["UploadedFile"];

        if (file == null || (file.ContentLength <= 0) || string.IsNullOrEmpty(file.FileName))
            return View(model);

        using (var package = new ExcelPackage(file.InputStream))
        {
            var currentSheet = package.Workbook.Worksheets;
            var workSheet = currentSheet.First();

            switch (workSheet.Cells[1, 1].Value.ToString().Trim())
            {
                case "Custom Order":
                    // Custom order
                    IterateCustomOrder(model, workSheet);
                    break;
                case "Purchase Order":
                    // Purchase order
                    IteratePurchaseOrder(model, workSheet);
                    break;
                default:
                    model.TriggerOnLoadMessage = "Incorrect file format, please use our template.";
                    model.TriggerOnLoad = true;
                    model.CustomOrderList = null;
                    model.PurchaseOrderList = null;
                    return View(model);
            }
        }

        return View(model);
    }

    [HttpPost]
    public ActionResult ConfirmExcelDocument(ExcelModel model)
    {
        // Later we want to further validate the information here. Currently we only print the TriggerOnLoadMessage on the screen after the "Confirm"-button is pressed.
        model = new ExcelModel
        {
            TriggerOnLoad = true,
            TriggerOnLoadMessage = "YOU PRESSED THE CONFIRM BUTTON!",
            PurchaseOrderList = null
        };
        return View(model);
    }
}

查看

@{
    if (Model.TriggerOnLoad && Model.CustomOrderList != null)
    {
        using (Html.BeginForm("Excel", "Excel", FormMethod.Post))
        {
            <input id="ConfirmCustomOrder" type="submit" class="standardbutton" name="ConfirmCustomOrder" value="Confirm Custom Order" formaction="Excel" />
        }

            <table id="logtable">
                <thead>
                    <tr>
                        <th>Order</th>
                        <th>Customer</th>
                        <th>Line</th>
                        <th>Product</th>
                        <th>Quantity</th>
                        <th></th>
                    </tr>
                </thead>
             <tbody>
             @foreach (var item in Model.CustomOrderList)
             {
                 <tr>
                     <td>@Html.DisplayFor(modelItem => item.OrderNr)</td>
                     <td>@Html.DisplayFor(modelItem => item.Name)</td>
                     <td>@Html.DisplayFor(modelItem => item.Line)</td>
                     <td>@Html.DisplayFor(modelItem => item.ItemId)</td>
                     <td>@Html.DisplayFor(modelItem => item.Quantity)</td>
                     <td><input type="button" class="standardbutton extra-info-button" name="answer" value="Info" onclick="showDiv(@item.RowNum.ToString())" /></td>
                 </tr>
                 <tr>
                     <td id="@item.RowNum.ToString()" style="display: none;" class="answer_list" colspan="5">
                     <pre>
                         <strong>OrderNr:</strong> @item.OrderNr
                         <strong>Customer:</strong> @item.Customer 
                         <strong>OrderLines:</strong> @item.OrderLines 
                         // ...and a lot more fields in the model. 
                     </pre> <br />
                 </td>
              </tr>
           }
        </tbody>
     </table>
  }

修改1。

Picture of the problem.

2 个答案:

答案 0 :(得分:1)

你无法发送excel模型信息,因为你的BeginForm只包装了按钮。

无论如何,我认为即使你这样做,也会遇到问题,因为模型绑定器需要一个索引来绑定一个集合。看看这个stackoverflows条目。

MVC post a list of complex objects

MVC Form not able to post List of objects

How can I post a list of items in MVC

答案 1 :(得分:1)

所以我意识到实际上没有好办法做我正在计划的事情。网络上的替代方案是使用隐藏字段或绑定到索引,然后重新构建列表等...两者都很难从我的理解。而且由于它是一张包含50多列的Excel表格,并且有无限行的可能性,因此它似乎不是最佳的。

我最终使用Session(感谢@AbdulG)来存储我的Model.CustomOrderList以获得我正在寻找的结果(在模型的视图中发布之后不必重新构建我的列表)

<强>控制器

[HttpPost]
public ActionResult Excel(FormCollection formCollection)
{
    if (Session["myID"] == null)
    {
        return ExpireSession();
    }
    if (Request.Form.AllKeys.Contains("ConfirmCustomOrder"))
    {
        return ConfirmExcelDocument();
    }

    var model = new ExcelModel
    {
        CustomOrderList = null,
        PurchaseOrderList = null,
        TriggerOnLoad = false,
        TriggerOnLoadMessage = string.Empty
    };

    if (!ModelState.IsValid)
        return View(model);

    var file = Request?.Files["UploadedFile"];

    if (file == null || (file.ContentLength <= 0) || string.IsNullOrEmpty(file.FileName))
        return View(model);

    using (var package = new ExcelPackage(file.InputStream))
    {
        var currentSheet = package.Workbook.Worksheets;
        var workSheet = currentSheet.First();

        switch (workSheet.Cells[1, 1].Value.ToString().Trim())
        {
            case "Custom Order":
                // Custom order
                IterateCustomOrder(model, workSheet);
                Session["CustomOrderList"] = model.CustomOrderList;
                break;
            case "Purchase Order":
                // Purchase order
                IteratePurchaseOrder(model, workSheet);
                Session["PurchaseOrderList"] = model.PurchaseOrderList;
                break;
            default:
                model.TriggerOnLoadMessage = "Incorrect file format, please use our template.";
                model.TriggerOnLoad = true;
                model.CustomOrderList = null;
                model.PurchaseOrderList = null;
                return View(model);
        }
    }

    return View(model);     
}

[HttpPost]
public ActionResult ConfirmExcelDocument()
{
    var model = new ExcelModel
    {
        TriggerOnLoad = true,
        TriggerOnLoadMessage = string.Empty,
        PurchaseOrderList = null,
        CustomOrderList = null
    };

    if (Session["CustomOrderList"] == null)
        return View(model);

    var list = (IEnumerable<CustomOrderRow>)Session["CustomOrderList"];

    Session["CustomOrderList"] = null;

    // ... Do some validating etc. 

    return View(model);
}