2017-05-24 25 views
1

以下Post method在我的ASP.NET MVC Core 1.1应用程序中向数据库添加记录。只要用户从multi-select dropdown中选择exactly 3种订单类型,该方法就会成功添加记录。用户应该从下拉列表中选择​​3种订单类型。因此,如果用户选择少于3个订单类型,则如预期的那样,将引发众所周知的错误:Index was outside the bounds of the array问题:如果用户选择less than 3订单类型,如何避免上述错误。我想我可以将整个var oOrder = new Order{...}声明放在if...else..的每个块内,以避免错误。但在实际情况下,有更多的模型属性,因此在if...else...块中重复它们3次会使代码看起来比实际更复杂。有没有更好的方法来做到这一点?使用数组填充MVC模型属性

[HttpPost] 
public IActionResult AddOrder(OrderViewModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     var oOrder = new Order 
     { 
      orderName = model.orderName,    
      StartDate = model.StartDate, 
      EndDate = model.EndDate, 
      .... 
      .... 
      lkupType_1_ID = model.SelectedTypeIDs[0], 
      lkupType_2_ID = model.SelectedTypeIDs[1], 
      lkupType_3_ID = model.SelectedTypeIDs[2], 
      .... 
     }; 

      _context.Add(oOrder); 
    } 
    return RedirectToAction(....); 
} 

UPDATE

快照视图的

.... 
<div>....</div> 
.... 

<div class="form-group"> 
    <label asp-for="SelectedOrderTypeIDs"></label> 
    <div class="col-md-10"> 
     <select asp-for="SelectedOrderTypeIDs" asp-items="Model.lstOrderTypes"></select> 
    </div> 
</div> 

<button type="submit" name="submit">Add Order</button> 

注意:我使用ASP.NET MVC tag helpers和经常使用this post@Shyju为很好的例子多选标签帮手。

+0

你如何建立你的看法?默认的模型绑定器在发布的模型中需要不间断的索引,所以如果你没有发布正确的表单值,你的模型将不能正确绑定。 –

+0

@ TiesonT.I've添加了更新到我的文章来回答你的问题。请记住,代码在从下拉列表中选择3'项时工作正常 – nam

+0

这是标签助手中的表单吗?根据你的助手是如何嵌套的,如果你使用强类型的助手,它们应该生成隐藏的表单输入,这将确保(对于集合类型属性)索引从0开始连续。 –

回答

0

您可以使用Length属性来检查SelectedTypeIDs列表中的项目数。

if(model.SelectedTypeIDs.Length>3){ 
    //code 
} 

如果条件false你可以为了显示error查看使用ModelState.AddModelError方法。

if(model.SelectedTypeIDs.Length>3){ 
    ModelState.AddModelError("Dropdown", "Error! You must have maximum of 3 options"); 
    return View(); 
} 

UPDATE

您可以创建一个generic函数returns 0,如果index是出界或列表项的替代。

public static TValue GetSafe<TItem>(this IList<TItem> list, 
int index, TValue defaultValue) 
{ 
    if (index < 0 || index >= list.Count) 
    { 
     return defaultValue; 
    } 
    return list[index]; 
} 

现在,您可以使用此功能来实现您的功能。

var oOrder = new Order 
     { 
      orderName = model.orderName,    
      StartDate = model.StartDate, 
      EndDate = model.EndDate, 
      .... 
      .... 
      lkupType_1_ID =model.SelectedTypeIDs.GetSafe(0, 0) , 
      lkupType_2_ID =model.SelectedTypeIDs.GetSafe(1, 0) , 
      lkupType_3_ID =model.SelectedTypeIDs.GetSafe(2, 0) , 
      .... 
     }; 
+0

但是,用户可以选择'最多'3意味着1,2或3.条件不完全是3,而是<= 3。所以如果用户只选择1或2种订单类型,就会发生错误。 – nam

+0

你上面试过我的解决方案吗? – Morgs

+0

@南,我更新了我的答案。 –

0

您可以在下面试试,一个if作为tenary操作:

[HttpPost] 
    public IActionResult AddOrder(OrderViewModel model) 
    { 
     if (ModelState.IsValid) 
     { 
      var oOrder = new Order 
      { 
       orderName = model.orderName,    
       StartDate = model.StartDate, 
       EndDate = model.EndDate, 
       .... 
       .... 
       lkupType_1_ID = (model.SelectedTypeIDs.Length > 0) ? model.SelectedTypeIDs[0] : 0, // You can default it to null if it is Int? 
       lkupType_2_ID = (model.SelectedTypeIDs.Length > 1) ? model.SelectedTypeIDs[1] : 0, 
       lkupType_3_ID = (model.SelectedTypeIDs.Length > 2) ? model.SelectedTypeIDs[2] : 0, 
       .... 
      }; 

       _context.Add(oOrder); 
     } 
     return RedirectToAction(....); 
    } 
+0

当我选择,比如2时,它仍然会给出相同的错误。我认为这是因为,在'ternary operator'中,我们仍然要求编译器评估'model.SelectedTypeIDs [2]',结果是数组超出范围。 – nam

+0

@南,你有没有试过我的答案? –