【问题标题】:Connect to a WCF service from Android - getting 405 - Method not allowed从 Android 连接到 WCF 服务 - 获取 405 - 方法不允许
【发布时间】:2011-03-24 10:22:19
【问题描述】:

我创建了一个 WCF 服务,打算在将数据从 Android 应用程序发送到 MSSQL 数据库时使用它。

该服务已托管并包含 2 个方法.. Data() 和 GetData()。 Data 方法用于将 JSON POST 到,GetData 只返回一个字符串。

我尝试了以下方法:

我的数据合同:

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

我的安卓代码:

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>

Data 方法被设置为接收一个“Data”对象:

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

Data 方法只做 1 次操作:

return data.year.toString();

【问题讨论】:

    标签: android wcf data-transfer


    【解决方案1】:

    当我过去这样做时,我使用 Fiddler2 来区分我的 .Net 测试应用程序作为请求发送的内容与我的 Android 应用程序发送的内容之间的区别。标头、post 参数的打包方式等可能存在差异。此外,Fiddler2 将向您显示响应和响应代码。这应该会为您提供解决问题所需的所有信息。

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

    编辑

    在 cmets 中来回发言后,这里是我认为您的问题的更新答案。

    我找不到用于在 Android 客户端和 WCF 服务之间进行通信的原始 POC 的代码,但我确实找到了一些其他代码,用于发布 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 Web 方法时,这应该是字符串 arg 的值。

    【讨论】:

    • 嗨..我已经更改了原始帖子,但您的评论仍然非常有效..但是我如何查看我的 android 应用程序请求什么?提琴手似乎没有抓住它..:/
    • 我不知道有什么方法可以像 Fiddler 在 PC 上工作那样在 Android 设备上捕获数据,但是您可以在 Data 方法中在您的网络服务器上进行某种登录。快速而肮脏的方法是转储值参数并循环通过标头将其转储到字符串。将其写入网络服务器上的文本文件,并设置一个常规的 aspx 页面来读取和输出该文件。来自您的测试应用程序的请求,然后刷新页面。从您的 Android 应用请求并再次刷新。您将能够看到不同请求中的差异。
    • 但我仍然收到错误请求,我不明白为什么.. :/
    • 也许在不应该的地方有一些额外的空白?也许您缺少一些必需的样板文件,例如 声明?不确定。听起来像一个空白的东西。你在检查你所有的 http 请求头吗?
    • 说实话,我真的不知道要检查什么......:/
    【解决方案2】:

    &lt;?xml version=\"1.0\"?&gt;之后不应该有换行吗?

    此外,除非您确实需要在发送到服务器之前验证 XML,否则建议您简单地将实体附加为文本(跳过 xml 内容类型等)并在服务器上解析 XML。

    那是因为您总是无论如何都会解析和验证服务器上的传入数据,否则会带来巨大的安全风险。除非你想通过像这样拒绝格式不正确的 XML 来保存请求往返......

    另外,您确定您的 XML 是有效的 SOAP 请求 XML 格式吗?由于您的标头指示消息是 SOAP,因此内容应该是格式正确的 SOAP XML...

    【讨论】:

    • 嘿..感谢您的回答..我已经更新了原始帖子以反映我的最新代码。
    【解决方案3】:

    你能从你的 c# WCF 发布你的 web.config 吗?有时我创建了一个充当 WebService 的 WCF 服务器,但我遇到了同样的问题,而且都是关于配置的。除了 actuakl 配置,如果您使用 wsHttpBinding 默认托管 WCF 服务,它将启用“Windows”身份验证。您是如何创建服务的?

    【讨论】:

    • Web.Config 和最新代码添加到原始帖子中。
    猜你喜欢
    • 2016-06-13
    • 2011-01-13
    • 2017-10-10
    • 2014-04-27
    • 1970-01-01
    • 2014-07-17
    • 2013-03-15
    • 2012-10-25
    • 2014-03-30
    相关资源
    最近更新 更多