3

WCF Rest サービス メソッドのパラメータが常に null なのはなぜですか?...サービスのメソッドにアクセスし、wcf メソッドによって返された文字列を取得しますが、パラメータは null のままです。

運営契約:

  [OperationContract]
    [WebInvoke(UriTemplate = "AddNewLocation",
        Method="POST",
        BodyStyle = WebMessageBodyStyle.WrappedRequest,
        ResponseFormat = WebMessageFormat.Json,
        RequestFormat = WebMessageFormat.Json)]
    string AddNewLocation(NearByAttractions newLocation);

AddNewLocation メソッドの実装

 public string AddNewLocation(NearByAttractions newLocation)
    {
        if (newLocation == null)
        {
            //I'm always getting this text in my logfile
            Log.Write("In add new location:- Is Null");
        }
        else
        {
            Log.Write("In add new location:- " );
        }

        //String is returned even though parameter is null
        return "59";
    }

クライアントコード:

        WebClient clientNewLocation = new WebClient();
        clientNewLocation.Headers[HttpRequestHeader.ContentType] = "application/json";

        JavaScriptSerializer js = new JavaScriptSerializer();
        js.MaxJsonLength = Int32.MaxValue;

        //Serialising location object to JSON
        string serialLocation = js.Serialize(newLocation);

        //uploading JSOn string and retrieve location's ID
        string jsonLocationID = clientNewLocation.UploadString(GetURL() + "AddNewLocation", serialLocation);

クライアントでもこのコードを試しましたが、まだ null パラメータを取得しています

            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(NearByAttractions));

        MemoryStream ms = new MemoryStream();
        ser.WriteObject(ms, newLocation);

        String json = Encoding.UTF8.GetString(ms.ToArray());


        WebClient clientNewLocation = new WebClient();
        clientNewLocation.Headers[HttpRequestHeader.ContentType] = "application/json";

        string r = clientNewLocation.UploadString(GetURL() + "AddNewLocation", json);

        Console.Write(r);

次に、BodyStyleオプションを「Bare」に変更しましたが、次のエラーが発生しました(両方のクライアントコードで):

リモート サーバーがエラーを返しました: (400) 不正な要求。

何か助けてください。ありがとう

編集 1: 私の GetUrl() メソッドは、Web 構成ファイルから Web サービスの IP アドレスを読み込み、Uri 型のオブジェクトを返します。

private static Uri GetURL()
    {
        Configuration config = WebConfigurationManager.OpenWebConfiguration("~/web.config");

        string sURL = config.AppSettings.Settings["serviceURL"].Value;
        Uri url = null;

        try
        {
            url = new Uri(sURL);
        }
        catch (UriFormatException ufe)
        {
            Log.Write(ufe.Message);
        }
        catch (ArgumentNullException ane)
        {
            Log.Write(ane.Message);
        }
        catch (Exception ex)
        {
            Log.Write(ex.Message);
        }

        return url;
    }

次のように Web 構成に保存されているサービス アドレス:

<appSettings>
    <add key="serviceURL" value="http://192.168.2.123:55666/TTWebService.svc/"/>
  </appSettings>

これが私の NearByAttraction クラスの定義方法です

 [DataContractAttribute]
public class NearByAttractions
{


    [DataMemberAttribute(Name = "ID")]
    private int _ID;
    public int ID
    {
        get { return _ID; }
        set { _ID = value; }
    }



    [DataMemberAttribute(Name = "Latitude")]
    private string _Latitude;
    public string Latitude
    {
        get { return _Latitude; }
        set { _Latitude = value; }
    }


     [DataMemberAttribute(Name = "Longitude")]
    private string _Longitude;
    public string Longitude
    {
        get { return _Longitude; }
        set { _Longitude = value; }
    }
4

2 に答える 2

4

あなたは正しい軌道に乗っているようです。body スタイルが必要Bareです。それ以外の場合は、シリアル化されたバージョンの入力を別の JSON オブジェクトでラップする必要があります。2 番目のコードは機能するはずですが、サービスのセットアップ方法やGetURL()戻り値に関する詳細情報がなければ、推測するしかありません。

WCF REST サービスに何を送信するかを確認する 1 つの方法は、WCF クライアント自体をWebChannelFactory<T>使用することです。クラスを使用してから、Fiddler などのツールを使用して送信内容を確認します。以下の例は、シナリオの動作を示すSSCCEです。

public class StackOverflow_15786448
{
    [ServiceContract]
    public interface ITest
    {
        [OperationContract]
        [WebInvoke(UriTemplate = "AddNewLocation",
            Method = "POST",
            BodyStyle = WebMessageBodyStyle.Bare,
            ResponseFormat = WebMessageFormat.Json,
            RequestFormat = WebMessageFormat.Json)]
        string AddNewLocation(NearByAttractions newLocation);
    }
    public class NearByAttractions
    {
        public double Lat { get; set; }
        public double Lng { get; set; }
        public string Name { get; set; }
    }
    public class Service : ITest
    {
        public string AddNewLocation(NearByAttractions newLocation)
        {
            if (newLocation == null)
            {
                //I'm always getting this text in my logfile
                Console.WriteLine("In add new location:- Is Null");
            }
            else
            {
                Console.WriteLine("In add new location:- ");
            }

            //String is returned even though parameter is null
            return "59";
        }
    }
    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        WebServiceHost host = new WebServiceHost(typeof(Service), new Uri(baseAddress));
        host.Open();
        Console.WriteLine("Host opened");

        Console.WriteLine("Using WCF-based client (WebChannelFactory)");
        var factory = new WebChannelFactory<ITest>(new Uri(baseAddress));
        var proxy = factory.CreateChannel();
        var newLocation = new NearByAttractions { Lat = 12, Lng = -34, Name = "56" };
        Console.WriteLine(proxy.AddNewLocation(newLocation));

        Console.WriteLine();
        Console.WriteLine("Now with WebClient");

        DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(NearByAttractions));
        MemoryStream ms = new MemoryStream();
        ser.WriteObject(ms, newLocation);

        String json = Encoding.UTF8.GetString(ms.ToArray());

        WebClient clientNewLocation = new WebClient();
        clientNewLocation.Headers[HttpRequestHeader.ContentType] = "application/json";

        string r = clientNewLocation.UploadString(baseAddress + "/AddNewLocation", json);

        Console.WriteLine(r);
    }
}
于 2013-04-03T16:17:35.130 に答える
3

解決しました、ありがとうございます

BodyStyle を「Bare」に変更したので、サービス インターフェイスは次のようになります。

  [OperationContract]
    [WebInvoke(UriTemplate = "AddNewLocation",
        Method="POST",
        BodyStyle = WebMessageBodyStyle.Bare,
        ResponseFormat = WebMessageFormat.Json,
        RequestFormat = WebMessageFormat.Json)]
    string AddNewLocation(NearByAttractions newLocation);

次に、クライアントを次のように実装しました。

MemoryStream ms = new MemoryStream();

        DataContractJsonSerializer serialToUpload = new DataContractJsonSerializer(typeof(NearByAttractions));
        serialToUpload.WriteObject(ms, newLocation);


        WebClient client = new WebClient();
        client.Headers.Add(HttpRequestHeader.ContentType, "application/json");

        client.UploadData(GetURL() + "AddNewLocation", "POST", ms.ToArray());

UploadString の代わりに WebClient.UploadData を使用しました。

于 2013-04-04T12:26:41.980 に答える