Как мне сериализовать анонимный объект для отправки через веб-сервис SOAP? - PullRequest
5 голосов
/ 03 декабря 2008

Я пытаюсь отправить анонимный объект через веб-сервис. Есть ли в любом случае я могу сделать это без создания класса вручную и приведения его к этому классу? В настоящее время выдается исключение, сообщающее, что анонимный объект не может быть сериализован.

// 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;
}

Заранее спасибо.

Редактировать: Вот пример того, что я имею в виду, вручную создав класс для возврата и заполнения его анонимным объектом ...

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;
}

Ответы [ 2 ]

7 голосов
/ 03 декабря 2008

Анонимный тип предназначен для использования в простых проекциях очень слабо связанных данных, используемых только внутри метода. Если для веб-метода имеет смысл возвращать данные типа, он действительно должен быть прилично инкапсулирован. Другими словами, даже если вы можете найти способ вернуть экземпляр анонимного типа из веб-метода, я настоятельно рекомендую вам не делать этого.

Лично я бы не создавал классы с открытыми полями - вместо этого используйте автоматически реализованные свойства, так что вы можете смело добавлять больше поведения позже, если вам нужно.

Обратите внимание, что после того, как вы создали "правильный" тип, ваше выражение запроса нужно только очень и очень незначительно изменить - просто добавьте имя типа между new и {, чтобы использовать инициализатор объекта.

1 голос
/ 04 декабря 2008

Вот код, который я использовал.

[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; }
}

}

...