Вызов веб-службы 400 Ошибка неверного запроса

Я пытаюсь вызвать веб-сервис в своем приложении С# ASP.Net MVC3. Это исходный код:

public string getCourseSchedule()
{
    string url = "http://192.168.1.198:15014/ShoppingCart2/CourseSchedule";
    string data = "Months&StatesMX&Zip=&Miles=&ProgramCodes=&EventCode=&PaginationStart=1&PaginationLimit=3";
    byte[] bytes          = Encoding.UTF8.GetBytes(data);
    var myReq             = (HttpWebRequest)WebRequest.Create(url);
    myReq.Method          = "POST";
    myReq.ContentLength   = data.Length;
    myReq.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
    string responseString = "";

    using (Stream requestStream = myReq.GetRequestStream())
    {
        requestStream.Write(bytes, 0, bytes.Length);
    }

    using (HttpWebResponse response = (HttpWebResponse)myReq.GetResponse())
    {
        HttpStatusCode statusCode = response.StatusCode;
        if (statusCode == HttpStatusCode.OK)
        {
            responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
        }
    }
    return responseString;
}

Код возвращает ошибку «400 Bad Request». Вот как я делаю это в javascript, и это работает.

Mexico_Schedule: {"Months": null,
                  "States": [{"State: "MX"}],
                  "Zip": "",
                  "Miles": "",
                  "ProgramCodes": null,
                  "EventCode": null
                  "PaginationStart": 1,
                  "PaginationLimit": 3
};

$.ajax({
    async:       true,
    cache:       false,
    type:        'POST',
    contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
    url:         "http://192.168.1.198:15014/ShoppingCart2/CourseSchedule",
    data:        JSON.stringify(Mexico_Schedule),
    dataType:    'json',
    success: function (data) {
        console.log('Fired when the request is successful');
        // Do something with results
    }
});

Какие изменения мне нужно внести, чтобы версия C# заработала?


person MB34    schedule 10.09.2013    source источник
comment
Это вряд ли сработает в javascript. Вы указали contentType: 'application/x-www-form-urlencoded; и отправляете полезные данные запроса JSON. Или, может быть, веб-сервис, который вы пытаетесь вызвать, не уважает или не заботится о каких-либо стандартах протокола HTTP?   -  person Darin Dimitrov    schedule 11.09.2013
comment
Извините, но это работает.   -  person MB34    schedule 11.09.2013
comment
О, тогда веб-сервис, который вы вызываете, чертовски дерьмовый. Я имею в виду, что вы устанавливаете тип контента application/x-www-form-urlencoded и отправляете полезную нагрузку application/json, и это работает? WTF человек, вы можете сообщить об ошибке авторам этого дерьма. Я даже не могу поверить, что люди до сих пор пишут такую ​​чушь и публикуют ее для публики.   -  person Darin Dimitrov    schedule 11.09.2013
comment
Если вы не можете быть вежливым, не отвечайте, черт возьми.   -  person MB34    schedule 11.09.2013
comment
Нет, я просто высказываю свое мнение, и все.   -  person Darin Dimitrov    schedule 11.09.2013
comment
Если я установлю его на application/json, он вернет запрос 400 Bad.   -  person MB34    schedule 11.09.2013
comment
ВАУ, это еще хуже :-) Указание правильного типа контента в этом случае не работает. Вы уверены, что хотите и дальше называть это (как вы это называете?) service? Я говорю о версии javascript здесь.   -  person Darin Dimitrov    schedule 11.09.2013
comment
Пожалуйста, вынесите свои МНЕНИЯ в другое место, здесь они не нужны.   -  person MB34    schedule 11.09.2013
comment
Это версия javascript, которую вы указали contentType: 'application/json', не работает? Может быть, я неправильно вас понял. Если вы указали этот тип контента в своей версии C#, убедитесь, что вы закодировали JSON полезные данные запроса с помощью сериализатора JSON. Но опять же, если вы говорите, что настройка contentType: 'application/json' в вашей версии javascript не работает, то мой комментарий о дрянности этого сервиса полностью остается в силе.   -  person Darin Dimitrov    schedule 11.09.2013


Ответы (3)


Просто сформируйте свой data (используя Json.Net) как:

var obj = new
{
    States = new[] { new{ State = "MX" } },
    Zip = "",
    Miles = "",
    PaginationStart = 1,
    PaginationLimit = 3
};

string data = JsonConvert.SerializeObject(obj);
person I4V    schedule 10.09.2013
comment
Ошибки: Инициализаторы массива можно использовать только в инициализаторе переменной или поля. Вместо этого попробуйте использовать новое выражение. и Имя «Штат» не существует в текущем контексте. - person MB34; 11.09.2013
comment
@ MB34 Я обновил ответ, добавив маленькую new. Попробуйте еще раз, я проверял. - person I4V; 11.09.2013

Я лучше попытаюсь упростить ваш код, используя WebClient и JSON serializer:

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

В качестве альтернативы, если вы не хотите использовать встроенный класс .NET JavaScriptSerializer, вы можете использовать сторонний класс, например JSON.NET:

string json = JsonConvert.SerializeObject(new
{
    States = new[] { new { State = "MX" } },
    Zip = "",
    Miles = "",
    PaginationStart = 1,
    PaginationLimit = 3
});
person Darin Dimitrov    schedule 10.09.2013
comment
Mexico_Schedule — это имя переменной. Не часть json. - person I4V; 11.09.2013
comment
Дарин, см. мой новый вопрос, пожалуйста. - person MB34; 11.09.2013
comment
Какой новый вопрос вы имеете в виду более конкретно? - person Darin Dimitrov; 11.09.2013

Вы указываете неправильный тип контента. Вы публикуете данные в формате x-www-form-urlencoded, но устанавливаете для типа контента значение «application/json», чтобы ваши данные соответствовали типу вашего контента, или наоборот.

person jlew    schedule 10.09.2013
comment
В Ajax это работает именно так. Если я установлю его на application/json, он сделает то же самое. - person MB34; 11.09.2013