C# 难以从android应用程序将复杂的JSON对象传递到RESTful服务

C# 难以从android应用程序将复杂的JSON对象传递到RESTful服务,c#,android,json,web-services,wcf,C#,Android,Json,Web Services,Wcf,我对android->JSON->RESTful WCF webserive架构的实现有一个问题。我主要来自基于C模式的背景,因此很难理解android架构。我设计C webservice的方式是使用一个完整的模型名称空间,将所有业务对象(如User、UserProfile、UserSearchCriteria、UserPhoto等)定义为CLR对象 我已经使用RESTful模型通过WCF公开了我的webservice接口,并结合了我习惯使用的请求/响应模式。RESTWeb方法的一个示例如下所示

我对android->JSON->RESTful WCF webserive架构的实现有一个问题。我主要来自基于C模式的背景,因此很难理解android架构。我设计C webservice的方式是使用一个完整的模型名称空间,将所有业务对象(如User、UserProfile、UserSearchCriteria、UserPhoto等)定义为CLR对象

我已经使用RESTful模型通过WCF公开了我的webservice接口,并结合了我习惯使用的请求/响应模式。RESTWeb方法的一个示例如下所示

[OperationContract]
        [WebInvoke(
            Method = "POST",
            RequestFormat = WebMessageFormat.Json,
            ResponseFormat = WebMessageFormat.Json,
            UriTemplate = "/GetSeeds"
            )]
        GetSeedsResponse GetSeeds(GetSeedsRequest request);
响应对象

[DataContract]
    public class GetSeedsResponse
    {
        public GetSeedsResponse(List<Seed> seeds)
        {
            Seeds = seeds;
        }

        [DataMember]
        public List<Seed> Seeds { get; set; }
    }
注意:我的所有请求对象都继承自我自己的自定义基本请求对象,该对象仅为它们提供一个用于身份验证的公共头,如下所示,我不确定这是否是处理身份验证的最佳方法,但这是我熟悉的,所以我现在已经这样做了

[DataContract]
    public abstract class BaseRequest
    {
        [DataMember]
        public Header Header { get; set; }
    }

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.2022")]
    [System.SerializableAttribute]
    [System.Diagnostics.DebuggerStepThroughAttribute]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:MyStory:Web:Services:ServiceModel:Headers")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:MyStory:Web:Services:ServiceModel:Headers", IsNullable=true)]
    public class Header
    {
        public int UserId { get; set; }

        public string SessionToken { get; set; }
    }
到目前为止,我已经在AsyncTask后台工作程序中使用以下代码成功地从android调用了RESTful webmethod

protected ArrayList<Seed> doInBackground(String... params)
    {
        try
        {
            HttpClient client = new DefaultHttpClient();
            HttpPost post = new HttpPost(SERVICE_URI);

            post.setHeader("Accept", "application/json");
            post.setHeader("Content-type", "application/json");

            JSONObject data = new JSONObject();
            data.put("UserId", 1);
            data.put("NumberToTake", 10);
            data.put("StartPosition", 0);

            StringEntity entity = new StringEntity(data.toString());
            post.setEntity(entity);

            HttpResponse response = client.execute(post);
           }
...
}
但这无法处理一般的错误请求异常,webservice甚至没有输入webmethod。我在第1行设置了一个断点,该断点在没有标头的情况下被命中,但在包含标头的情况下不会被命中,因此,我假设我没有正确理解JSON或在请求对象中传递嵌入对象的方式

[DataContract]
    public class GetSeedsRequest : BaseRequest
    {
        public GetSeedsRequest(int userId, int numberToTake, int startPosition)
        {
            NumberToTake = numberToTake;
            StartPosition = startPosition;
            UserId = userId;
        }

        [DataMember]
        public int NumberToTake { get; set; }

        [DataMember]
        public int StartPosition { get; set; }

        [DataMember]
        public int UserId { get; set; }
    }
2我的整个架构方法是否正确?为每个web服务调用手动构造数组索引的请求和响应似乎相当费力,而且容易出错。我应该如何构建我的项目,为我的Web服务想要接受作为参数或作为响应对象返回的所有CLR对象创建匹配的android对象?JSON还有很多我不知道应该使用的功能吗?对于这些请求,我是否需要为可能进行的每个web服务调用创建定制的单个AsyncTask对象?我的应用程序将调用大约40种不同的web方法,这是否意味着40个AsyncTask对象保存在我代码库的某个包中?我正在努力找出最佳实践,设计一个具有相当数量web服务交互的大小合适的应用程序。如果有人有任何书籍或教程可以推荐,这些书籍或教程涉及到android项目设计的最佳实践、我的场景的架构,那么我将非常感激


为帖子的长度道歉

将Android端与Windows服务器端分离。我们使用JSON和REST的原因是它们与系统无关。不要担心窗户侧的结构。相反,关注JSON请求对服务器的作用,并关注在Android上创建JSON

首先,获得一个类似REST的客户机,并弄清楚REST调用是什么样子的,JSON主体是什么样子的

然后,想一想如何让Android发送这个身体

最后,找出如何让Android以编程方式生成JSON主体。对于最后一个,我强烈推荐。它将允许您使用更高级别的对象,而不是手动构建JSON。如果您使用JSON主体更新请求,我将使用如何在Gson中生成响应来更新此响应


作为补充说明,我建议您查看Apache HTTP客户端,而不是Apache HTTP客户端。它的功能更加全面和强大。这完全没有必要,但它会让你的生活更轻松。

谢谢你的回复,非常有帮助。就在决定什么JSON请求对服务器起作用的第一步,它应该如何看待我的WCF服务方法——我应该反序列化传递的JSON请求吗?在这种情况下,方法的签名应该是什么,字符串请求参数?例如,在我的一个请求类中,我有三个int字段和一个嵌套的复杂CLR对象,该对象本身有四个int字段和一个string字段。我是否希望将整个请求CLR对象的序列化JSON表示形式作为请求参数传递?因为您正在执行HTTP POST,所以将在POST正文中发送JSON。我对.NET服务器代码不是特别熟悉,因此我无法在服务器所期望的方面提供太多帮助,但基本上是根据GetSeedsRequest对象的性质创建的。我猜是这样的:{'NumberToTake':1,'StartPosition':2,'UserId'='jdoe'}
JSONObject header = new JSONObject();
            header.put("UserId", 1);
            header.put("SessionToken", "");
JSONObject data = new JSONObject();
            data.put("UserId", 1);
            data.put("NumberToTake", 10);
            data.put("StartPosition", 0);
data.put("Header", header);