9

私のRESTfulWCFSericeでは、URITemplateのパラメーターとしてクラスを渡す必要があります。1つまたは複数の文字列をパラメーターとして渡すことができました。しかし、WCFサービスに渡すフィールドはたくさんあります。そこで、クラスを作成し、すべてのフィールドをプロパティとして追加しました。次に、このクラスを1つのパラメーターとしてURITemplateに渡します。クラスをURITemplateに渡そうとすると、「パスセグメントには文字列型が必要です」というエラーが表示されます。クラスをパラメータとして受け入れません。クラスをパラメータとして渡す方法についてのアイデア。これが私のコードです(inputDataはクラスです)


    [OperationContract]
    [WebGet(UriTemplate = "/InsertData/{param1}")]
    string saveData(inputData param1);
4

2 に答える 2

17

実際には、GET 要求で複合型 (クラス) を渡すことができますが、QueryStringConverter を介して、その使用方法を WCF に「教える」必要があります。ただし、通常、特にサービス内の何かを変更するメソッドでは、これを行うべきではありません (GET は読み取り専用操作に使用する必要があります)。

以下のコードは、GET (カスタム QueryStringConverter を使用) と POST (想定される方法) で複合型を渡す方法の両方を示しています。

public class StackOverflow_6783264
{
    public class InputData
    {
        public string FirstName;
        public string LastName;
    }
    [ServiceContract]
    public interface ITest
    {
        [OperationContract]
        [WebGet(UriTemplate = "/InsertData?param1={param1}")]
        string saveDataGet(InputData param1);
        [OperationContract]
        [WebInvoke(UriTemplate = "/InsertData")]
        string saveDataPost(InputData param1);
    }
    public class Service : ITest
    {
        public string saveDataGet(InputData param1)
        {
            return "Via GET: " + param1.FirstName + " " + param1.LastName;
        }
        public string saveDataPost(InputData param1)
        {
            return "Via POST: " + param1.FirstName + " " + param1.LastName;
        }
    }
    public class MyQueryStringConverter : QueryStringConverter
    {
        public override bool CanConvert(Type type)
        {
            return (type == typeof(InputData)) || base.CanConvert(type);
        }
        public override object ConvertStringToValue(string parameter, Type parameterType)
        {
            if (parameterType == typeof(InputData))
            {
                string[] parts = parameter.Split(',');
                return new InputData { FirstName = parts[0], LastName = parts[1] };
            }
            else
            {
                return base.ConvertStringToValue(parameter, parameterType);
            }
        }
    }
    public class MyWebHttpBehavior : WebHttpBehavior
    {
        protected override QueryStringConverter GetQueryStringConverter(OperationDescription operationDescription)
        {
            return new MyQueryStringConverter();
        }
    }
    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        host.AddServiceEndpoint(typeof(ITest), new WebHttpBinding(), "").Behaviors.Add(new MyWebHttpBehavior());
        host.Open();
        Console.WriteLine("Host opened");

        WebClient client = new WebClient();
        Console.WriteLine(client.DownloadString(baseAddress + "/InsertData?param1=John,Doe"));

        client = new WebClient();
        client.Headers[HttpRequestHeader.ContentType] = "application/json";
        Console.WriteLine(client.UploadString(baseAddress + "/InsertData", "{\"FirstName\":\"John\",\"LastName\":\"Doe\"}"));

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}
于 2011-07-22T02:49:18.227 に答える
5

クラス (データ コントラクト) の受け渡しは、POST または PUT 要求 ( ) でのみ可能WebInvokeです。GET 要求では、それぞれがUriTemplateメソッドのパラメーターにマップされる必要がある単純な型のみが許可されます。

于 2011-07-21T21:52:50.943 に答える