1

编辑:好的,所以看起来发布为 application/json 需要在服务器端单独处理而不是表单。有没有更好的方法将 C# 中的表单作为复杂对象发布?字符串:字符串只是没有削减它。例如,我希望能够使用 Dictionary 来生成:

{
 "data_map":{"some_value":1,"somevalue":"2"},
 "also_array_stuffs":["oh look","people might", "want to", "use arrays"],
 "integers_too":4
}

---OP---

我看过SO和其他地方。我只是想将 JSON 字符串发布到 URL,但服务器端一直将内容解释为字符串而不是查询字典。我们有其他不在 C# 中的客户端可以很好地访问服务器端(在 HTML、JS、Objective-C、Java 中),但由于某种原因,POST 数据从 C# 客户端返回时很不稳定。

C#源代码:

private static Dictionary<string,object> PostRequest(string url, Dictionary<string, object> vals)
{           
    var httpWebRequest = (HttpWebRequest)WebRequest.Create(BaseURL+url);
    httpWebRequest.ContentType = "application/json; charset=utf-8";
    httpWebRequest.Method = "POST";

    using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
    {
        string json = JsonFx.Json.JsonWriter.Serialize(vals);
        //json = json.Substring(1,json.Length-1);

        streamWriter.Write(json);
        streamWriter.Close();
    }

    try
    {
        var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
        using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
        {
            string response = streamReader.ReadToEnd();
            Dictionary<string,object>  retval = JsonFx.Json.JsonReader.Deserialize<Dictionary<string,object>>(response);

            return retval;
        }
    }
    catch(WebException e)
    {
    }

    return null;
}

这被称为:

public static void Main (string[] args)
{   
    Dictionary<string,object> test = new Dictionary<string, object>();
    test.Add("testing",3);
    test.Add("testing2","4");

    Dictionary<string,object> test2 =  PostRequest("unitytest/",test);          
    Console.WriteLine (test2["testing"]);
}

无论出于何种原因,这是通过的请求对象:

<WSGIRequest
GET:<QueryDict: {}>,
POST:<QueryDict: {u'{"testing":3,"testing2":"4"}': [u'']}>,
COOKIES:{},
META:{'CELERY_LOADER': 'djcelery.loaders.DjangoLoader',
 'CONTENT_LENGTH': '28',
 'CONTENT_TYPE': 'application/json; charset=utf-8',
 'DJANGO_SETTINGS_MODULE': 'settings.local',
 'GATEWAY_INTERFACE': 'CGI/1.1',
 'HISTTIMEFORMAT': '%F %T  ',
 'HTTP_CONNECTION': 'close',
 'LANG': 'en_US.UTF-8',
 'QUERY_STRING': '',
 'REMOTE_ADDR': '127.0.0.1',
 'REMOTE_HOST': '',
 'REQUEST_METHOD': 'POST',
 'RUN_MAIN': 'true',
 'SCRIPT_NAME': u'',
 'SERVER_PORT': '9090',
 'SERVER_PROTOCOL': 'HTTP/1.0',
 'SERVER_SOFTWARE': 'WSGIServer/0.1 Python/2.7.2+',
 'SHELL': '/bin/sh',
 'SHLVL': '1',
 'SSH_TTY': '/dev/pts/0',
 'TERM': 'xterm',
 'TZ': 'UTC',
 'wsgi.errors': <open file '<stderr>', mode 'w' at 0x7f3c30158270>,
 'wsgi.file_wrapper': <class 'django.core.servers.basehttp.FileWrapper'>,
 'wsgi.input': <socket._fileobject object at 0x405b4d0>,
 'wsgi.multiprocess': False,
 'wsgi.multithread': True,
 'wsgi.run_once': False,
 'wsgi.url_scheme': 'http',
 'wsgi.version': (1, 0)}>
[18/Oct/2012 19:30:07] "POST /api/1.0/unitytest/ HTTP/1.0" 200 31

请求中的一些更敏感的数据已被删除,但无关紧要

4

2 回答 2

0

呃,我希望我不要养成回答自己问题的习惯。

因此,以这种方式发布 Json 与普通的表单提交不同。这意味着如果您的服务器端只期望正常的表单提交,它将无法正常工作。C# 代码按预期执行,但仅提交 JSON 字符串作为 POST 正文。虽然这对于验证、清理和处理原始输入的人来说可能很方便,但请记住,如果您使用的是普通的 Web 框架,则必须编写一个替代条件来接受原始字符串。

如果有人知道如何在 C# 中提交包含比字符串哈希图/字典更复杂的对象的表单提交,那么我会支持你的答案并给你很多拥抱。现在,这个老生常谈的废话将不得不做。

于 2012-10-20T02:34:32.763 回答
0

好吧,很久以前,我实现了一个银行应用程序前端,它大量使用 JSON 进行客户端和服务器之间的通信。

这是一种从服务器中查找复杂对象的干净方法,无需进行复杂的清理或原始字符串处理。

关键是在服务器端使用为 ajax 设计的 WebServices,您的 Web 服务器类应如下所示:

[WebService(Namespace = "http://something.cool.com/")]
[ScriptService] // This is part of the magic
public class UserManagerService : WebService
{
    [WebMethod]
    [ScriptMethod] // This is too a part of the magic
    public MyComplexObject MyMethod(MyComplexInput myParameter)
    {
        // Here you make your process, read, write, update the database, sms your boss, send a nuke, or whatever...

        // Return something to your awaiting client
        return new MyComplexObject();
    }

}

现在,在您的客户端,进行设置以使 ASP.NET 以 JSON 格式与您对话,我使用 JQuery 来发出 ajax 请求。

$.ajax({ 
    type: 'POST', 
    url: "UserManagerService.asmx/MyMethod", 
    data: { 
        myParameter:{
            prop1: 90,
            prop2: "Hallo",
            prop3: [1,2,3,4,5],
            prop4: {
                // Use the complexity you need.
            }
        }
    }, 
    contentType: 'application/json; charset=utf-8', 
    dataType: 'json', 
    success: function(response) {
        alert(response.d);
    }
});

ASP 想要作为 ScriptMethod 的结果返回的任何内容都将包含在 response.d 变量中。因此,假设您从服务器返回一个复杂对象,“response.d”是对您的对象的引用,您照常使用点符号访问所有对象成员。

于 2012-10-20T03:54:27.833 回答