I’m trying to POST a serialized object to my WCF service. However, I keep receiving a “NotFound” error. I have been beating my head on this for three days. Can someone tell me what I’m doing wrong? Below is my client-side code, my WCF service operation, and the class definition I’m trying to serialize.
Client-Side Code
// Build a wrapper exception that will be serialized
Exception ex = e.ExceptionObject;
MyException exception = new MyException(ex.Message, ex.StackTrace, "silverlight app", ex.GetType().FullName, string.Empty);
string json = string.Empty;
using (MemoryStream memoryStream = new MemoryStream())
{
// Serialize the object
DataContractJsonSerializer serializer = new DataContractJsonSerializer(objectType);
serializer.WriteObject(memoryStream, objectToSerialize);
// Convert the data to json
byte[] bytes = memoryStream.ToArray();
int count = (int)(memoryStream.Length);
json = Encoding.UTF8.GetString(bytes, 0, count);
}
// Submit the information to log
string url = "http://localhost:90/services/MyService.svc/LogError";
WebClient loggingService = new WebClient();
loggingService.UploadStringCompleted += new UploadStringCompletedEventHandler(loggingService_UploadStringCompleted);
loggingService.Headers["Content-type"] = "application/json";
loggingService.Encoding = Encoding.UTF8;
loggingService.UploadStringAsync(new Uri(logExceptionUrl), "POST", json);
MyException (Client-Side Version)
public class MyException : Exception
{
private readonly string stackTrace;
public override string StackTrace
{
get {
return base.StackTrace;
}
}
private readonly string message;
public override string Message
{
get {
return base.Message;
}
}
private readonly string component;
public string Component
{
get { return component; }
}
private readonly string typeName;
public string TypeName
{
get { return typeName; }
}
private readonly string miscellaneous;
public string Miscellaneous
{
get { return miscellaneous; }
}
public MyException()
{ }
public MyException(string message) : base(message)
{ }
public MyException(string message, Exception inner) : base(message, inner)
{ }
public MyException(string message, string stackTrace) : base()
{
this.message = message;
this.stackTrace = stackTrace;
}
public MyException(string message, string stackTrace, string component, string typeName, string miscellaneous) : base()
{
this.message = message;
this.stackTrace = stackTrace;
this.component = component;
this.typeName = typeName;
this.miscellaneous = miscellaneous;
}
}
WCF Service
[OperationContract]
[WebInvoke(UriTemplate = "/LogError", BodyStyle=WebMessageBodyStyle.Bare, RequestFormat=WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
public string LogError(MyException exc)
{
try
{
// Write the details of exc to the database
return "ok";
}
catch (Exception ex)
{
return "error";
}
}
MyException in the WCF Project
[Serializable]
public class MyException : Exception
{
public override string StackTrace
{
get { return base.StackTrace; }
}
private readonly string stackTrace;
public override string Message
{
get { return base.Message; }
}
private readonly string message;
public string Component
{
get { return component; }
set { /* */ }
}
private readonly string component;
public string TypeName
{
get { return typeName; }
set { /* */ }
}
private readonly string typeName;
public string Miscellaneous
{
get { return miscellaneous; }
set { /* */ }
}
private readonly string miscellaneous;
public MyException()
{}
public MyException(string message) : base(message)
{ }
public MyException(string message, Exception inner) : base(message, inner)
{ }
public MyException(string message, string stackTrace) : base()
{
this.message = message;
this.stackTrace = stackTrace;
}
public MyException(string message, string stackTrace, string component, string typeName, string miscellaneous) : base()
{
this.message = message;
this.stackTrace = stackTrace;
this.component = component;
this.typeName = typeName;
this.miscellaneous = miscellaneous;
}
protected MyException(SerializationInfo info, StreamingContext context) : base(info, context)
{
component = info.GetString("component");
typeName = info.GetString("typeName");
miscellaneous = info.GetString("miscellaneous");
}
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
info.AddValue("component", component);
info.AddValue("typeName", typeName);
info.AddValue("miscellaneous", miscellaneous);
}
}
Thank you for your help!
In order to invoke a web service in .NET you usually generate a client proxy. You could use the svcutil.exe utility or Add Service Reference… dialog in Visual Studio. Once you have the strongly typed client proxy you simply invoke the service without using any WebClients, MemoryStreams, DataContractJsonSerializers, …
The WCF infrastructure takes care of the rest.