2

WCF RESTful、コンソールでのホスト、

私の手順:

  1. サンプル モデルの作成
  2. サービス契約を作成する
  3. サービスを作成する
  4. このサービスをコンソールでホストします。
  5. このホストを実行すると、問題ないようです。
  6. winform を作成し、サービス ホストへの json post 経由でサービス アドレスを使用します。
  7. うまくいくことを願っていますが、http 400 を返します。

私はWCF(RESTではない)コンソールでホストされたWebAPIを試してみましたが、すべて問題ありませんでした。

最後に、stackoverflow.com

助けてください

モデル

[Serializable]
public abstract class Building
{
    public Manufacturer Manufacturer { get; set; }
}

[Serializable]
public class Manufacturer
{
    public string Name { get; set; }

    public string Telephone { get; set; }
}

[Serializable]
public class Furniture : Building
{
    public string Name { get; set; }
}

[Serializable]
public class Reception
{
    public int Floor { get; set; }

    public int Number { get; set; }
}

[Serializable]
public class Room : Building
{
    public string Number { get; set; }

    public List<Furniture> Furnitures { get; set; }
}

[Serializable]
public class Hotel : Building
{
    public Guid Guid { get; set; }

    public List<Reception> Receptions { get; set; }

    public List<Room> Rooms { get; set; }

    public string Name { get; set; }

    public string Address { get; set; }
} 

契約

[ServiceContract]
public interface IHotel
{
    // Create objct Hotel
    [OperationContract]
    [WebInvoke(UriTemplate = "", Method = "POST", RequestFormat= WebMessageFormat.Json, ResponseFormat=WebMessageFormat.Json)]
    bool Create(Hotel hotel);
}

サービス

public class HotelService : I Hotel
{
    public bool Build(Models.Hotel hotel)
    {
        if (hotel == null)
            return false;

        // codes here is object hotel(EF) creation, test OK
        return true;
    }
}

ホスト (コンソール)

WebServiceHost serviceHost = new WebServiceHost(typeof(Demo.Services.HotelService), new Uri("http://192.168.1.101/HotelService"));
ServiceEndpoint endpoint = serviceHost.AddServiceEndpoint(typeof(Demo.Contracts.IHotel), new WebHttpBinding(), "");
ServiceDebugBehavior sdb = serviceHost.Description.Behaviors.Find<ServiceDebugBehavior>();
sdb.HttpHelpPageEnabled = false;

Console.WriteLine("Starting Service...");
// start service
serviceHost.Open();
Console.WriteLine("Started, press RETURN to exit.");
Console.ReadLine();
serviceHost.Close();

クライアント(Winform)

発信者

public bool BuildHotel(string json)
{
    WebRequest request = HttpWebRequest.Create("http://192.168.1.101/HotelService");

    request.ContentType = "application/json";

    byte[] data = Encoding.UTF8.GetBytes(json);
    request.ContentLength = data.Length;
    Stream requestStream = request.GetRequestStream();
    requestStream.Write(data, 0, data.Length);
    requestStream.Close();

    WebResponse response = request.GetResponse(); // 400 throwed here
    Stream responseStream = response.GetResponseStream();
    StreamReader responseStreamReader = new StreamReader(responseStream);
    string result = responseStreamReader.ReadToEnd();

    return true;
}

「bool BuildHotel(string)」の Json 文字列

{
    "Guid":"ea59c011-d656-4870-b29b-30a44e668560",
    "Receptions":[
        {"Floor":1,"Number":1},
        {"Floor":2,"Number":2}
    ],
    "Rooms":[
        {
            "Number":"c",
            "Furnitures":[
                {"Name":"1","Manufacturer":{"Name":"1","Telephone":"1"}},
                {"Name":"2","Manufacturer":{"Name":"2","Telephone":"2"}}
            ],
            "Manufacturer":{"Name":"c","Telephone":"c"}
        }
    ],
    "Name":"x",
    "Address":"x",
    "Manufacturer":{"Name":"x","Telephone":"x"}
}
4

1 に答える 1

0

次のような種類の JSON が必要です。

{"k_ BackingField":{"k _BackingField":"4","k_ BackingField":"4"}," k_BackingField":"x","k_ BackingField":"ea59c011-d656-4870-b29b-30a44e668560 ","k _BackingField":"x","k_ BackingField":[{"k _BackingField":1,"k_ BackingField":1},{"k _BackingField":2,"k_ BackingField":2}], "k _BackingField":[{"k_ BackingField":{"k _BackingField":"3","k_ BackingField":"3"},"k _BackingField":[{"k_ BackingField":{"k _BackingField":"1","k_ BackingField":"1"},"k _BackingField":"1"},{"k_ BackingField":{"k _BackingField":"2","k_ BackingField":"2"}, "k_BackingField":"2"}],"k__BackingField":null}]}

これを変更するには、すべてのデータ コントラクトを DataContract および DataMember 属性でマークします。

    [DataContract]
    public abstract class Building
    {
        [DataMember]
        public Manufacturer Manufacturer { get; set; }
    }

この場合、質問で提供されたようにjsonを理解し、正常に処理します。

于 2014-04-12T11:15:19.390 に答える