Подключение к службе WCF из Android - получение 405 - Метод не разрешен - PullRequest
3 голосов
/ 24 марта 2011

Я создал службу WCF, которую намереваюсь использовать при отправке данных из приложения Android в базу данных MSSQL.

Сервис уже размещен и содержит 2 метода. Data () и GetData (). Метод Data используется для POST JSON, а GetData просто возвращает строку.

Я пробовал следующее:

Контракт с моими данными:

[OperationContract]
[WebInvoke(Method = "POST",
UriTemplate = "/Data",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped)]
string Data(Data test);

Мой код Android:

HttpPost request = new HttpPost("http://lino.herter.dk/Service.svc/Data");
try {
JSONObject json = new JSONObject();
json.put("year", 2011);
StringEntity entity = new StringEntity(json.toString());

entity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
entity.setContentType( new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
request.setEntity(entity);

DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(request);
Log.i("!!! WebInvoke", response.getStatusLine().toString());

if(response!=null) {
InputStream in = response.getEntity().getContent(); //Get the data in the entity'
Log.i("TEST", convertStreamToString(in));
}

Подобный метод прекрасно работает с GetData .. но вызов метода Data возвращает:

400 Bad Request
The server encountered an error processing the request. The exception message is 'Object reference not set to an instance of an object.'.

Web.Config выглядит так:

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
    <customErrors mode="Off"/>
  </system.web>
  <system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior name="jsonBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    <services>
      <service name="WcfEA.Service">
        <endpoint address="" behaviorConfiguration="jsonBehavior" binding="webHttpBinding" contract="WcfEA.IService" />
      </service>
    </services>
  </system.serviceModel>
</configuration>

Метод данных настроен на получение объекта «Данные»:

[DataContract]
public class Data
{
    [DataMember(Name = "year")]
    public int Year
    {
        get;
        set;
    }
}

и метод Data выполняет только 1 операцию:

return data.year.toString();

Ответы [ 3 ]

1 голос
/ 04 апреля 2011

Разве после <?xml version=\"1.0\"?>?

не должно быть перевода строки. Кроме того, если вам действительно не нужно проверять XML перед отправкой на сервер, предложите просто присоединить объект в виде текста (пропустите тип содержимого xml и т. д.) и выполните синтаксический анализ XML на сервере.

Это потому, что вы всегда в любом случае анализировали бы и проверяли входящие данные на сервере, в противном случае он открываетсяогромные угрозы безопасности.Если вы не хотите сохранить запрос в обоих направлениях, отказавшись от неправильно отформатированного XML-файла, как это ...

Кроме того, вы уверены, что ваш XML-файл находится в допустимом формате XML-запроса SOAP?Поскольку ваш заголовок указывает, что сообщение должно быть SOAP, содержимое должно быть правильно отформатировано в SOAP XML ...

1 голос
/ 04 апреля 2011

Не могли бы вы опубликовать свой web.config от вас c # WCF?Некоторое время я создал сервер WCF, который действует как WebService, и у меня были те же проблемы, и все было связано с настройкой.Помимо конфигурации actakl, если вы размещаете службу WCF с использованием wsHttpBinding по умолчанию, она будет включать аутентификацию Windows.Как вы создаете сервис?

1 голос
/ 24 марта 2011

Когда я делал это в прошлом, я использовал Fiddler2, чтобы определить разницу между отправкой моего тестового приложения .Net в качестве запроса и отправкой моего приложения Android.В заголовках может быть несоответствие, способ упаковки ваших пост-параметров и т. Д. Кроме того, Fiddler2 покажет вам коды ответа и ответа.Это должно дать вам всю информацию, которая вам нужна, чтобы понять это.

http://www.fiddler2.com/fiddler2/

РЕДАКТИРОВАТЬ

После разговора в комментарияхВот обновленный ответ на вопрос, который, по моему мнению, является вашей проблемой.

Мне не удалось найти код для оригинального POC, который я сделал для связи между клиентом Android и службой WCF, но я нашел какой-то другойкод, где я публикую данные JSON.То, что я делаю иначе, чем вы, кажется, я передаю свою полезную нагрузку в виде пары имя / значение, поэтому она становится ключевой, когда она попадает в сервис.Похоже, вы передаете просто необработанную строку данных json, поэтому возможно, что служба ожидает ваши данные json в качестве значения пары имя-значение, для которой указано имя аргумента в вашей службе.

Чтобы перефразировать два подхода, вот метод, который вы используете для передачи необработанных строковых данных в качестве сущности.

JSONObject json = new JSONObject();
json.put("year", 2011);
StringEntity entity = new StringEntity(json.toString());
request.setEntity(entity);

Вот пример моих данных, которые я публикую как NameValuePair

List<NameValuePair> params = new ArrayList<NameValuePair>(1);
params.add(new BasicNameValuePair("SomeKey", someJsonString));
request.setEntity(new UrlEncodedFormEntity(params));

Если вы хотите передать сложный объект, вы можете создать его как строку json, как в моем примере используется выше.ИЛИ ... вы можете просто передать «год» в качестве ключа и «2011» в качестве значения, и это должно быть значение вашей строковой аргументации, когда она попадает в ваш веб-метод WCF.

...