2016-08-12 5 views
0

Ich versuche, eine Funktion in einem Angular-Controller zu erstellen, der ein Array von TestExpense-Objekten an eine C# API übergibt, die dann in eine Datenbank einfügt. Derzeit ist die API nur für die gleichzeitige Ausführung konfiguriert.Übergeben Sie ein Array von Objekten an POST in Angular

Die Objekte des Arrays, $scope.TestExpenses, möchte ich durch die folgende Konstruktor dargestellt passieren:

function TestExpense(employeeId, expenseDate, taskId, expenseTypeId, 
    billingCategory, notes, amount, lastUpdatedDate, lastUpdatedBy, dateSubmitted) { 
    this.employeeId = employeeId; 
    this.expenseDate = expenseDate; 
    this.taskId = taskId; 
    this.expenseTypeId = expenseTypeId; 
    this.billingCategory = billingCategory; 
    this.notes = notes; 
    this.amount = amount; 
    this.lastUpdatedDate = lastUpdatedDate; 
    this.lastUpdatedBy = lastUpdatedBy; 
    this.dateSubmitted = dateSubmitted; 
    this.location = location; 
} 

$scope.TestExpenses = []; 

Der aktuelle Zustand des jeweiligen Winkelfunktion submitEntriesToDatabase:

$scope.submitEntriesToDatabase = function() { 
    $http.post('/expense/submitExpense', $scope.TestExpenses) 
    .success(function (data, status, headers, config) { 

    }) 
    .error(function (data, status, headers, config) { 

    }); 


}; 

In C#, Ich habe folgendes Modell, das meinem TestExpense Objekt entspricht:

public class Expense 
{ 
    public int employeeId { get; set; } 
    public string expenseDate { get; set; } 
    public int taskId { get; set; } 
    public int expenseTypeId { get; set; } 
    public int billingCategory { get; set; } 
    public string notes { get; set; } 
    public float amount { get; set; } 
    public string LastUpdatedDate { get; set; } 
    public int LastUpdatedBy { get; set; } 
    public string dateSubmitted { get; set; } 
    public string location { get; set; } 
} 

Und die Methode, um die POST in der API zu handhaben:

public void SubmitExpenses(List<Expense> expenses) 
    { 

     //using(cnxn) 
     //{ 
     // using(SqlCommand sqlQuery = new SqlCommand("INSERT INTO Expenses " + 
     //  "(Employee_ID, Task_ID, Expense_Date, Expense_Type_ID, Billing_Category_ID, " + 
     //  "Amount, Notes, Last_Updated_By, Last_Update_Datetime, Date_Submitted, Location) " + 
     //  "Values (@employeeId, @taskId, @expenseDate, @expenseTypeId, @billingCategory, @amount, @notes, " + 
     //  "@lastUpdatedBy, @lastUpdatedDate, @dateSubmitted, @locationId)", cnxn)) 
     // { 
     //  sqlQuery.Parameters.Add(new SqlParameter("@employeeId", SqlDbType.Int) { Value = employeeId }); 
     //  sqlQuery.Parameters.Add(new SqlParameter("@expenseDate", SqlDbType.DateTime) { Value = expenseDate }); 
     //  sqlQuery.Parameters.Add(new SqlParameter("@taskId", SqlDbType.Int) { Value = taskId }); 
     //  sqlQuery.Parameters.Add(new SqlParameter("@expenseTypeId", SqlDbType.Int) { Value = expenseTypeId }); 
     //  sqlQuery.Parameters.Add(new SqlParameter("@billingCategory", SqlDbType.Int) { Value = billingCategory }); 
     //  sqlQuery.Parameters.Add(new SqlParameter("@notes", SqlDbType.Text) { Value = notes }); 
     //  sqlQuery.Parameters.Add(new SqlParameter("@amount", SqlDbType.Money) { Value = amount }); 
     //  sqlQuery.Parameters.Add(new SqlParameter("@lastUpdatedDate", SqlDbType.DateTime) { Value = lastUpdatedDate }); 
     //  sqlQuery.Parameters.Add(new SqlParameter("@lastUpdatedBy", SqlDbType.Int) { Value = lastUpdatedBy }); 
     //  sqlQuery.Parameters.Add(new SqlParameter("@dateSubmitted", SqlDbType.DateTime) { Value = dateSubmitted }); 
     //  sqlQuery.Parameters.Add(new SqlParameter("@locationId", SqlDbType.VarChar) { Value = "Radnor" }); 


     //  cnxn.Open(); 
     //  sqlQuery.ExecuteNonQuery(); 
     // } 
     //} 



    } 

Die Linien, die einen einzelnen Eintrags einfügen in meiner SubmitExpenses Arbeit sind auf Kommentar (mit der entsprechenden Methodensignatur, nicht das, was jetzt da ist). Es ist auch diese Funktionalität, die ich mit dem List<Expenses> expenses Argument nachahmen möchte. Von dem, was ich erhalte, muss ich die JSON-Zeichenfolge deserialisieren, die meine $scope.TestExpenses-Array darstellen wird, aber ich bin unsicher, wie man beginnt, einzelne Expense-Objekte daraus zu analysieren.

Die entsprechende Route in RouteConfig.cs:

routes.MapRoute(
    name:"SubmitExpense", 
    url:"expense/submitExpense", 
    defaults: new 
    { 
      controller = "Expense", 
      action = "SubmitExpenses" 
    } 
); 

Jede mögliche Anleitung geschätzt würde viel!

+0

Was die Strecke ist, die Einrichtung ist, wie auf diese Funktion angewendet wurde, dass? –

+0

Es ist wie in der '$ http.post' gesehen. Ich weiß, dass Daten an die 'SubmitExpenses'-Methode in meinem Controller übergeben werden, aber ich weiß nicht, wie ich die als Argument übergebene' List' zerlegen soll, was meiner Meinung nach unabhängig von der Route ein Problem darstellt. – WakaChewbacca

+0

Ich habe den Beitrag bearbeitet, weil ich den Methodenkopf 'SubmitClasses' nicht richtig eingerückt hatte. Es tut uns leid. – WakaChewbacca

Antwort

1

Von dem, was ich sammeln, muss ich die JSON-String deserialisieren, die my $ scope.TestExpenses Array darstellen, aber ich bin nicht sicher, wie man Startobjekte individuellen Aufwand aus es parsen.

Nein. Sie müssen keine Sache zum Deserialisieren tun. Es wird automatisch deserialisiert.

Eine bessere Umsetzung der POST-Anfrage wird dies sein.

$scope.submitEntriesToDatabase = function() { 
    var config = { 
     method: "POST", 
     url: '/expense/submitExpense', 
     data: $scope.TestExpenses 
    }; 
    $http(config).then(function(response) { 
     //success 
    }, function(response) { 
     //error 
    }); 
}; 

Wenn die Eigenschaftsnamen im Array gleich sind wie die der das Objekt in Ihre allgemeine Liste, wird die Web-api automatisch die JavaScript-Array zu List<T> konvertieren.

S.S. Verwenden Sie keine .success und .error Rückrufe, da sie veraltet sind. Verwenden Sie .then

+0

Vielen Dank! Außerdem ist +1, um mir einen Einblick in die richtige Verwendung von '$ http.post' – WakaChewbacca

+0

' $ http.post' zu geben, gleich gut. '$ http' gibt uns mehr Kontrolle. es ist meiner Meinung nach auch besser lesbar – naveen

2

Von dem, was ich sammeln, muss ich die JSON-String deserialisieren, die meine $ scope.TestExpenses Array darstellen, aber ich bin nicht sicher, wie von ihm einzelnen Kosten Objekte beginnen zu parsen.

Einfach. Verwenden Sie den Dekorator [FromBody] in Ihrer Methodensignatur. Ihre standardmäßigen Einstellungen für JSON-Serializer-Einstellungen für alle Controller versuchen, die Zeichenfolge in die Liste Expense zu parsen - wenn Sie Json.NET verwenden, kann sie dies automatisch verarbeiten.

public void SubmitExpenses([FromBody] List<Expense> expenses) 
+0

Ich werde das jetzt versuchen. Also sollte ich in der Lage sein, auf ein Element vom 'expenses' -Argument als' Expense'-Objekt über seinen Index zuzugreifen und dann auf die Eigenschaften jedes einzelnen Elements zuzugreifen? – WakaChewbacca

+0

+1 für Ihre Hilfe, @toadflakz. Ich habe '' FromBody ''nicht benötigt, wie von @naveen beschrieben, aber ich weiß es zu schätzen, dass du mir geholfen hast, auf den richtigen Weg zu kommen. – WakaChewbacca

+0

ist er richtig. Es ist nur, dass Web-API verwendet JSON.NET +1 – naveen

0

Die richtige Art und Weise einen Beitrag in Winkel 1.x zu tun, $ http wird:

$http.post('/my/url',{foo:bar}).then(function(result) { 
    console.log(result.data); // data property on result contains your data 
}); 
Verwandte Themen