after a server call my client catches an exception with the following message
"The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error."
Also, note I tried the configuration in WCF "The server did not provide a meaningful reply"
but still didn't work.
Please note, that I debug the service to the end, and the data is successfully populated but at the client end when the data is supposed to appear it just crashes with the mentioned exception.
Any help appreciated.
I figured out the reason behind this that the proxy was wrongly generated for an enum type, it was generated as a string so it failed and gave me out that exception
If someone else comes across this same exception, with the same behavior of debugging to the end in the server, but getting the exception on the return to the client, another possible cause is an uninitialized enum in the return data contract where the enum has explicit values, but no explicit zero value.
[ServiceContract]
public interfact IMyService
{
[OperationContract]
MyResult DoSomething();
}
[DataContract]
public class MyResult
{
[DataMember]
public OperationStatus Status {get; set;}
[DataMember]
public string ErrorText {get; set;}
}
[DataContract]
public enum Operation Status
{
[EnumMember]
Success = 1,
[EnumMember]
Failure = 2
}
public class MyService : IMyService
{
public MyResult DoSomething()
{
var result = new MyResult();
// ... do work, but don't set any properties on result ...
return result;
}
}
The reason the error happens in this scenario is that result.Status defaults to zero, but the data contract does not provide any means to serialize it, since it is not one of the explicitly defined enum values.
The solution (assuming you really do need this enum with explicit integer values) is to either set the enum value in the return object, or provide a default (zero) value.
[DataContract]
public enum Operation Status
{
[EnumMember]
Unknown = 0,
[EnumMember]
Success = 1,
[EnumMember]
Failure = 2
}
--Bill
if your web service return a DataTable, it must have TableName;
look at https://stackoverflow.com/a/5894732/775811
The cause of this error for me was a missing FaultContractAttribute(typeof(FaultModel)) on the Server function interface (The one marked with OperationContract attribute).
When the FaultException< FaultModel >() was thrown on the server side the client side was throwing - CommunicationException: "The server did not provide a meaningful reply this might be caused by a contract mismatch, a premature session shutdown or an internal server error.".
Hope will help someone.
This happened to me on a new system (Windows 10) after trying to call a Windows Workflow service. Other WCF service calls were working, but trying to call the workflow activity (a xamlx WF4 service) received this error.
Trying to browse to the service.xamlx file resulted in a blank screen. That eventually led me to this other answer (the IIS8 specific answer), which is to add the HTTP Activation feature under IIS Services:
WCF on IIS8; *.svc handler mapping doesn't work
Related
I am using a WCF Service and I have implemented IErrorHandler. In the HandleError method, I want to retrieve the caller's username in order to set a ThreadContext property for Log4Net (to save the username along with the exception details in SQL Server)
My code is working well if I avoid trying to retrieve the caller's username.
This is the line of code inside the HandleError method which is returning a NullReferenceException:
string username = ServiceSecurityContext.Current.WindowsIdentity.Name;
It seems that at the point the HandleError method of IErrorHandler kicks in, the original caller information has been disposed.
Does anyone have any idea how I can retrieve the caller's username inside the HandlerError method of IErrorHandler?
Thanks for your help!
Thanks to those who responded to help. My security appears to be configured correctly but I cannot retrieve the username in the HandleError method of the IErrorHandler interface in the WCF service. However, I am able to retrieve the username in the ProvideFault method. So, I declared a class level variable in the ErrorHandler (IErrorHandler) class which is set during the ProvideFault method and then read and logged with the exception in the ErrorHandler method. This is a "workaround" and not my preference, but unfortunately I cannot seem to access the security context inside the HandleError method.
Here is a sample of the code:
public class ErrorHandler : IErrorHandler, IServiceBehavior
{
private string username = null;
public bool HandleError(Exception error)
{
//Log the exception along with the username.
//...logging call including the username class member string...
//Return true to indicate we have performed our behaviour.
return true;
}
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
//Retrieve the username.
username = ServiceSecurityContext.Current.WindowsIdentity.Name;
}
}
If you get this exception then you probably do not have security configured correctly. See also this answer: https://stackoverflow.com/a/2869481/106567
Using a Class Level variable seems to have a side effect. The same instance of the handler seems to be used for every error handled (to be confirmed). So if 2 errors are raised at the exact same time, I don't know how it will react. So instead, in ProvideFault, I used the exception received as argument to transport the username to the HandleError method. An exception has a «Data» property which is a dictionary. I just add two key-value pairs (one for PrimaryIdentity and one for WindowsIdentity). In HandleError, I retrieved the information in the Data property of the exception received as argument.
I am very new to nservicebus. I am using version 3.0.1, the last one up to date. And I wonder if my case is a normal limitation of NSB, I am not aware of.
I have an asp.net MVC application, I am trying to setup and in my global.asax, I have the following :
var configure = Configure.WithWeb()
.DefaultBuilder()
.ForMvc()
.XmlSerializer();
But I have an error with the XmlSerializer when dealing with one of my object:
[Serializable]
public class MyMessage<T> : IMessage
{
public T myobject { get; set; }
}
I pass trough :
XmlSerializer()
instance.Initialize(types);
this.InitType(type, moduleBuilder);
this.InitType(info2.PropertyType, moduleBuilder);
and then when dealing With T,
string typeName = GetTypeName(t);
typename is null and the following instruction :
if (!nameToType.ContainsKey(typeName))
ends in error. null value not allowed.
Is this some limitations to Nservicebus, or am I messing something up?
NServiceBus intentionally does not support generic message types to encourage you to make your message schema explicit.
I'm creating an API which will just use a get request to return some search results from the database, I'm trying to make it so that optional parameters can be passed (easy with WCF) but also so that if parameters are specfied in the query string as long as they are empty they will be ignored by the service.
However if you have the a query string with empty parameters it will return a bad request (400) by the server e.g.
Using a end-user point of your choice pass the following querystring
http://www.exampleservice.com/basic/?apiKey=1234&noOfResults=3&maxSalary=&minSalary=&ouId=0&keywords=Web+Developer
Note that maxSalary and minSalary are not passing values
You then have the following WCF service:
[OperationContract]
[WebGet(UriTemplate = "basic/?apiKey={apiKey}&noOfResults={noOfResults}&maxSalary={maxSalary}&minSalary={minSalary}&ouId={ouId}&keywords={keywords}", BodyStyle = WebMessageBodyStyle.Bare)]
public List<SearchResultsDto> BasicSearch(string keywords, string apiKey, int noOfResults, int maxSalary, int minSalary, int ouId)
{
//Do some service stuff
}
This will cause a 400 error, please can someone explain how you pass empty parameters across to a WCF service or is this just not possible?
Currently passing null or an empty parameter is not supported in WCF, the main solution to this problem is to override the querystringconverter which handles the url as it comes through the pipe but before it reaches the operation contract.
An excellent example of implmenting an extension of the querystringconverter is found here:
In the WCF web programming model, how can one write an operation contract with an array of query string parameters (i.e. with the same name)?
HOWEVER
sadly there is a bug in WCF 4 where you cannot override the querystringconverter, this has been addressed by Microsoft and will be fixed in the SP1 release coming this year.
Until then there is no clean way to deal with this situation other than to handle the exception and return a status code of 400 (bad request) - good documentation of the api should handle this in the interim.
Is it just the integers giving you trouble? Maybe you can try making them nullable?
int? MaxSalary
hope this helps
You could send in "-1", and treat that in your business logic as not sent.
It can be handled in multiple ways. Since you are talking about a REST service that can have optional parameters, my suggestion will be do the something like this.
Create a DataObject that will be accepeted as parameter to this method.
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebGet(RequestFormat=WebMessageFormat.Json)]
RequestObject BasicSearch(RequestObject apiKey);
}
public class Service1 : IService1
{
public RequestObject BasicSearch(RequestObject obj)
{
//Do some service stuff
return obj;
}
}
[DataContract]
public class RequestObject
{
[DataMember]
public string Keywords {get; set;}
[DataMember]
public string ApiKey {get; set;}
[DataMember]
public int NoOfResults { get; set; }
}
Advantages (am going to be short, ping me back for details)
No change in service signature
contract does not change
you will get the flexibility of have
null parameters
you can always extend the number of
parameters without any impact to
existing services
below is the sample input and output from fiddler
note: in the request part i havent passed anything to NumberOfResults intentionally to prove
I implemented a class that implements IErrorHandler interface to log WCF errors. One of the things that I'd like to do is log who the identity of the user than connected to my service when an exception occurred. All my logging occurs in HandleError() method of IErrorHandler interface, but since HandleError() may not have current operation context, I can't get the SecurityContext.PrimaryIdentity. I've come up with the following code to capture things that may not be available in HandleError method, but I'm not sure this will work in all cases.
public class MyErrorHandler : IErrorHandler
{
private IIdentity identity;
public bool HandleError(Exception error)
{
// Do something with identity
return false;
}
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
this.identity = Operation.Current.SecurityContext.PrimaryIdentity;
}
}
The code above seems to be working, but are there any gotchas?
Thanks!
For some reason, I thought that the class was created every time there was an exception. In any case, I was able to solve my issue by using Dictionary property of Exception object to store custom data that I wanted to log with my exception.
I am trying to make a Delphi client (Delphi 2006) to communicate with a service written using WCF. Service is damn simple with just one function. Technically like below:
[ServiceContract (Namespace = "http://www.company.com/sample/")]
public interface IService
{
[OperationContract]
string GetNumber (string name);
}
I have hosted this service on IIS and exposed it using basicHttpBinding with mex end point. I am able to use it in .NET clients.
I tried to run WSDLImp.exe and it generated a source code unit (btw, it generates wierd classes to encapsulate string type. Why cant it be same as Delphi string type?). When I try to call this service, I get the exception:
The message with Action '' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).
I don't see any way to configure the Delphi Win32 client to changing the binding or security parameters. How can I fix this problem?
I've had the exact same problem. Delphi just has hard time importing the WSDL exposed by WCF. One solution is to add an ASMX wrapper to your service and use that with Delphi clients.
Here's an example:
[ServiceContract (Namespace = "http://www.company.com/sample/")]
public interface IService
{
[OperationContract]
string GetNumber (string name);
}
public class Service : IService
{
public string GetNumber (string name)
{
return Repository.GetNumber(name);
}
}
[WebService(
Namespace = "http://www.company.com/sample/",
Name = "wstest",
Description = "description")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class AsmxService : WebService
{
[WebMethod]
public string GetNumber(string name)
{
return Repository.GetNumber(name);
}
}
You need to look at the network traffic between the client and service to see what's going on. Alternatively, turn on WCF tracing on the service, possibly including message tracing. You should be able to see what's going on, in great detail.