2016-05-13 30 views
1

Ich versuche, eine Liste der Produkte von anzeigen Pass mehr Artikel von Liste <Artikel>, aber zu meinem Controller-Typ zu übergeben, wenn ich meine Daten einreichen Es wird in meinem Controller als null angezeigt.Wie Controller (ASP.NET MVC 4)

Was ich möchte, ist, dass ich eine Liste von 'Ausgaben' in der Ansicht habe, und neben jedem 'Aufwand' oder Element ist ein Kontrollkästchen von Eingereichte Boolesche Eigenschaft in meinem Modell. Wenn ich die Artikel überprüfe, möchte ich die Liste der geprüften Artikel Eigenschaften Eingereicht und DateSubmitted in der Datenbank aktualisiert werden.

@ Html.DisplayFor (ModellItem => item.Submitted) in der Ansicht erzeugt Kontrollkästchen.

Was mache ich falsch?

Hier ist meine Ansicht:

@model IEnumerable<Expenses.Models.Expense> 

@{ 
ViewBag.Title = "Submit Expenses"; 
Layout = "~/Views/Shared/_Layout.cshtml"; 

DateTime today = DateTime.Today; 
string formattedDate = today.ToString("MM/dd/yyyy"); 
} 

<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css"> 
<script src="//code.jquery.com/jquery-1.10.2.js"></script> 
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script> 

<h2>Submit Expenses</h2> 

@using (Html.BeginForm()) 
{ 
@Html.AntiForgeryToken() 
<div class="form-inline"> 
    <div class="form-group"> 
     <h4>Start Date:</h4> 
     <div class="col-md-10"> 
      @Html.TextBox("expenseDate", formattedDate, htmlAttributes: new 
      { 
       @class = "form-control" 
      }) 
     </div> 
    </div> 

    <div class="form-group"> 
     <h4>End Date:</h4> 
     <div class="col-md-10"> 
      @Html.TextBox("expenseDate2", formattedDate, htmlAttributes: new 
      { 
       @class = "form-control" 
      }) 
     </div> 
    </div> 

    <div class="form-group"> 
     @if (User.IsInRole("admin")) 
     { 
      <h4>Username:</h4> 
      <div class="editor-field"> 
       @Html.DropDownList("UserId", String.Empty) 
      </div> 
     } 
    </div> 

    <br /> 
    <br /> 

    <div class="form-group"> 
     <div class="col-md-2"> 
      <input type="submit" value="Retrieve Expenses" class="btn btn-default" /> 
     </div> 
    </div> 

</div> 

<br /> 
<br /> 


<p> 
    @Html.ActionLink("Create New", "Create") 
</p> 
<table style="margin-bottom: 20px;"> 
    <tr> 
     <th> 
      @Html.DisplayNameFor(model => model.Company) 
     </th> 
     <th> 
      @Html.DisplayNameFor(model => model.Category) 
     </th> 
     <th> 
      @Html.DisplayNameFor(model => model.Province) 
     </th> 
     <th> 
      @Html.DisplayNameFor(model => model.ReceiptName) 
     </th> 
     <th> 
      @Html.DisplayNameFor(model => model.Comment) 
     </th> 
     <th> 
      @Html.DisplayNameFor(model => model.GrossAmount) 
     </th> 
     <th> 
      @Html.DisplayNameFor(model => model.TaxAmount) 
     </th> 
     <th> 
      @Html.DisplayNameFor(model => model.NetAmount) 
     </th> 
     <th> 
      @Html.DisplayNameFor(model => model.Mileage) 
     </th> 
     <th> 
      @Html.DisplayNameFor(model => model.TravelStatus) 
     </th> 
     <th> 
      @Html.DisplayNameFor(model => model.LunchLearnStatus) 
     </th> 
     <th> 
      @Html.DisplayNameFor(model => model.WithClientStatus) 
     </th> 
     <th> 
      @Html.DisplayNameFor(model => model.DateEntered) 
     </th> 
     <th> 
      @Html.DisplayNameFor(model => model.DateSubmitted) 
     </th> 
     <th> 
      @Html.DisplayNameFor(model => model.ExpenseDate) 
     </th> 
     <th> 
      @Html.DisplayNameFor(model => model.ImageName) 
     </th> 
     @if (User.IsInRole("admin")) 
     { 
      <th> 
       @Html.DisplayNameFor(model => model.UserProfile.UserName) 
      </th> 
     } 
     <th></th> 
    </tr> 
    <tr> 
     <td> 
      <b>Select All:</b> 
      <br /> 
      <input type="checkbox" name="expense" value="Expense" id="selectAllCheckboxes" class="expenseCheck"> 
     </td> 
    </tr> 
    @foreach (var item in Model) 
    { 
     <tr> 
      <td class="submitCheck"> 
       @Html.EditorFor(modelItem => item.Submitted) 
      </td> 
      <td> 
       @Html.DisplayFor(modelItem => item.Company) 
      </td> 
      <td> 
       @Html.DisplayFor(modelItem => item.Category) 
      </td> 
      <td> 
       @Html.DisplayFor(modelItem => item.Province) 
      </td> 
      <td> 
       @Html.DisplayFor(modelItem => item.ReceiptName) 
      </td> 
      <td> 
       @Html.DisplayFor(modelItem => item.Comment) 
      </td> 
      <td> 
       @Html.DisplayFor(modelItem => item.GrossAmount) 
      </td> 
      <td> 
       @Html.DisplayFor(modelItem => item.TaxAmount) 
      </td> 
      <td> 
       @Html.DisplayFor(modelItem => item.NetAmount) 
      </td> 
      <td> 
       @Html.DisplayFor(modelItem => item.Mileage) 
      </td> 
      <td> 
       @Html.DisplayFor(modelItem => item.TravelStatus) 
      </td> 
      <td> 
       @Html.DisplayFor(modelItem => item.LunchLearnStatus) 
      </td> 
      <td> 
       @Html.DisplayFor(modelItem => item.WithClientStatus) 
      </td> 
      <td> 
       @Html.DisplayFor(modelItem => item.DateEntered) 
      </td> 
      <td> 
       @Html.DisplayFor(modelItem => item.DateSubmitted) 
      </td> 
      <td> 
       @Html.DisplayFor(modelItem => item.ExpenseDate) 
      </td> 
      <td> 
       @if (item.ImageName != null) 
       { 
        <a href="~/Images/@Html.DisplayFor(modelItem => item.UserProfile.FullName)/@Html.DisplayFor(modelItem => item.ImageName)" class="imageClick" target="_blank"><img src="~/Images/@Html.DisplayFor(modelItem => item.UserProfile.FullName)/@Html.DisplayFor(modelItem => item.ImageName)" alt="Image" style="width:80%" /></a> 
       } 
      </td> 
      @if (User.IsInRole("admin")) 
      { 
       <td> 
        @Html.DisplayFor(modelItem => item.UserProfile.UserName) 
       </td> 
      } 
      <td> 
       @Html.ActionLink("Edit", "Edit", new { id = item.ExpenseId }) | 
       @Html.ActionLink("Details", "Details", new { id = item.ExpenseId }) | 
       @if (User.IsInRole("admin")) 
       { 
        @Html.ActionLink("Delete", "Delete", new { id = item.ExpenseId }) 
       } 

      </td> 
     </tr> 
    } 

</table> 

@Html.ActionLink("Submit Expenses", "SubmitExpenses", "Expenses", null, new { @class = "submitLink", @style = "background-color: #d3dce0; border: 1px solid #787878; cursor: pointer; font-size: 1.5em; font-weight: 600; margin-right: 8px; padding: 7px; width: auto; text-decoration: none; font-weight:bold;"}) 

<div class="ExportSection" style="margin-top:30px;"> 
    @*<a href="javascript:void(0)">Export To CSV</a>*@ 
    @Html.ActionLink("Export To CSV", "ExportExpensesListToCSV") 
</div> 
} 

@section scripts { 
<script type="text/javascript"> 


    $("#selectAllCheckboxes").click(function() { 
     $('.submitCheck input:checkbox').not(this).prop('checked', this.checked); 
    }); 

    $(function() { 
     $("#expenseDate").datepicker(); 
    }); 

    $(function() { 
     $("#expenseDate2").datepicker(); 
    }); 

</script> 

} 

und hier ist mein Controller-Methode:

[Key] 
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
    public int ExpenseId { get; set; } 

    [Required] 
    public string Company { get; set; } 

    [Required] 
    public string Category { get; set; } 

    [Required] 
    [Display(Name = "Receipt Name")] 
    public string ReceiptName { get; set; } 
    public string Comment { get; set; } 

    [Required] 
    public string Province { get; set; } 

    [Required] 
    [Display(Name = "Gross Amount")] 
    public decimal GrossAmount { get; set; } 

    [Required] 
    [Display(Name = "GST/HST Amount")] 
    public decimal TaxAmount { get; set; } 

    [Required] 
    [Display(Name = "Net Amount")] 
    public decimal NetAmount { get; set; } 

    [Display(Name = "Mileage (in Kilometers)")] 
    public int Mileage { get; set; } 

    [Display(Name = "Travelling?")] 
    public bool TravelStatus { get; set; } 

    [Display(Name = "Lunch & Learn?")] 
    public bool LunchLearnStatus { get; set; } 

    [Display(Name = "With Clients?")] 
    public bool WithClientStatus { get; set; } 

    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")] 
    [Required] 
    [Display(Name = "Date Entered")] 
    public DateTime? DateEntered{ get; set; } 

    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")] 
    [Display(Name = "Date Submitted")] 
    public DateTime? DateSubmitted { get; set; } 

    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")] 
    [Required] 
    [Display(Name = "Expense Date")] 
    public DateTime? ExpenseDate { get; set; } 

    [Display(Name = "Image")] 
    public string ImageName { get; set; } 

    [Display(Name = "Submitted?")] 
    public bool Submitted { get; set; } 

    [Required] 
    [Display(Name = "Name")] 
    public int UserId { get; set; } 
    [ForeignKey("UserId")] 
    public virtual UserProfile UserProfile { get; set; } 

Meine Variable expensesFromView zeigt als null und:

public ActionResult SubmitExpenses(List<Expense> expenses, DateTime? expenseDate = null, DateTime? expenseDate2 = null, int? userId = 0) 
    { 
     expenseDate = (DateTime)Session["FirstDate"]; 
     expenseDate2 = (DateTime)Session["SecondDate"]; 

     if (expenseDate == null || expenseDate2 == null) 
     { 
      expenseDate = DateTime.Now.AddMonths(-1); 
      expenseDate2 = DateTime.Today; 
     } 

     string currentUserId = User.Identity.Name; 

     var query = from e in db.Expenses 
        join user in db.UserProfiles on e.UserId equals user.UserId 
        where e.ExpenseDate >= expenseDate && e.ExpenseDate <= expenseDate2 && e.DateSubmitted == null 
        orderby e.ExpenseDate descending 
        select new { e, user }; 

     if (User.IsInRole("admin") && userId != 0) 
     { 
      query = query.Where(x => x.user.UserId == userId); 
     } 
     else if (!User.IsInRole("admin")) 
     { 
      query = query.Where(x => x.user.UserName == currentUserId); 
     } 

     var expensesFromView = expenses; 

     var joined = from dbExpense in query.Select(x => x.e).AsEnumerable() 
        join localExpense in expenses on dbExpense.ExpenseId equals localExpense.ExpenseId 
        where localExpense.Submitted 
        select dbExpense; 

     foreach (Expense exp in joined) 
     { 
      exp.DateSubmitted = DateTime.Today; 
     } 

     try 
     { 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e); 
      return RedirectToAction("Submit"); 
     } 

    } 

Hier mein Modell ist Als Ergebnis bekomme ich einen Fehler auf meiner joined Abfrage, die sagt:

Wert kann nicht null sein. Parametername: In Innen

Antwort

1

Ich konnte nicht wirklich eine Möglichkeit finden, eine Liste von Elementen direkt von View zu Controller zu übergeben, also entschied ich mich, AJAX zu verwenden.

ich die Parameter meines Controller von Typ Liste <> zu int geändert [] ein Array von Element-IDs zu nehmen:

public ActionResult SubmitExpenses(int[] expenseIDs, DateTime? expenseDate = null, DateTime? expenseDate2 = null, int? userId = 0) 
    { 
     expenseDate = (DateTime)Session["FirstDate"]; 
     expenseDate2 = (DateTime)Session["SecondDate"]; 

     if (expenseDate == null || expenseDate2 == null) 
     { 
      expenseDate = DateTime.Now.AddMonths(-1); 
      expenseDate2 = DateTime.Today; 
     } 

     string currentUserId = User.Identity.Name; 

     var query = from e in db.Expenses 
        join user in db.UserProfiles on e.UserId equals user.UserId 
        where e.ExpenseDate >= expenseDate && e.ExpenseDate <= expenseDate2 && e.DateSubmitted == null 
        orderby e.ExpenseDate descending 
        select new { e, user }; 

     if (User.IsInRole("admin") && userId != 0) 
     { 
      query = query.Where(x => x.user.UserId == userId); 
     } 
     else if (!User.IsInRole("admin")) 
     { 
      query = query.Where(x => x.user.UserName == currentUserId); 
     } 

     //var localExpenseIDs = expenseIDs; 

     var joined = from dbExpense in query.Select(x => x.e).AsEnumerable() 
        join localExpense in expenseIDs on dbExpense.ExpenseId equals localExpense 
        where localExpense == dbExpense.ExpenseId 
        select dbExpense; 

     foreach (Expense exp in joined) 
     { 
      exp.DateSubmitted = DateTime.Today; 
      exp.IsSubmitted = true; 
     } 

     try 
     { 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e); 
      return RedirectToAction("Submit"); 
     } 

    } 

Meiner Ansicht zugewiesen ich die ID der einzelnen Elemente auf die ID für eine eigene HTML-Checkbox:

@foreach (var item in Model) 
    { 
     <tr> 
      <td class="checkbox-td"> 
       @Html.CheckBox("isSubmitted", new 
      { 
       @id = @Html.DisplayFor(modelItem => item.ExpenseId), 
       @class = "submitBox" 
      }) 
      </td> 
     </tr> 
    } 

<div> 
    @Html.ActionLink("Submit Expenses", "", "", null, new { @id = "submitExpensesLink" }) 
</div> 

ich einige jQuery geschrieben, so dass jedes Kontrollkästchen, das die ID des Eingangselements zu einem Array und dem arra fügt geprüft y von ganzen Zahlen würde zur SubmitExpenses Aktion Aufgegeben:

var checkedArray = []; 

    $(':checkbox[name=isSubmitted]').on('change', function() { 

     checkedArray = $(':checkbox[name=isSubmitted]:checked').map(function() { 
       return this.id; 
     }) 
     .get(); 


     //alert(checkedArray); 
    }); 

    $('#submitExpensesLink').click(function() { 

     $.ajax({ 
      type: "POST", 
      traditional: true, 
      url: "@Url.Action("SubmitExpenses", "Expenses")", 
      data: { expenseIDs: checkedArray }, 
     success: function() { 
      alert("Success!"); 
     }, 
     error: function (XMLHttpRequest, textStatus, errorThrown) { 
      if (debug) { 
       alert(XMLHttpRequest.responseText); 
       alert(textStatus); 
       alert(errorThrown); 
      } 
     } 
    }); 
    }) 
0

1) FormMethod.Post in @using (Html.BeginForm()) {}

@using (Html.BeginForm("nameAction", "nameController", FormMethod.Post)) 
{ 
    //Your code 
} 

2) Sie sollten hinzufügen Name für die Eingänge wie folgt aus:

<input type="text" name="someName"/> 
+0

Vielen Dank für Ihre Antwort. Ich habe das versucht und die Daten werden noch nicht richtig übergeben. – Sicypher

+0

@ bkhosh2, Ich habe meine Lösung bearbeitet – praguan

1

Es gibt zwei Möglichkeiten, tun dies -

1.

Sie können diese Erweiterung benötigen, die wirklich gut ist und extensible- MvcCheckBoxList - scheint dieser Website heruntergefahren wurde :) beziehen sich die Option 2

2.

@for (int i = 0; i < Model.Count; i++) 
{ 
    <tr> 
     <td class="submitCheck"> 
     <input type="checkbox" value="@Model[i].Id" name="Expense[@i].Id"> 
     <input type="hidden" value="0" name="Expense[@i].Id">   
     </td> 
     <td> 
       @Html.DisplayFor(modelItem => item.Company) 
     </td> 

btw: wenn Sie die zweite Art und Weise verwenden: in Ihrem Controller, Filter für den Nullwert für das ID-Kosten-Objekt; coz, wenn es nicht ausgewählt ist, wird Null an den Controller (als die ID des Elements) an das "verborgene" Feld gesendet, das Sie im obigen Code sehen können.

+0

Danke Mann. Die Verbindung, die du mir gegeben hast, scheint zu sein, was ich brauche. Ich werde es ausprobieren und Sie wissen lassen, ob es funktioniert! – Sicypher

+0

frage mich, warum das nicht für dich funktioniert hat. In Ihrer Controller-Aktion sollten Sie int [] mit den übergebenen Werten erhalten. Vergiss nicht, nur die Items mit dem Id-Wert> 0 zu nehmen –