How to add List<int> to a DataContract of a web service - datacontract

I want to create a DataContract that is a class with 2 different List members. When I try to start the web service, I get the error that my method, SendEmail, is not supported by the Test WCF Client.
This is my Data Contract:
[DataContract]
[KnownType(typeof(int[]))]
public class EmailInfo
{
private string strFromUserID = string.Empty;
private string strFromAddress = string.Empty;
private string strFromName = string.Empty;
private object lstIndividualIDs = null;
private object lstGroupIDs = null;
private string strSubject = string.Empty;
private string strMessage = string.Empty;
[DataMember]
public string FromUserID
{
get { return strFromUserID; }
set { strFromUserID = value; }
}
[DataMember]
public string FromAddress
{
get { return strFromAddress; }
set { strFromAddress = value; }
}
[DataMember]
public string FromName
{
get { return strFromName; }
set { strFromName = value; }
}
[DataMember]
public object IndividualIDs
{
get { return lstIndividualIDs; }
set { lstIndividualIDs = value; }
}
[DataMember]
public object GroupIDs
{
get { return lstGroupIDs; }
set { lstGroupIDs = value; }
}
[DataMember]
public string Subject
{
get { return strSubject; }
set { strSubject = value; }
}
[DataMember]
public string Message
{
get { return strMessage; }
set { strMessage = value; }
}
}
This is my method that uses the DataContract:
public string SendEmail(EmailInfo emailInfo)
{
string tstrErrorMsg = string.Empty;
SqlConnection SqlConn = null;
try
{
return tstrErrorMsg;
}
catch (Exception ex)
{
return null;
}
finally
{
if (SqlConn != null)
{
SqlConn.Close();
}
}
}
I would like to have a DataMember in the DataContract that is of type List. How do I add that type to a DataContract?

I got the web service to run by changing the lstIndividualIDs and listGroupIDs to List.
I thought I had to use objects.
In case anybody else has this problem...
object lstIndividualIDs -> List listIndividualIDs
same with GroupIDs.
This allowed the Test client to run the service..

Related

How to return different types of responses from WCF service application method?

I have a WCF service application with a method
public PersonResponse(PersonRequest request)
{
return new PersonResponse { Id = 1, Name = "Mark" };
}
I have 2 different responses possible for that method
[DataContract]
public class PersonResponse
{
int id;
string name;
[DataMember]
public int Id
{
get { return id; }
set { id = value; }
}
[DataMember]
public string Name
{
get { return name; }
set { name = value; }
}
}
and
[DataContract]
public class ErrorResponse
{
int errorCode;
string errorText;
[DataMember]
public int? ErrorCode
{
get { return errorCode; }
set { errorCode = value; }
}
[DataMember]
public string ErrorText
{
get { return errorText; }
set { errorText = value; }
}
}
Is it possible to write a method that could return either of those responses but not both at the same time?
I Could do something like
[DataContract]
public class Response
{
PersonResponse personResponse;
ErrorResponse errorResponse;
[DataMember]
public bool PersonResponse
{
get { return personResponse; }
set { personResponse= value; }
}
[DataMember]
public string ErrorResponse
{
get { return errorResponse; }
set { errorResponse= value; }
}
}
public Response(PersonRequest request)
{
return new Response{ PersonResponse = New PersonResponse { Id = 1, Name = "Mark" }, ErrorResponse = new ErrorResponse { ErrorCode = null, ErrorText = null } };
}
But I only need 1 type of the response to be returned, not both.
I've tried
public PersonResponse(PersonRequest request)
{
throw new WebFaultException<ErrorResponse>(new ErrorResponse { ErrorCode = 103 ErrorText = "Try again later" }, HttpStatusCode.Conflict);
}
But it seems that this way it only returns the exception and not the ErrorResponse.
I've also tried adding and interface layer to the response like so and then returning that interface as a response
public interface IResponse {}
[DataContract]
public class PersonResponse : IResponse
{
int id;
string name;
[DataMember]
public int Id
{
get { return id; }
set { id = value; }
}
[DataMember]
public string Name
{
get { return name; }
set { name = value; }
}
}
[DataContract]
public class ErrorResponse : IResponse
{
int errorCode;
string errorText;
[DataMember]
public int? ErrorCode
{
get { return errorCode; }
set { errorCode = value; }
}
[DataMember]
public string ErrorText
{
get { return errorText; }
set { errorText = value; }
}
}
public IResponse(PersonRequest request)
{
return new PersonResponse { Id = 1, Name = "Mark" };
}
But when I add this service as a reference to another project id doesn't generate any of the response type (Iresponse, ErrorResonse or PersonResponse) and throws an error when I try to call the method (Exception message https://ibb.co/Zdsbr9p)
I think you can try to use FaultContractAttribute. Fault contracts allow you to specify alternate responses that will be returned in a SOAP fault.
Example interface:
[ServiceContract]
interface IService
{
[OperationContract]
[FaultContract(typeof(ErrorResponse))]
PersonResponse GetResponse();
}
Service:
class Service : IService
{
public PersonResponse GetResponse()
{
if (success)
{
return new PersonResponse();
}
else
{
throw new FaultException<ErrorResponse>(new ErrorResponse()
{
ErrorMessage = "Something Happened"
})
}
}
}
The client can then handle the fault by catching FaultException<ErrorResponse>:
var serviceProxy = new ServiceProxy();
try
{
var dataObj = serviceProxy.GetResponse();
}
catch (FaultException<ErrorResponse> error)
{
ErrorResponse detail = error.Detail;
Console.WriteLine(detail.ErrorMessage);
}
source:How best should a Wcf service return different objects for the same method
resemblance:Return different Object (List or error class) from WCF service

How to resolve an error with WCF data contract -Message = "There was an error while trying to serialize parameter

I have two data contracts of same contents in two different namespaces. i have copied one datacontract to another and
passed to a particular method. but it is giving the below error and throwing exception. it is not going into that method.
Please let me know any ideas /suggestions on how to resolve this.Appreciate your help:
Exception errror:
{"Type 'System.Collections.Generic.List`1[[GlobalWcfServiceLib.TopicDetailsInfo, GlobalWcfContracts, Version=1.2.2.0, Culture=neutral,
PublicKeyToken=17c64733a9775004]]' with data contract name 'ArrayOfTopicDetailsInfo:http://CName.GlobalService/11.1/2010/11'
is not expected. Consider using a DataContractResolver or add any types not known statically to the list of
known types - for example, by using the KnownTypeAttribute attribute or by
adding them to the list of known types passed to DataContractSerializer."}
Message = "There was an error while trying to serialize parameter
http://CName.SharedServices.DBServiceLib:subscriptionDataContract.
The InnerException message was 'Type 'System.Collections.Generic.List`1
[[GlobalWcfServiceLib.TopicDetailsInfo,
GlobalWcfContra...
//////
Here is my scenario : i am copying the data from dc to new data contract as below. after copying , when i am executing the createsubscriptions method i am getting the above mentioned error. i have given the details of data contract and error attached to this question. please refer to that as well.
Method1(SubscriptionDataContracts dc)
{
SubscriptionDataContract subscriptionDataContract = new SubscriptionDataContract();
List<SubscriptionTopicInfo> topicsInfo = dc.TopicList;
List<SubscriptionTopic> newTopicsList = new List<SubscriptionTopic>();
subscriptionDataContract.ExtensionData = dc.ExtensionData;
subscriptionDataContract.UserID = dc.UserID;
for (int i = 0; i < topicsInfo.Count; i++)
{
SubscriptionTopic topic = new SubscriptionTopic();
topic.DBHandle = topicsInfo[i].DBHandle;
topic.Topic = topicsInfo[i].Topic;
topic.Target = topicsInfo[i].Target;
newTopicsList.Add(topic);
}
subscriptionDataContract.TopicList = newTopicsList;
CreateSubscriptions(subscriptionDataContract); //getting the above mentioned error in another dll after going into this method
}
////////////////////////////////
//My data contract
[DataContract(Name = "TopicDetailsInfo", Namespace = "http://CName.GlobalService")]
[Serializable]
public class TopicDetailsInfo
{
protected object topic;
protected object baseObjectType;
[DataMember]
public object BaseObjectType
{
get
{
return baseObjectType;
}
set
{
baseObjectType = value;
}
}
[DataMember]
public object TopicID
{
get
{
return topic;
}
set
{
topic = value;
}
}
static public TopicDetailsInfo CreateTopic<T, mT>(IComparable<T> objectType, IComparable<mT> objectID)
{
var topicDetails = new TopicDetailsInfo();
topicDetails.BaseObjectType = objectType;
topicDetails.TopicID = objectID;
return topicDetails;
}
}
[DataContract(Name = "SubscriptionTopicInfo", Namespace = "http://CName.GlobalService")]
[KnownType(typeof(List<TopicDetailsInfo>))]
[Serializable]
public class SubscriptionTopicInfo
{
private object topic;
private object target;
private object creator;
[DataMember]
public object Topic
{
get
{
return topic;
}
set
{
topic = value;
}
}
[DataMember]
public object Target
{
get
{
return target;
}
set
{
target = value;
}
}
[DataMember]
public object DBHandle
{
get
{
return creator;
}
set
{
creator = value;
}
}
static public SubscriptionTopicInfo CreateSubscriptions<T, mT, nT>(IList<TopicDetailsInfo> topic, IComparable<mT> target, IComparable<nT> handle)
{
var subscriptionTopic = new SubscriptionTopicInfo();
subscriptionTopic.Target = target;
subscriptionTopic.Topic = topic;
subscriptionTopic.DBHandle = handle;
return subscriptionTopic;
}
}
[DataContract(Name = "SubscriptionData", Namespace = "http://CName.GlobalService")]
[KnownType(typeof(List<SubscriptionTopicInfo>))]
[Serializable]
public class SubscriptionDataContracts : IExtensibleDataObject
{
private ExtensionDataObject extensionDataObjectValue;
[DataMember]
public string UserID
{
get;
set;
}
[DataMember]
public string ProjectID
{
get;
set;
}
[DataMember]
public string FromDiscipline
{
get;
set;
}
[DataMember]
public string ModuleID
{
get;
set;
}
[DataMember]
public string SessionID
{
get;
set;
}
[DataMember]
public List<SubscriptionTopicInfo> TopicList
{
get;
set;
}
public ExtensionDataObject ExtensionData
{
get
{
return extensionDataObjectValue;
}
set
{
extensionDataObjectValue = value;
}
}
}

Returning Custom Class from WCF Method?

There are so many question about that but there is no solution for my problem. I want to return a custom class which has datacontract key and it's members have datamember key. I am getting this error while I testing it;
When I call it from my windows phone application, it returns "The remote server not found"
It returns not found but it runs methods that return types are void, bool, list.
[OperationContract]
BaseModel Login(string userName, string password);
[DataContract]
public class UserModel
{
private int userID;
[DataMember]
public int UserID
{
get { return userID; }
set { userID = value; }
}
private string userName;
[DataMember]
public string UserName
{
get { return userName; }
set { userName = value; }
}
private string password;
[DataMember]
public string Password
{
get { return password; }
set { password = value; }
}
private string email;
[DataMember]
public string Email
{
get { return email; }
set { email = value; }
}
private int securityQuestionID;
[DataMember]
public int SecurityQuestionID
{
get { return securityQuestionID; }
set { securityQuestionID = value; }
}
private string securityQuestionAnswer;
[DataMember]
public string SecurityQuestionAnswer
{
get { return securityQuestionAnswer; }
set { securityQuestionAnswer = value; }
}
private string sex;
[DataMember]
public string Sex
{
get { return sex; }
set { sex = value; }
}
private string gsmNo;
[DataMember]
public string GSMNo
{
get { return gsmNo; }
set { gsmNo = value; }
}
private DateTime birthDate;
[DataMember]
public DateTime BirthDate
{
get { return birthDate; }
set { birthDate = value; }
}
private string registeredDeviceUniqueID;
[DataMember]
public string RegisteredDeviceUniqueID
{
get { return registeredDeviceUniqueID; }
set { registeredDeviceUniqueID = value; }
}
private string registrationType;
[DataMember]
public string RegistrationType
{
get { return registrationType; }
set { registrationType = value; }
}
private string registeredDeviceType;
[DataMember]
public string RegisteredDeviceType
{
get { return registeredDeviceType; }
set { registeredDeviceType = value; }
}
private string registeredApplication;
[DataMember]
public string RegisteredApplication
{
get { return registeredApplication; }
set { registeredApplication = value; }
}
private DateTime registeredDate;
[DataMember]
public DateTime RegisteredDate
{
get { return registeredDate; }
set { registeredDate = value; }
}
private string registeredGSM;
[DataMember]
public string RegisteredGSM
{
get { return registeredGSM; }
set { registeredGSM = value; }
}
private string profilePictureURL;
[DataMember]
public string ProfilePictureURL
{
get { return profilePictureURL; }
set { profilePictureURL = value; }
}
}
[DataContract]
public class BaseModel
{
private string errorMessage;
[DataMember]
public string ErrorMessage
{
get { return errorMessage; }
set { errorMessage = value; }
}
private string informationMessage;
[DataMember]
public string InformationMessage
{
get { return informationMessage; }
set { informationMessage = value; }
}
private string warningMessage;
[DataMember]
public string WarningMessage
{
get { return warningMessage; }
set { warningMessage = value; }
}
private string succeedMessage;
[DataMember]
public string SucceedMessage
{
get { return succeedMessage; }
set { succeedMessage = value; }
}
private object returnObject;
[DataMember]
public object ReturnObject
{
get { return returnObject; }
set { returnObject = value; }
}
private bool isSucceed;
[DataMember]
public bool IsSucceed
{
get { return isSucceed; }
set { isSucceed = value; }
}
}
And the method is;
public BaseModel Login(string userName, string password)
{
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["conStr"].ConnectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand("SELECT * FROM UserBaseInformations WITH (NOLOCK) Where UserName=#userName", connection))
{
command.Parameters.Add(new SqlParameter("#userName", userName));
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = command;
DataTable dt = new DataTable();
adapter.Fill(dt);
DataSet ds = new DataSet();
ds.Tables.Add(dt);
connection.Close();
if (dt.Rows.Count == 0)
return new BaseModel() { IsSucceed = false, ErrorMessage = "Geçersiz bir kullanıcı adı girdiniz." };
else if (!dt.Rows[0]["Password"].ToString().Equals(password))
return new BaseModel() { IsSucceed = false, ErrorMessage = "Şifrenizi yanlış girdiniz." };
else
return new BaseModel()
{
IsSucceed = true,
ReturnObject = new UserModel()
{
Email = dt.Rows[0]["Email"].ToString(),
Password = dt.Rows[0]["Password"].ToString(),
UserID = (int)dt.Rows[0]["UserID"],
UserName = dt.Rows[0]["UserName"].ToString(),
SecurityQuestionID = (int)dt.Rows[0]["SecurityQuestionID"],
SecurityQuestionAnswer = dt.Rows[0]["SecurityQuestionAnswer"].ToString()
}
};
}
}
}
I have found solution.
Returning an object type can be problem in WCF so I changed it to a base class for returning my classes and added KnownType attribute to BaseModel.

Determine what fields to save in Windows Azure Table Storage

I'm trying to store an entity called Tshirt into a Windows Azure table storage along with a Blob on Windows Azure Blob storage.
That entity Tshirt contains a field called Image (byte[]) but I don't want to save that in my table.
How can I indicate in my class that I don't want to save that field?
public class Tshirt : TableServiceEntity
{
public Tshirt(string partitionKey, string rowKey, string name)
{
this.PartitionKey = partitionKey;
this.RowKey = rowKey;
this.Name = name;
this.ImageName = new Guid();
}
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
private string _color { get; set; }
public string Color
{
get { return _color; }
set { _color = value; }
}
private int _amount { get; set; }
public int Amount
{
get { return _amount; }
set { _amount = value; }
}
[NonSerialized]
private byte[] _image;
public byte[] Image
{
get { return _image; }
set { _image = value; }
}
private Guid _imageName;
public Guid ImageName
{
get { return _imageName; }
set { _imageName = value; }
}
}
The easy way is to expose the field as a pair of methods rather than an actual property:
public byte[] GetImage()
{
return _image;
}
public void SetImage(byte[] image)
{
_image = image;
}
If that's not an option, then you can remove the Image property when you're storing the entity by handling the WritingEntity event. (Credit to Neil Mackenzie)
public void AddTshirt(Tshirt tshirt)
{
var context = new TableServiceContext(_baseAddress, _credentials);
context.WritingEntity += new EventHandler<ReadingWritingEntityEventArgs>(RemoveImage);
context.AddObject("Tshirt", tshirt);
context.SaveChanges();
}
private void RemoveImage(object sender, ReadingWritingEntityEventArgs args)
{
XNamespace d = "http://schemas.microsoft.com/ado/2007/08/dataservices";
XElement imageElement = args.Data.Descendants(d + "Image").First();
imageElement.Remove();
}

NHibernate FetchMode.Lazy

I have an object which has a property on it that has then has collections which i would like to not load in a couple situations. 98% of the time i want those collections fetched but in the one instance i do not. Here is the code I have... Why does it not set the fetch mode on the properties collections?
[DataContract(Name = "ThemingJob", Namespace = "")]
[Serializable]
public class ThemingJob : ServiceJob
{
[DataMember]
public virtual Query Query { get; set; }
[DataMember]
public string Results { get; set; }
}
[DataContract(Name = "Query", Namespace = "")]
[Serializable]
public class Query : LookupEntity<Query>, DAC.US.Search.Models.IQueryEntity
{
[DataMember]
public string QueryResult { get; set; }
private IList<Asset> _Assets = new List<Asset>();
[IgnoreDataMember]
[System.Xml.Serialization.XmlIgnore]
public IList<Asset> Assets { get { return _Assets; } set { _Assets = value; } }
private IList<Theme> _Themes = new List<Theme>();
[IgnoreDataMember]
[System.Xml.Serialization.XmlIgnore]
public IList<Theme> Themes { get { return _Themes; } set { _Themes = value; } }
private IList<Affinity> _Affinity = new List<Affinity>();
[IgnoreDataMember]
[System.Xml.Serialization.XmlIgnore]
public IList<Affinity> Affinity { get { return _Affinity; } set { _Affinity = value; } }
private IList<Word> _Words = new List<Word>();
[IgnoreDataMember]
[System.Xml.Serialization.XmlIgnore]
public IList<Word> Words { get { return _Words; } set { _Words = value; } }
}
using (global::NHibernate.ISession session = NHibernateApplication.GetCurrentSession())
{
global::NHibernate.ICriteria criteria = session.CreateCriteria(typeof(ThemingJob));
global::NHibernate.ICriteria countCriteria = session.CreateCriteria(typeof(ThemingJob));
criteria.AddOrder(global::NHibernate.Criterion.Order.Desc("Id"));
var qc = criteria.CreateCriteria("Query");
qc.SetFetchMode("Assets", global::NHibernate.FetchMode.Lazy);
qc.SetFetchMode("Themes", global::NHibernate.FetchMode.Lazy);
qc.SetFetchMode("Affinity", global::NHibernate.FetchMode.Lazy);
qc.SetFetchMode("Words", global::NHibernate.FetchMode.Lazy);
pageIndex = Convert.ToInt32(pageIndex) - 1; // convert to 0 based paging index
criteria.SetMaxResults(pageSize);
criteria.SetFirstResult(pageIndex * pageSize);
countCriteria.SetProjection(global::NHibernate.Criterion.Projections.RowCount());
int totalRecords = (int)countCriteria.List()[0];
return criteria.List<ThemingJob>().ToPagedList<ThemingJob>(pageIndex, pageSize, totalRecords);
}