POST request to the WCF service by the use of HttpWebRequest - wcf

My Service Contract
[ServiceContract]
public interface ITsdxService
{
[OperationContract]
[WebGet(UriTemplate="/GetTestCostCentre")]
CostCentre GetTestCostCentre();
[OperationContract]
[WebInvoke(UriTemplate="/SetCostCentre", Method="POST")]
string SetCostCentre(CostCentre cc);
}
public class TsdxService : ITsdxService
{
public CostCentre GetTestCostCentre()
{
CostCentre cc = new CostCentre();
cc.Code = "Test";
cc.Name = "Test Cost Centre";
cc.Description = new byte[] { 12, 34, 89, 240, 66, 87, 189 };
cc.SAPStatus = "Existent";
cc.SAPSiteFolder = "Folder1";
return cc;
}
public string SetCostCentre(CostCentre cc)
{
return cc.Code;
}
}
Then I start this service and try to work with it from different application:
Uri requestUri = new Uri(textBox1.Text + "/tsdx/GetTestCostCentre");
HttpWebRequest request = WebRequest.Create(requestUri) as HttpWebRequest;
XElement root;
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(response.GetResponseStream());
root = XElement.Parse(reader.ReadToEnd());
textBox2.Text = root.ToString();
}
All is ok, I am getting the xml document. But I've faced with problem when I tried to send POST request to this service:
Uri requestUri = new Uri(textBox1.Text + "/tsdx/SetCostCentre");
HttpWebRequest request = WebRequest.Create(requestUri) as HttpWebRequest;
byte[] bytes = Encoding.UTF8.GetBytes(textBox2.Text);
request.ContentLength = bytes.Length;
request.Method = "POST";
Stream dataStream = request.GetRequestStream();
dataStream.Write(bytes, 0, bytes.Length);
dataStream.Close();
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(response.GetResponseStream());
textBox2.Text = reader.ReadToEnd();
}
Exception: The remote server returned an error: (400) Bad Request.
What I did wrong?

Change your client code like this
byte[] bytes = Encoding.UTF8.GetBytes(#"<CostCentre xmlns=""http://schemas.datacontract.org/2004/07/WCF_BadRequestService"">
<Code>String content</Code>
<Description>QmFzZSA2NCBTdHJlYW0=</Description>
<Name>String content</Name>
<SAPSiteFolder>String content</SAPSiteFolder>
<SAPStatus>String content</SAPStatus>
</CostCentre>");
request.ContentLength = bytes.Length;
request.Method = "POST";
request.ContentType = "application/xml";
Now it's fine.
And also i think Java supports WCF BasicHttpBinding, and you can use WCF services using the Java provided tools to generate web-service proxy in an easy supported manner.

Another thing you might want to do is to extend ClientBase to do all the hard work of serializing xml for you. Especially if you want to support more than one message format like json it will make your life a lot easier plus it will make any changes to the interface compile time errors instead of runtime errors.
public class ITsdxServiceProxy : ClientBase<ITsdxService>, ITsdxService {
#region ITsdxService Members
public CostCentre GetTestCostCentre() {
return Channel.GetTestCostCentre();
}
public string SetCostCentre(CostCentre cc) {
return Channel.SetCostCentre(cc);
}
#endregion
}
usage on client side
var proxy = new ITsdxServiceProxy();
var costCenter = proxy.GetTestCostCentre();
Configuration on client side
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint
address="Root address for rest service"
binding="webHttpBinding"
behaviorConfiguration="web"
contract="FullyQualifiedNameOfInterface.ITsdxService">
</endpoint>
</client>
</system.serviceModel>

Related

WCF Timeout exception on streaming big files

I'm currently working on a WCF streaming service. So far everything works great for files up to 2 GB. I've set up the service as a streaming service and I am chunking the files on my own on 5 MB chunks. However, files bigger than 2 GB (somewhere there is the threshold) i always get an InvalidOperationExceptionwith the message Timeouts are not supported on this stream. I'm not really sure why and where this exception is thrown. It don't think this is a server side problem because every request should be the same and most of them work. But the exceptions comes from the generated proxy. So the source is System.Private.ServiceModel
Stack trace:
at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.End(SendAsyncResult result)
at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
at System.ServiceModel.Channels.ServiceChannelProxy.TaskCreator.<>c__DisplayClass0.<CreateGenericTask>b__1(IAsyncResult asyncResult)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Company.OurApp.App.DataService.BaseFile.<DownloadItem>d__59.MoveNext()
Here is my server implementaion:
var response = new GetFileResponse();
using (var impersonation = new Impersonation(request.Domain, request.Username, request.Password))
{
using (Stream fStream = File.OpenRead(request.FullFilePath))
{
fStream.Seek(request.FilePart * request.FilePartSize, SeekOrigin.Begin);
BinaryReader bStream = new BinaryReader(fStream);
var filePart = bStream.ReadBytes(request.FilePartSize);
using (Stream mStream = new MemoryStream(filePart))
{
response.FileByteStream = mStream;
return response;
}
}
}
The GetFileResponse looks like this:
[MessageContract]
public class GetFileResponse
{
[MessageBodyMember(Order = 1)]
public Stream FileByteStream { get; set; }
}
This is how the client handles the download (UWP App):
using (Stream f = await StorageFile.OpenStreamForWriteAsync())
{
//Cancelation area - after every async operation if possilble
for (int i = 0; i < sections; i++)
{
token.ThrowIfCancellationRequested();
var response = await client.GetFilePartAsync(request.ConnectionPassword, request.Domain, i, FilePartSize, FullPath, request.Password, request.Username);
token.ThrowIfCancellationRequested();
DownloadProgress = response.FileByteStream.Length;
f.Seek(0, SeekOrigin.End);
await f.WriteAsync(response.FileByteStream, 0, response.FileByteStream.Length);
await f.FlushAsync();
}
}
And here is the service web.config:
<system.serviceModel>
<services>
<service behaviorConfiguration="HttpsServiceBehaviour"
name="Company.OurApp.TransportService.DataService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="streamedBinding" contract="Company.OurAppTransportService.IDataService">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="HttpsServiceBehaviour">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="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>
<bindings>
<basicHttpBinding>
<binding name="streamedBinding" transferMode="Streamed" closeTimeout="10:00:00">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
When generating the client proxy, i set some timeouts but that didn't change anything:
public DataServiceClient GetDataServiceClient(string endpoint = null)
{
var useEndpoint = String.IsNullOrEmpty(endpoint) ? Configuration.ConfigService : endpoint;
System.ServiceModel.BasicHttpBinding result = new System.ServiceModel.BasicHttpBinding();
result.MaxBufferSize = int.MaxValue;
result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
result.MaxReceivedMessageSize = int.MaxValue;
result.AllowCookies = true;
result.Security.Transport.ClientCredentialType = System.ServiceModel.HttpClientCredentialType.Windows;
//TODO Try to work with timeouts for larges files?
result.SendTimeout = TimeSpan.FromMinutes(5);
result.ReceiveTimeout = TimeSpan.FromMinutes(5);
result.OpenTimeout = TimeSpan.MaxValue;
if (useEndpoint.ToLower().StartsWith("https://"))
result.Security.Mode = System.ServiceModel.BasicHttpSecurityMode.Transport;
else
result.Security.Mode = System.ServiceModel.BasicHttpSecurityMode.TransportCredentialOnly;
var client = new DataServiceClient(result, new System.ServiceModel.EndpointAddress(String.Concat(useEndpoint, fixedEndpointSuffix)));
client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
if (AppState.IsLoggedIn)
{
client.ClientCredentials.Windows.ClientCredential.UserName = $#"{AppState.Domain}\{AppState.User}";
client.ClientCredentials.Windows.ClientCredential.Password = AppState.Password;
}
return client;
}
Any idea where and why the exception is thrown? Server? Client? Is it coming from the stream? Help is very much appreciated.
For everybody else facing the same problem. I got it solved by analyzing the exceptions with the WCF TraceViewer. I also called the Service from a console application to be sure it's not a UWP problem. The problem was that I closed the streams before the response could reach the client.
Broken implementation:
var response = new GetFileResponse();
using (var impersonation = new Impersonation(request.Domain, request.Username, request.Password))
{
using (Stream fStream = File.OpenRead(request.FullFilePath))
{
fStream.Seek(request.FilePart * request.FilePartSize, SeekOrigin.Begin);
BinaryReader bStream = new BinaryReader(fStream);
var filePart = bStream.ReadBytes(request.FilePartSize);
using (Stream mStream = new MemoryStream(filePart))
{
response.FileByteStream = mStream;
return response;
}
}
}
This one fixed it for me:
Stream fStream = File.OpenRead(request.FullFilePath);
long offset = request.FilePart * request.FilePartSize;
fStream.Seek(offset, SeekOrigin.Begin);
BinaryReader bStream = new BinaryReader(fStream);
var filePart = bStream.ReadBytes((int)request.FilePartSize);
Stream mStream = new MemoryStream(filePart);
response.FileByteStream = mStream;
return response;
Hope it helps!

Could not upload Image to WCF Rest service

I am creating a WCF Rest Service to Upload Images from Mobile application. but i am getting
The remote server returned an error: (400) Bad Request. can any one point me what i have done wrong.
Following are my Definitions :
[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "/PostImage",Method ="POST")]
PublicMessage PostImage(Upload obj);
[DataContract]
public class Upload
{
[DataMember]
public Stream File { get; set; }
}
Service Definition :
public PublicMessage PostImage(Upload obj)
{
byte[] buffer = StreamToByte(obj.File); //Function to convert the stream to byte array
FileStream fs = new FileStream(#"D:\ShopMonkeyApp\Desert.jpg", FileMode.Create, FileAccess.ReadWrite);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(buffer);
bw.Close();
return new PublicMessage { Message = "Recieved the image on server" };
}
Client Application :
string filePath = #"D:\ShopMonkeyApp\Desert.jpg";
string url = "http://localhost:50268/shopmonkey.svc/PostImage/"; // Service Hosted in IIS
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Accept = "text/xml";
request.Method = "POST";
request.ContentType = "image/jpeg";
using (Stream fileStream = File.OpenRead(filePath))
using (Stream requestStream = request.GetRequestStream())
{
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int byteCount = 0;
while ((byteCount = fileStream.Read(buffer, 0, bufferSize)) > 0)
{
requestStream.Write(buffer, 0, byteCount);
}
}
string result;
using (WebResponse response = request.GetResponse())
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
result = reader.ReadToEnd();
}
Console.WriteLine(result);
Web Config :
<system.serviceModel>
<services>
<service name="ShopMonkey.ShopMonkey" behaviorConfiguration="ServiceBehaviour">
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address ="" binding="webHttpBinding" contract="ShopMonkey.IShopMonkey" behaviorConfiguration="web">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.behaviorConfiguration="web"
-->
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehaviour">
<!-- 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="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
<dataContractSerializer maxItemsInObjectGraph="10000000"/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
Thanks
Vijay
Increasing the message queue length in web.config solves my issue.
<webHttpBinding>
<binding name="streamWebHttpbinding" transferMode="Streamed" maxReceivedMessageSize="1000000000000" receiveTimeout="01:00:00" sendTimeout="01:00:00" />
</webHttpBinding>
Thanks to all
If you dont have any other properties on the Upload class then change the WCF service method to have a Stream param rather than wrapping it in a class as below:
[OperationContract]
[WebInvoke(UriTemplate = "/PostImage",Method ="POST")]
PublicMessage PostImage(Stream obj);
Then you can use the WebClient class to upload a file directly as shown below:
var c = new System.Net.WebClient();
c.OpenWrite(string.Concat("http://localhost:50268/shopmonkey.svc", "/PostImage"), "POST");
c.Headers[HttpRequestHeader.ContentType] = "image/jpeg";
return c.UploadFile(string.Concat(serviceBaseUrl, resourceUrl), filePath);
Also refer to this link.
UPDATE :
Please find the sample to get your code working below:
[OperationContract]
[WebInvoke(UriTemplate = "/PostImage",Method ="POST")]
PublicMessage PostImage(Upload obj);
[DataContract]
public class Upload
{
[DataMember]
public MemoryStream FileContent { get; set; }
}
Now your method that implements the PostImage looks as follows:
public PublicMessage PostImage(Upload obj)
{
byte[] buffer = new byte[obj.FileContent.Length];
using (FileStream ms = new FileStream(#"D:\ShopMonkeyApp\Temp\Desert.jpg", FileMode.OpenOrCreate))
{
obj.FileContent.Position = 0;
int read = fileInfo.Content.Read(buffer, 0, buffer.Length);
ms.Write(buffer, 0, read);
}
return new PublicMessage { Message = "Recieved the image on server" };
}
Now since our server side code is complete now moving to the client side part that uploads your file to the server as below:
private string ClientSample()
{
var uploadObject = new Upload();
Image image = Image.FromFile(#"D:\ShopMonkeyApp\Desert.jpg");
MemoryStream ms = new MemoryStream();
uploadObject.FileContent = new MemoryStream();
image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
ms.WriteTo(uploadObject.FileContent);
ms.Close();
string responseMessage = null;
var request = WebRequest.Create(http://localhost:50268/shopmonkey.svc/PostImage) as HttpWebRequest;
if (request != null)
{
request.ContentType = "application/xml";
request.Method = method;
}
if(method == "POST" && requestBody != null)
{
byte[] requestBodyBytes;
requestBodyBytes = ToByteArrayUsingDataContractSer<Upload>(requestBody);
request.ContentLength = requestBodyBytes.Length;
using (Stream postStream = request.GetRequestStream())
postStream.Write(requestBodyBytes, 0, requestBodyBytes.Length);
}
if (request != null)
{
var response = request.GetResponse() as HttpWebResponse;
if(response.StatusCode == HttpStatusCode.OK)
{
Stream responseStream = response.GetResponseStream();
if (responseStream != null)
{
var reader = new StreamReader(responseStream);
responseMessage = reader.ReadToEnd();
}
}
else
{
responseMessage = response.StatusDescription;
}
}
}
private static byte[] ToByteArrayUsingDataContractSer<T>(T requestBody)
{
byte[] bytes = null;
var serializer1 = new DataContractSerializer(typeof(T));
var ms1 = new MemoryStream();
serializer1.WriteObject(ms1, requestBody);
ms1.Position = 0;
var reader = new StreamReader(ms1);
bytes = ms1.ToArray();
return bytes;
}
NOTE: Make sure that your Upload object both on the client and server have the same namespace and properties defined so that you avoid any deserialization issues.

dispatchOperation.Formatter NULL when call soap service

I have IDispatchMessageFormatter implementation
class ServerMessageFormatter : IDispatchMessageFormatter
{
private IDispatchMessageFormatter Formatter;
public ServerMessageFormatter(IDispatchMessageFormatter formatter)
{
this.Formatter = formatter;
}
public void DeserializeRequest(System.ServiceModel.Channels.Message message, object[] parameters)
{
Formatter.DeserializeRequest(message, parameters);
}
}
and in OperationBegavior
public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
ServerMessageFormatter Formatter = new ServerMessageFormatter(dispatchOperation.Formatter);
dispatchOperation.Formatter = Formatter;
}
and call soap service
GetInfoRequest message = CheckedFields;
string soap = #"<?xml version=""1.0"" encoding=""utf-8""?>
<soap12:Envelope xmlns:soap12=""http://www.w3.org/2003/05/soap-envelope"">
<soap12:Header>
<Action soap12:mustUnderstand=""1"" xmlns=""http://www.w3.org/2005/08/addressing"">ServiceModel/IService/GetSoapData</Action>
</soap12:Header>
<soap12:Body>
<GetInfoRequest xmlns=""ServiceModel"">
<Data xmlns:d4p1=""http://schemas.microsoft.com/2003/10/Serialization/Arrays"" xmlns:i=""http://www.w3.org/2001/XMLSchema-instance""/>
</GetInfoRequest>
</soap12:Body>
</soap12:Envelope>";
XmlSerializer serializer = new XmlSerializer(typeof(GetInfoRequest));
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://dev.add.renault.com/Service.svc/soap");
MemoryStream stream1 = new MemoryStream();
serializer.Serialize(stream1, message);
stream1.Position = 0;
StreamReader sr = new StreamReader(stream1);
string t = sr.ReadToEnd();
t = t.Remove(0, 22).Trim();
t = string.Format(soap, t);
ASCIIEncoding encoding = new ASCIIEncoding();
request.Timeout = 99999999;
request.ContentLength = t.Length;
request.Method = "POST";
request.ContentType = "application/soap+xml; charset=utf-8";
request.Accept = "application/soap+xml; charset=utf-8";
using (Stream stm = request.GetRequestStream())
{
using (StreamWriter stmw = new StreamWriter(stm))
{
stmw.Write(t);
}
}
var response = (HttpWebResponse)request.GetResponse();
var abc = new StreamReader(response.GetResponseStream());
Problem is that when I call my REST service and set breakpoint in DeserializeRequest I see that Formatter has set value from Operation Behavior. But when call soap service my Formatter has null value and deserialization was aborted. Why when calling soap I have that problem? Any idea?
Unfortunatelly I can not fire breakpoint in Operaration Behavior and see what value have dispatchOperation...
You don't show how you configure your service to add your custom IDispatchMessageFormatter extension. So just taking a guess here, you may be adding it only to the webHttpBinding endpoint and not to the soap based binding endpoint. If you are using the WebHttpBehavior methods (GetRequestDispatchFormatter & GetReplyDispatchFormatter) then this won't apply to your soap endpoints. This blog post has a good overview of how to use IDispatchMessageFormatter with webHttpBinding and basicHttpBinding.
EDIT:
The specific code in the article that shows how to add the a custom message formatter to the basicHttpBinding is below. Just prior to that section, he explains why this approach is necessary.
//--- snipped ---//
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "");
endpoint.Contract.Operations.Find("Add").Behaviors.Add(new MyOperationBehaviorAttribute());
host.Open();
//--- snipped ---//

Restful WCF bad request error

I have a simple resftul wcf service. The .svc file looks like this
<%# ServiceHost Service="NameSpace.RestfulService" Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>
The interface method declaration
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "test2", RequestFormat = WebMessageFormat.Json,ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
List<MyObj> Test2(MyObj test);
Method implementation
public List<MyObj> Test2(MyObj test)
{
return new List<MyObj>() { new MyObj() { MyObjId = "1", RowVersion = 1 }, new MyObj() { MyObj= "2", RowVersion = 2 } };
}
Method on a wpf client to call the service
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(MyObj));
MemoryStream ms = new MemoryStream();
serializer.WriteObject(ms, new MyObj() { MyObjId = "A", RowVersion = 1 });
string jason = Encoding.Default.GetString(ms.ToArray());
//get a handle to the request stream to write data to it
WebRequest myRequest = WebRequest.Create("http://localhost/MyService.svc/test2");
myRequest.Method = "POST";
myRequest.ContentType = "application/jason; charset=utf-8";
StreamWriter sw = new StreamWriter(myRequest.GetRequestStream());
sw.Write(jason);
sw.Close();
//get a handle to the response stream from the server to read the response
WebResponse myResponse = myRequest.GetResponse();
DataContractJsonSerializer RecData = new DataContractJsonSerializer(typeof(List<MyObj>));
var result = (List<MyObj>)RecData.ReadObject(myResponse.GetResponseStream());
When I try to get the RequestStream "myRequest.GetRequestStream()" it says bad request error 400.
Any idea what might be causing this error?
Thanks
Your content type is "application/jason; charset=utf-8". JSON's MIME-type is "application/json" (no 'a'). This is my likely why it 400's when you send the initial headers (which is done when you call GetRequestStream) because the WCF service doesn't recognize the content-type and immediately rejects the request.

FullCalendar and WCF

I've been trying to get data from a wcf service and into the fullcalendar control. However, ive had no luck and wondered what i was doing wrong.
jscript :
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay'
},
editable: false,
height: 200,
aspectRatio: 100,
events: "http://localhost:63295/_services/Service2.svc/DoWork/"
etc...
WCF interface :
[ServiceContract]
public interface IService2
{
[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
string[] DoWork();
}
WCF Service :
public string[] DoWork()
{
// Add your operation implementation here
SortedDictionary<string, string> d = new SortedDictionary<string, string>();
NameValueCollection AE = new NameValueCollection();
SqlDataReader sdr = ReadData("SelectALLAE");
while (sdr.Read())
{
AE.Add("title", sdr["AE_EmployeeID"].ToString() + " " + sdr["AE_EmployeeName"].ToString() + " " + sdr["AE_EventCode"].ToString());
AE.Add("start", sdr["AE_StartDateTime"].ToString());
AE.Add("end", sdr["AE_EndDateTime"].ToString());
}
return AE.GetValues(0).ToArray();
}
Web.config :
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="CountryProvinceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="CountryProvinceBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="CountryProvinceBehavior" name="TimesheetsV2._0_Investigations._services.Service2">
<endpoint address="" binding="webHttpBinding" contract="TimesheetsV2._0_Investigations._services.IService2" behaviorConfiguration="CountryProvinceBehavior"/>
</service>
</services>
</system.serviceModel>
I've successfully connected to this wcf on a page without the full calendar. This was so i could test how to connect to the wcf service via jquery.
But when i use the fullcalendar event option, nothing happens. it doesn't even connect the wcf service at all ( i tried to do a debug on the service and nothing happened ).
any help would be appreciated
thanks
I know this is 7 months old but - try taking the trailing slash off the url call in the $.ajax call.
I think you want : "http://localhost:63295/_services/Service2.svc/DoWork"
try this:
$("#calendar").fullCalendar({
events: {
url: 'http://localhost:63295/_services/Service2.svc/DoWork',
type: 'POST',
data: '{}',
error: function () {
alert('there was an error while fetching events!');
},
color: 'yellow', // a non-ajax option
textColor: 'black' // a non-ajax option
}
});
Also - consider changing the bodystyle of your webinvoke call BodyStyle parameter to BodyStyle = WebMessageBodyStyle.WrappedRequest (I've read you'll get an error with plain wrapped). And not sure if you're doing it already, but be sure to code your start and end values in your list / array as unix time stamps or one of the allowed date types.
your web.config is good.
Here's something I've tested (.net 4.0) with the above fullcalendar ajax call except I used a list not an array - I'm presuming you may be reading in standard dates which won't work either, so there's a function here to convert the dates to unix timestamps on the fly, just dodge it if you're already working with unix time stamps.
[WebInvoke(Method="POST", BodyStyle=WebMessageBodyStyle.WrappedRequest, ResponseFormat=WebMessageFormat.Json)]
[OperationContract]
public List<AELIST> DoWork()
{
SqlConnection sqlconn = new SqlConnection();
sqlconn.ConnectionString = ConfigurationManager.ConnectionStrings["YourConnNameInWebConfig"].ConnectionString;
sqlconn.Open();
string sqlstring = "Select * from YourTable";
SqlCommand sqlcomm = new SqlCommand(sqlstring, sqlconn);
SqlDataReader sreader = sqlcomm.ExecuteReader();
List<AELIST> AE = new List<AELIST>();
while (sdr.Read())
{
DateTime dsx = Convert.ToDateTime(sdr["AE_StartTime"]);
Double mystart = ConvertToTimestamp(dsx);
DateTime dex = Convert.ToDateTime(sdr["AE_EndDateTime"]);
Double myend = ConvertToTimestamp(dex);
AELIST AEEntry = new AELIST<>();
AEEntry.title = sdr["AE_EmployeeID"].ToString() + " " + sdr["AE_EmployeeName"].ToString() + " " + sdr["AE_EventCode"].ToString();
AEEntry.start = mystart.ToString();
AEEntry.end = myend.ToString();
AE.Add(AEEntry);
}
sqlconn.Close();
sdr.Close();
sreader.Dispose();
sqlcomm.Dispose();
return AE;
}
private double ConvertToTimestamp(DateTime value)
{
TimeSpan span = (value - new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime());
return (double)span.TotalSeconds;
}
public class AELIST
{
public string title {get; set;}
public string start {get; set;}
public string end {get; set;}
}