Test WCF Service using postman - wcf

I developed my first WCF Service and I want to test using postman but I keep getting 404 not found error.
I tested it using WCFClient and it was working fine.
My Model
[DataContract]
public class chatbotModel
{
[DataMember]
public System.Guid id { get; set; }
[DataMember]
public string subject { get; set; }
[DataMember]
public Nullable<System.DateTime> date_started { get; set; }
}
My function:
public bool InsertChatBotData(chatbotModel model)
{
using (var chatBotContext = new regacrmEntities())
{
var id = Guid.NewGuid();
var NewchatBot = new a01_chatbot()
{
id = id,
date_entered = model.date_started,
date_modified = model.date_ended,
name = model.subject,
description = model.description
};
chatBotContext.a01_chatbot.Add(NewchatBot);
chatBotContext.SaveChanges();
return true;
}
}
[ServiceContract]
public interface ICrmService
{
[OperationContract]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Xml, UriTemplate = "InsertChatBotData")]
bool InsertChatBotData(chatbotModel model);
}
Postman request:
I added the header:
SOAPAction:http://tempuri.org/ICrmService/InsertChatBotData

This is because you visited the wrong URL, I suggest you enable the help document. Here is a demo:
<endpointBehaviors>
<behavior name="ESEndPointBehavior">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
You need to apply ESEndPointBehavior to the endpoint.
Then you can access the help document in your browser:
The help document includes the requested url, http verb and the requested format.

Related

WCF RESTful Console-hosted, return 400 Bad Request

Studying WCF RESTful, host in a Console,
my steps:
create sample models
create contract of service
create service
host this service in a console.
run this host, looks ok.
create a winform, use service address via json post to service host.
i hope it would work, but return http 400.
I tried on WCF(not REST) Console-hosted, WebAPI, steps all ok.
finally, stackoverflow.com
please help
Models
[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; }
}
Contract
[ServiceContract]
public interface IHotel
{
// Create objct Hotel
[OperationContract]
[WebInvoke(UriTemplate = "", Method = "POST", RequestFormat= WebMessageFormat.Json, ResponseFormat=WebMessageFormat.Json)]
bool Create(Hotel hotel);
}
Service
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;
}
}
Host(Console)
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();
Client(Winform)
Caller
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;
}
Json String for 'bool BuildHotel(string)' upon
{
"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"}
}
it expects such kind of 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}]}
To change it you can mark all your data contracts with DataContract and DataMember attribute:
[DataContract]
public abstract class Building
{
[DataMember]
public Manufacturer Manufacturer { get; set; }
}
In this case it will understand json as you have given us in the question and will process it successfully.

Post object to a WCF method

I am a newbie to both RestSharp and WCF and I am trying to write a working sample that has a post method which takes a string and an object as parameters. I have looked at another post here where someone asked the same question and I still couldn't get it to work. Can someone please point me in the right direction. I debugged the code and I am getting a null in the object. It seems like its pretty straight forward but I am not sure what I am missing. This is what I have so far.
Server side:
[OperationContract]
[Description("addUser")]
[WebInvoke(Method = "POST", UriTemplate = "/addUser?id={id}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
TSCRUResponse addUser(string id, User usr);
public TSCRUResponse addUser(string id, User usr)
{
TSCRUResponse r = new TSCRUResponse();
r.status = id + usr.name + usr.age + usr.gender;
return r;
}
The first parameter for the above method comes through OK but not the object.
These are the objects:
[DataContract]
public class TSCRUResponse
{
[DataMember(Name = "status")]
public string status { get; set; }
}
[DataContract]
public class User
{
[DataMember(Name = "name")]
public string name { get; set; }
[DataMember(Name = "age")]
public string age { get; set; }
[DataMember(Name = "gender")]
public string gender { get; set; }
}
Client side :
public void postmethod(string uri)
{
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate);
RestClient client = new RestClient();
client.BaseUrl = "http://localhost:1119/TestService.svc/";
client.Authenticator = new HttpBasicAuthenticator("username", "password");
RestRequest request = new RestRequest("addUser?id={id}", Method.POST);
request.AddHeader("Accept", "application/json");
request.JsonSerializer = new RestSharp.Serializers.JsonSerializer();
request.RequestFormat = DataFormat.Json;
request.AddParameter("id", "12839", ParameterType.UrlSegment);
User itm = new User { age = "40", name = "user1", gender = "M" };
request.AddBody(itm);
var response = client.Execute<TSCRUResponse>(request);
TSCRUResponse addres = response.Data;
Console.WriteLine(addres.status);
}

WebGet and object as GET parameter in WCF REST client

Let's say we have REST client with next declaration:
[ServiceContract]
interface ITestClient
{
[OperationContract]
[WebGet(UriTemplate = "SetData/?d1={d1}&d2={d2}")]
void SetData(string d1, string d2);
}
I would like tu use it with next signature (HTTP GET):
[ServiceContract]
interface ITestClient
{
[OperationContract]
[WebGet(UriTemplate = "SetData/?")]
void SetData(SetDataRequest setData);
}
[DataContract]
public class SetDataRequest
{
[DataMember(Name = "d1")]
private string Data1 { get; set; }
[DataMember(Name = "d2")]
private string Data2 { get; set; }
}
I wish that WCF serializes instance of the SetDataRequest to HTTP QueryString.
Is this possible (HTTP POST is not acceptable)?
You should not use WebGet for this you should instead do:-
[OperationContract]
[WebInvoke( UriTemplate="SetDate/" Method="POST")]
void SetData(SetDataRequest setData);
You should use a post when submitting data as you will run into security/caching issues if you don't.

Send large JSON data to WCF Rest Service

I have a client web page that is sending a large json object to a proxy service on the same domain as the web page.
The proxy (an ashx handler) then forwards the request to a WCF Rest Service. Using a WebClient object (standard .net object for making a http request)
The JSON successfully arrives at the proxy via a jQuery POST on the client webpage.
However, when the proxy forwards this to the WCF service I get a Bad Request - Error 400
This doesn't happen when the size of the json data is small
The WCF service contract looks like this
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
CarConfiguration CreateConfiguration(CarConfiguration configuration);
And the DataContract like this
[DataContract(Namespace = "")]
public class CarConfiguration
{
[DataMember(Order = 1)]
public int CarConfigurationId { get; set; }
[DataMember(Order = 2)]
public int UserId { get; set; }
[DataMember(Order = 3)]
public string Model { get; set; }
[DataMember(Order = 4)]
public string Colour { get; set; }
[DataMember(Order = 5)]
public string Trim { get; set; }
[DataMember(Order = 6)]
public string ThumbnailByteData { get; set; }
[DataMember(Order = 6)]
public string Wheel { get; set; }
[DataMember(Order = 7)]
public DateTime Date { get; set; }
[DataMember(Order = 8)]
public List<string> Accessories { get; set; }
[DataMember(Order = 9)]
public string Vehicle { get; set; }
[DataMember(Order = 10)]
public Decimal Price { get; set; }
}
When the ThumbnailByteData field is small, all is OK. When it is large I get the 400 error
What are my options here?
I've tried increasing the MaxBytesRecived config setting but that is not enough
Any ideas?
I would also tweak maxStringContentLength and maxBytesPerRead. Also make sure that whatever binding configuration you set up, you're actually using it in all the right places.
This thread captures pretty well all the things that can go wrong when you are dealing with a large string in WCF message input, so I'd follow the guidance here: Sending large strings to a WCF web service

WCF Rest client and Transfer Encoding Chunked: Is it supported?

I have a datacontract as defined below:
[DataContract(Namespace="",Name="community")]
public class Community {
[DataMember(Name="id")]
public int Id{get; set;}
[DataMember(Name="name")]
public string Name { get; set; }
[DataMember(Name="description")]
public string Description { get; set; }
}
and the service contract goes like this:
[OperationContract]
[WebGet(
BodyStyle = WebMessageBodyStyle.Bare,
ResponseFormat = WebMessageFormat.Xml,
UriTemplate = "{id}"
)]
Community GetCommunity(string id);
When I make a rest call to the host, I get data but only Id and Name properties are populated. The Description property is null! I am creating the channel by inheriting from ClientBase.
Does anybody know why WCF serializes Id and Name but not Description? The Transfer Encoding is set to 'Chunked' on the response from the host and I would like to know if that has anything to do with it ?
I found out that some of the properties were not getting serialized because the response xml had the elements in a different order. The solution was to explicitly set serialization order on the datacontract. Here is the datacontract after I added order attribute:
[DataContract(Namespace="",Name="community")]
public class Community
{
[DataMember(Name = "name",Order=2)]
public string Name { get; set; }
[DataMember(Name="id",Order = 1)]
public int Id{get; set;}
[DataMember(Name="description",Order=3)]
public string Description { get; set; }
}