0

尝试从 web 服务调用中获取结果以返回模型。我收到错误消息:无法将当前 JSON 数组(例如 [1,2,3])反序列化为类型“CI.Models.Schedule”,因为该类型需要 JSON 对象(例如 {"name":"value"})正确反序列化。

public Schedule getCourseSchedule()
{
    var obj = new
    {
        States = new[] { new { State = "MX" } },
        Zip = "",
        Miles = "",
        PaginationStart = 1,
        PaginationLimit = 3
    };
    using (var client = new WebClient())
    {
        client.Headers[HttpRequestHeader.ContentType] = "apoplication/json";
        var url = "http://192.168.1.198:15014/ShoppingCart2/CourseSchedule";
        var json = JsonConvert.SerializeObject(obj);
        byte[] data = Encoding.UTF8.GetBytes(json);
        byte[] result = client.UploadData(url, data);
        string returnjson = Encoding.UTF8.GetString(result);
        Schedule sched = JsonConvert.DeserializeObject<Schedule>(returnjson);
        return sched;
    }
}

时间表模型:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Globalization;

namespace CI.Models
{
    public class Schedule
    {
        public IEnumerable<Course> Courses { get; set; }
    }

    public class Course
    {

/*
JSON Data returned from web service:        
{
   "ProgramGroup":"MR",
   "ProgramCode":"RM",
   "EventCode":"20160901MXMR",
   "FormalDate":"September 1-2, 2016",
   "StartDate":"2016\/09\/01",
   "Price":5,
   "LocName":"WB Hotel",
   "LocAddress":"Av. Speedy Gonzales 220",
   "LocCity":"Monterrey",
   "LocState":"MX",
   "LocZipCode":null,
   "LicenseeURL":null,
   "AgendaURL":"NA",
   "SeatsAreAvailable":"2",
   "GeneralInfoHTML":"General Info goes here.",
   "GateKeeperHTML":null,
   "EventType":"SS",
   "TotalCourses":3
}
*/
        public string ProgramGroup { get; set; }
        public string ProgramCode { get; set; }
        public string EventCode { get; set; }
        public string FormalDate { get { return FormalDate; } set { FormalDate = convertFormalDateToSpanish(value); } }
        public string StartDate { get; set; }
        public double Price { get; set; }
        public string LocName { get; set; }
        public string LocAddress { get; set; }
        public string LocCity { get ; set; }
        public string LocState { get; set; }
        public string LocZipCode { get; set; }
        public string LicenseeURL { get; set; }
        public string AgendaURL { get { return AgendaURL; } set { AgendaURL = buildAgendaLink(value); } }
        public string SeatsAreAvailable { get; set; }
        public string GeneralInfoHTML { get; set; }
        public string GateKeeperHTML { get; set; }
        public string EventType { get; set; }
        public int TotalCourses { get; set; }

        public string convertFormalDateToSpanish(string val) 
        {
            DateTime TheDate = DateTime.Parse(StartDate);
            string[] FormalDate = val.Split(" ".ToCharArray());
            CultureInfo ci = new CultureInfo("es-ES");
            string _Date = FormalDate[1].Replace("-", " al ").Replace(",", "");
            string _Month = ci.TextInfo.ToTitleCase(TheDate.ToString("MMMM", ci));
            val = string.Concat(_Date, " ", _Month);
            return val;
        }

        private string buildAgendaLink(string val)
        {
            if (val.Trim() != "")
            {
                val = string.Concat("<a href=\"/pdfs/", EventCode, "_Agenda.pdf\">Agenda</a>");
            }
            else
            {
                val = "Agenda";
            }
            return val;
        }

    }


}
4

2 回答 2

2

您的服务器返回一个数组。试试看嘛

Course[] courses = JsonConvert.DeserializeObject<Course[]>(returnjson);
于 2013-09-10T21:12:20.053 回答
1

请注意,这不是您原始问题的答案,但我将其添加为答案,以便用一些实际代码解释我上面的评论。

FormalDate您的代码的第一个问题是AgendaUrl属性根本不起作用。访问它们将导致StackOverflowException, 因为您基本上是递归地定义了它们。

一个属性只是两个独立的 getter/setter 方法的语法糖,所以通过这样写:

public class Course
{
    public string FormalDate
    {
        get { return FormalDate; }
    }
}

你基本上是在写这个:

public class Course
{
    public string GetFormalDate()
    {
        // recursive call, with no terminating condition,
        // will infinitely call itself until there is no
        // more stack to store context data (and CLR
        // will then throw an exception)
        return GetFormalDate(); 
    }
}

要解决这个问题,您需要添加一个实际的支持字段,例如:

public class Course
{
    private string _formalDate; // <-- this is a backing field;

    // and this property uses the backing field to read/store data
    public string FormalDate 
    { 
        get { return _formalDate; } 
        set { _formalDate = convertFormalDateToSpanish(value); } 
    }
}

此外,属性 getter 返回与通过 setter 设置的值不同的值是不常见的。换句话说,我永远不会期望在课堂上这样:

var course = new Course();
course.StartDate = "2016/09/01";
course.FormalDate = "September 1-2, 2016";

Console.WriteLine(course.FormalDate); // prints "1 al 2 Septiembre" ?

我宁愿将此功能移动到不同的类中,或者至少创建返回这些值的不同属性:

public class CourseInfo
{
    // this is now a "dumb" auto-implemented property
    // (no need for a backing field anymore)
    public string FormalDate { get; set; }

    // this read-only property returns the converted value
    public string LocalizedFormalDate
    {
        get 
        {
            return convertFormalDateToSpanish(FormalDate);
        }
    }
}
于 2013-09-11T19:06:20.060 回答