muratkazanova
asked on
How to pass complex object as a parameter to WCF Rest from Windows form application.
Hi;
I would like to pass a basic Employee class to WCF Rest service via POST method. I've ALREADY achieved this by using the WCF REST Starter Kit's HTTPClient and Extension libraries.
My service script is:
<%@ServiceHost language="C#" Debug="true" Service="restfirst.first" Factory="System.ServiceMod el.Activat ion.WebSer viceHostFa ctory" %>
The class i would like pass is:
My interface looks like this:
Implementation is:
and here is the my web config's wcf section:
Ok, so if make the call from windows form button click action as its listed below the current implementation for AddEntityOld work fine with Stream work fine:
FINALLY, what i'm trying to achieve here is, passing Employee emp as a parameter to AddEntityOld method instead of using Stream emp as a parameter and its implementation recieve the passed Employee object's properties with WebRequest Call.
Thank you for your help in advance
I would like to pass a basic Employee class to WCF Rest service via POST method. I've ALREADY achieved this by using the WCF REST Starter Kit's HTTPClient and Extension libraries.
My service script is:
<%@ServiceHost language="C#" Debug="true" Service="restfirst.first" Factory="System.ServiceMod
The class i would like pass is:
namespace UtilityClasses
{
[DataContract]
public class Employee
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
public static List<Employee> getEmployeeList()
{
var xdoc = XDocument.Load(HttpContext.Current.Server.MapPath("~/Employee/Employee.xml"));
return (from e in xdoc.Descendants("Employee")
select new Employee
{
Id = Convert.ToInt32(e.Element("Id").Value),
Name = e.Element("Name").Value
}).ToList<Employee>();
}
public static string addNew(int Id, string Name)
{
string returnValue = string.Empty;
try
{
var xdoc = XDocument.Load(HttpContext.Current.Server.MapPath("~/Employee/Employee.xml"));
xdoc.Root.Add(new XElement("Employee",
new XElement("Id", Id),
new XElement("Name", Name)
));
xdoc.Save(HttpContext.Current.Server.MapPath("~/Employee/Employee.xml"));
returnValue = "Done!";
}
catch (Exception ex)
{
returnValue = ex.Message.ToString();
}
return returnValue;
}
}
}
My interface looks like this:
[ServiceContract]
public interface Ifirst
{
[OperationContract]
[WebGet(UriTemplate = "Employee/{Id}")]
List<Employee> getEmployeesById(string Id);
[WebInvoke(UriTemplate = "Employee/Add")]
Employee addNew(Employee emp);
[WebInvoke(UriTemplate = "Employee/AddOld",BodyStyle=WebMessageBodyStyle.WrappedRequest, RequestFormat=WebMessageFormat.Xml)]
string addNewOld(Stream Id);
[WebInvoke(Method="POST", UriTemplate = "Employee/AddEntityOld",BodyStyle=WebMessageBodyStyle.Bare, RequestFormat=WebMessageFormat.Xml)]
string addNewEntityOld(Stream emp);
Implementation is:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class first : Ifirst
{
public List<Employee> getEmployeesById(string Id)
{
int id = Convert.ToInt32(Id);
var emplist = Employee.getEmployeeList();
var filtered = (from e in emplist
where e.Id == id
select e).ToList<Employee>();
return filtered;
}
public Employee addNew(Employee emp)
{
Employee returnValue = null;
try
{
string result = Employee.addNew(emp.Id, emp.Name);
if (result.StartsWith("Done"))
returnValue = emp;
}
catch (Exception ex)
{
returnValue = null;
}
return returnValue;
}
public string addNewOld(Stream id)
{
string returnValue = string.Empty;
StreamReader sr = new StreamReader(id);
string res = sr.ReadToEnd();
return res;
System.Collections.Specialized.NameValueCollection coll = HttpUtility.ParseQueryString(res);
return string.Format("{0} {1}", coll["Id"], "");
}
public string addNewEntityOld(Stream emp)
{
try
{
XmlSerializer xs = new XmlSerializer(typeof(Employee));
Employee e = (Employee)xs.Deserialize(emp);
return string.Format("{0} {1}", e.Id, e.Name);
}
catch (Exception ex)
{
return ex.Message.ToString();
}
}
}
and here is the my web config's wcf section:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="True" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
Ok, so if make the call from windows form button click action as its listed below the current implementation for AddEntityOld work fine with Stream work fine:
string endPoint = "http://localhost:1212/first.svc/Employee/AddEntityOld";
var request = (HttpWebRequest)WebRequest.Create(endPoint);
var populatedEndPoint = new Employee() { Id = 99, Name = "Still testing..." };
XmlSerializer xs = new XmlSerializer(populatedEndPoint.GetType());
MemoryStream ms = new MemoryStream();
xs.Serialize(ms, populatedEndPoint);
byte[] bytes = ms.ToArray();
request.Method = "POST";
request.ContentType = "test/xml";
request.ContentLength = bytes.Length;
var requestStream = request.GetRequestStream();
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Close();
using (var responsex = (HttpWebResponse)request.GetResponse())
{
string s = new System.IO.StreamReader(responsex.GetResponseStream()).ReadToEnd();
MessageBox.Show(s);
if (responsex.StatusCode != HttpStatusCode.OK)
{
string message = String.Format("POST failed. Received HTTP {0}", responsex.StatusCode);
throw new ApplicationException(message);
}
}
FINALLY, what i'm trying to achieve here is, passing Employee emp as a parameter to AddEntityOld method instead of using Stream emp as a parameter and its implementation recieve the passed Employee object's properties with WebRequest Call.
[WebInvoke(Method = "POST", UriTemplate = "Employee/AddEntityOld2", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Xml)]
string addNewEntityOld(Employee emp);
Thank you for your help in advance
ASKER
In my recent attempt i used DataContractSerializer but still getting 400 Bad Request from server
string endPoint = "http://localhost:1212/first.svc/Employee/AddEntityOld";
var request = (HttpWebRequest)WebRequest.Create(endPoint);
var populatedEndPoint = new Employee() { Id = 99, Name = "Still testing..." };
DataContractSerializer ser = new DataContractSerializer(typeof(Employee));
MemoryStream ms = new MemoryStream();
ser.WriteObject(ms, emp);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
//request.ContentType = "test/html";
request.ContentLength = ms.Length;
var requestStream = request.GetRequestStream();
requestStream.Write(ms.ToArray(), 0, (int)ms.Length);
requestStream.Close();
using (var responsex = (HttpWebResponse)request.GetResponse())
{
string s = new System.IO.StreamReader(responsex.GetResponseStream()).ReadToEnd();
MessageBox.Show(s);
if (responsex.StatusCode != HttpStatusCode.OK)
{
string message = String.Format("POST failed. Received HTTP {0}", responsex.StatusCode);
throw new ApplicationException(message);
}
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER