2008-12-03 7 views
5

Ich versuche, ein anonymes Objekt über einen Webdienst zu senden. Kann ich das trotzdem tun, ohne manuell eine Klasse zu erstellen und sie in diese Klasse zu übertragen? Gegenwärtig kann eine Ausnahme, die das Anonyme Objekt angibt, nicht serialisiert werden.Wie serialisiere ich ein anonymes Objekt zum Senden über einen SOAP-Webdienst?

// Some code has been removed here to simplify the example. 
[WebMethod(EnableSession = true)] 
public Response GetPatientList() { 
    var patientList = from patient in ((User)Session["user"]).Practice.Patients 
         select new { 
          patientID = patient.PatientID, 
          status = patient.Active ? "Active" : "Inactive", 
          patientIdentifier = patient.PatientIdentifier, 
          physician = (patient.Physician.FirstName + " " + patient.Physician.LastName).Trim(), 
          lastModified = patient.Visits.Max(v => v.VisitDate) 
         }; 
    return patientList; 
} 

Vielen Dank im Voraus.

Edit: Hier ist ein Beispiel dafür, was ich meine, durch manuelles Erstellen einer Klasse mit dem anonymen Objekt zurück und füllen ...

public class Result { 
    public bool success; 
    public bool loggedIn; 
    public string message; 
} 

public class PracticeInfoResult : Result { 
    public string practiceName; 
    public string address; 
    public string city; 
    public string state; 
    public string zipCode; 
    public string phone; 
    public string fax; 
} 

Antwort

7

Anonym Art sollen für einfache Projektionen verwendet werden sehr lose gekoppelter Daten, die nur innerhalb einer Methode verwendet werden. Wenn es sinnvoll ist, dass eine Webmethode Daten eines Typs zurückgibt, sollte sie wirklich gut gekapselt sein. Mit anderen Worten, auch wenn Sie können einen Weg finden, um eine Instanz eines anonymen Typs von einer Webmethode zurückzugeben, empfehle ich dringend, dass Sie es nicht tun.

Ich würde persönlich nicht die Klassen mit öffentlichen Feldern entweder erstellen - verwenden Sie stattdessen automatisch implementierte Eigenschaften, so dass Sie sicher mehr Verhalten später hinzufügen können, wenn Sie müssen.

Beachten Sie, dass nach dem Erstellen des "richtigen" Typs der Abfrageausdruck nur sehr, sehr geringfügig geändert werden muss - fügen Sie einfach den Namen des Typs zwischen new und { ein, um einen Objektinitialisierer zu verwenden.

+0

Einfach nur neugierig, warum bevorzugen Sie automatisch Eigenschaften über den öffentlichen Bereichen umgesetzt? – Kevin

+0

Siehe http://csharpindepth.com/Articles/Chapter8/PropertiesMatter.aspx –

+0

Wenn Sie eine serialisierte Nachricht wie JSON zurückgeben, würde das nicht bedeuten, dass Sie mit der Vorstellung einverstanden sind, dass es lose gekoppelt ist? das scheint immer noch ein gültiger Anwendungsfall zu sein. – pc1oad1etter

1

Hier ist der Code, den ich mit aufgewickelt habe.

[WebMethod(EnableSession = true)] 
public PatientsResult GetPatientList(bool returnInactivePatients) { 
    if (!IsLoggedIn()) { 
     return new PatientsResult() { 
      Success = false, 
      LoggedIn = false, 
      Message = "Not logged in" 
     }; 
    } 
    Func<IEnumerable<PatientResult>, IEnumerable<PatientResult>> filterActive = 
     patientList => returnInactivePatients ? patientList : patientList.Where(p => p.Status == "Active"); 
    User u = (User)Session["user"]; 
    return new PatientsResult() { 
     Success = true, 
     LoggedIn = true, 
     Message = "", 
     Patients = filterActive((from p in u.Practice.Patients 
         select new PatientResult() { 
          PhysicianID = p.PhysicianID, 
          Status = p.Active ? "Active" : "Inactive", 
          PatientIdentifier = p.PatientIdentifier, 
          PatientID = p.PatientID, 
          LastVisit = p.Visits.Count > 0 ? p.Visits.Max(v => v.VisitDate).ToShortDateString() : "", 
          Physician = (p.Physician == null ? "" : p.Physician.FirstName + " " + p.Physician == null ? "" : p.Physician.LastName).Trim(), 
         })).ToList<PatientResult>() 
    }; 
} 
public class Result { 
    public bool Success { get; set; } 
    public bool LoggedIn { get; set; } 
    public string Message { get; set; } 
} 
public class PatientsResult : Result { 
    public List<PatientResult> Patients { get; set; } 
} 
public class PatientResult { 
    public int PatientID { get; set; } 
    public string Status { get; set; } 
    public string PatientIdentifier { get; set; } 
    public string Physician { get; set; } 
    public int? PhysicianID {get;set;} 
    public string LastVisit { get; set; } 
} 

}