2012-04-03 10 views
1

Ich habe die folgenden Klassen:Web API + MVC 4 bezüglich Modell von komplexen Typen Bindung

public class State 
{ 
    public long Id     { get; set; } 
    public string Name    { get; set; } 
    public string Abbreviation  { get; set; } 

    // Navigation Properties 
    public virtual Country Country { get; set; } 
} 

public class School 
{ 
    public long Id     { get; set; } 
    public string Name    { get; set; } 
    public string Abbreviation  { get; set; } 

    // Navigation Properties 
    public virtual State State  { get; set; } 
} 

und die folgenden Daten in meinem SQL Server

| School|    |    | 
| Id | Name  | State  | 
| 1 | UCLA  |  1  | 
+-------+-------------+---------------+ 
| State |    |    | 
| Id | Name  | Abbreviation | 
| 1 | California |  CA  | 

Ich bin versucht, einen Rest zu schaffen Controller, der eine Instanz der Schule mithilfe des HTTP-POST-Verbs mithilfe der Web-API erstellt.

public HttpResponseMessage<School> Post(School school) 
{ 
    SchoolService.CreateSchool(school); 
    var response = new HttpResponseMessage<School>(school, HttpStatusCode.Created); 
    string uri = Url.Route(null, new { id = school.Id }); 

    response.Headers.Location = new Uri(Request.RequestUri, uri); 
    return response; 
} 

Web API bindet richtig meine Schulklasse Namen und Abkürzung Eigenschaften von meinem Web-Formular und ruft die POST-Methode in der Steuerung, aber es nicht weiß, was mit der State-Klasse zu tun. Ich bin mir nicht sicher, wie ich das einrichten soll. Ich hätte gerne ein Drop-down, das an die State-Klasse gebunden ist, und wenn ich die Erstellung der School einreiche, wird der korrekte Zustand aus meinen bestehenden Daten der neuen Schulinstanz zugewiesen.

+0

Wie übermitteln Sie den Wert für die Klasse "Store"? können Sie die HTTP-Anforderungsdetails (Kopfzeilen, Formularfelder und Werte usw.) posten? – tugberk

+0

Ich habe das gleiche Problem; Ich bin XML-Deserialisierung eines komplexen Typs in einem POST und es versucht, ModelBinders anstelle der Standard-XmlMediaTypeFormatter zu gehen. Es wird erwähnt, dass JSON dafür geeignet ist - verwenden Sie XML oder JSON Serialization? – Steve

Antwort

1

Zunächst ist Ihr Domain-Modell-Design ein wenig rau. Ihre School Tabelle soll einen FK zu State Tisch hat und Sie sollen haben, dass in Ihrer POCO Klasse auch:

public class School 
{ 
    public long Id     { get; set; } 
    public long StateId    { get; set; } 
    public string Name    { get; set; } 
    public string Abbreviation  { get; set; } 

    // Navigation Properties 
    public virtual State State  { get; set; } 
} 

Dann sollten Sie ein Formularfeld, ähnlich wie unten haben:

<select id="StateId" name="StateId"> 
    <option value="">Select a State</option> 
    <option value="310">CA</option> 
    <option value="311">NY</option> 
</select> 
+0

Hallo Tugberk, In meinen vorherigen Iterationen hätte ich ein ViewModel der Schule, das die FK enthält. Da Web API eingeführt wurde, wollte ich versuchen, dies ohne Verwendung von FKs und ohne eine Viewmodel-Klasse insgesamt zu tun, in der Hoffnung, dass es eine Möglichkeit geben würde, komplexe Typen zu binden, wie zum Beispiel State in diesem Fall. Ich denke, meine Frage ist, ob es möglich ist, es auf diese Weise zu implementieren, ohne FKs zu verwenden, und wenn ja, wie die Post-Methode eingerichtet wird und wie der Wert für den Status übermittelt wird. Ich muss vielleicht den FK/viewmodel Weg machen, wenn es nicht möglich ist. – khaihon

0

In meinem aktuelles Projekt Ich habe etwas Ähnliches mit folgendem Ansatz erreicht:

Ich habe eine Device-Klasse (POCO) und eine DeviceCommand-Klasse (POCO). Gerät kann viele Befehle haben und jeder Befehl wird genau ein Gerät haben.

Ich habe nicht mit ViewModel und POCO Klassen zwischen den Schichten verwendet.

public class Device 
{ 
    [Key] 
    public int ID { get; set; } 

    public int DeviceID { get; set; } 

    public bool IsActive { get; set; } 

    // Navigational properties 
    public ICollection<DeviceCommand> CommandList { get; set; } 
} 

Und

public class DeviceCommand 
{ 
    public int Id { get; set; } 

    public string CommandText { get; set; } 
    public string CommandId { get; set; } 

    // Navigational properties 
    public int DeviceId { get; set; } 
    public Device Device { get; set; } 
} 

Und in meinem DbContext abgeleiteten Klasse I folgenden Code haben:

protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder) 
    {   
     modelBuilder.Entity<DeviceCommand>() 
      .HasRequired(d => d.Device) 
      .WithMany(l => l.CommandList) 
      .HasForeignKey(b => b.DeviceId) 
      .WillCascadeOnDelete(); 
    } 

IMO werden Sie zu Setup eine Fremdschlüsselbeziehung entweder Anmerkungen oder fließend API.

Wenn der Parameter in der POST-Methode kein Attribut enthält, wird die Entscheidung ausschließlich auf dem .NET-Typ des Parameters getroffen. "Simple types" verwendet Modellbindung. Komplexe Typen verwenden die Formatierer.

entnehmen Sie bitte diesen Link web api Bindung besser zu verstehen:

http://blogs.msdn.com/b/jmstall/archive/2012/04/16/how-webapi-does-parameter-binding.aspx

Hoffnung, das hilft.