I have a type MyParameter that i pass as a parameter to a wcf service
[Serializable]
public class MyParameter : IXmlSerializable
{
public string Name { get; set; }
public string Value { get; set; }
public string Mytype { get; set; }
#region IXmlSerializable Members
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
XElement e = XElement.Parse(reader.ReadOuterXml());
IEnumerable<XElement> i = e.Elements();
List<XElement> l = new List<XElement>(i);
Name = l[0].Name.ToString();
Value = l[0].Value.ToString();
Mytype = l[0].Attribute("type").Value.ToString();
}
public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteStartElement(Name);
writer.WriteAttributeString("xsi:type", Mytype);
writer.WriteValue(Value);
writer.WriteEndElement();
}
#endregion
}
The service contract looks like this:
[ServiceContract]
public interface IOperation
{
[OperationContract]
void Operation(List<Data> list);
}
Where data defines a data contract
[DataContract]
public class Data
{
public string Name { get; set; }
public List<MyParameter> Parameters{ get; set; }
}
When I run the service and test it
I get rhe exception in readXml of MyParameter
"the prefix xsi is not defined"
xsi should define the namespace "http://w3.org/2001/xmlschema-instance"
How do I fix the problem
I am very new to this so a sample code will be very very very helpful
thanks
Add:
writer.WriteAttributeString("xmlns","xsi", null,#"http://w3.org/2001/xmlschema-instance");
Related
I use DTO class in API layer and I struggle to map DTO class to "model" class in generic Repository.cs in core layer.
Repository.cs :
namespace DTOMap.Core.Repository.Generic
{
public class Repository<T> : IRepository<T> where T : class
{
private DTOMapContext _context;
private DbSet<T> _table;
private IMapper _mapper;
public Repository(DTOMapContext context)
{
_context = context;
_table = _context.Set<T>();
var config = new MapperConfiguration(cfg =>
{
cfg.AddProfile<MyMapper>();
});
_mapper = config.CreateMapper();
}
public T Add(T obj)
{
// Here how to use My Mapper to save a book or an author generically
// Sth like :
// temp = _table.Add(_mapper.Map<T>(obj)); Here I want to map Dto to model to save in the db
// return = (_mapper.Map<T>(temp)); Here I want to map Model to DTO to collect it in API
// but I can't have a reference to TDTO
throw new NotImplementedException();
}
}
}
I show you the other classes that I find useful (I only implement Add function for this example and I am a beginner in .Net) :
Author.cs
namespace DTOMap.Core.Models
{
[Table("Author")]
internal class Author
{
[Key]
public int id { get; set; }
[Required, MaxLength(255)]
public string firstName { get; set; }
[Required,MaxLength(255)]
public string lastName { get; set; }
}
}
Book.cs
namespace DTOMap.Core.Models
{
[Table("Book")]
internal class Book
{
[Key]
public int id { get; set; }
[Required,MaxLength(255)]
public string name { get; set; }
[Required]
public int authorId { get; set; }
[Required]
public Author author { get; set; }
}
}
AuthorDTO.cs
namespace DTOMap.Domain.DTO
{
public class AuthorDTO
{
public int id { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
}
}
BookDTO.cs
namespace DTOMap.Domain.DTO
{
public class BookDTO
{
public int id { get; set; }
public string name { get; set; }
public int authorId { get; set; }
public AuthorDTO author { get; set; }
}
}
IRepository.cs
namespace DTOMap.Domain.Interface
{
public interface IRepository<T>
{
T Add(T obj);
}
}
MyMapper.cs
namespace DTOMap.Core
{
public class MyMapper : Profile
{
public MyMapper()
{
CreateMap<Book, BookDTO>();
CreateMap<BookDTO, Book>();
CreateMap<Author, AuthorDTO>();
CreateMap<AuthorDTO, Author>();
}
}
}
program.cs
... Some Fcts
builder.Services.AddTransient<IRepository<BookDTO>, BookRepository>();
builder.Services.AddTransient<IRepository<AuthorDTO>, AuthorRepository>();
... Some Fcts
If you need any other information, please ask me.
Im trying to use a Class in a WCF service. When im calling the
u.attributeChanges.Add(a);
i get:
"Object reference not set to an instance of an object"
If create the classes in the client application it's working.
UpdateChanges Class
[DataContract]
public class UpdateChanges
{
private void Initialize()
{
this.attributeChanges = new List<AttributeChanges>();
}
public UpdateChanges()
{
this.Initialize();
}
[DataMember]
public string objectGuid { get; set; }
[DataMember]
public Utilities.ObjectTypes objectType { get; set; }
[DataMember]
public Utilities.ChangeType changeType{ get; set; }
[DataMember]
public List<AttributeChanges> attributeChanges { get; set; }
[OnDeserializing]
public void OnDeserializing(StreamingContext ctx)
{
this.Initialize();
}
}
AttributeChanges class
[DataContract]
public class AttributeChanges
{
[DataMember]
public string attributeName { get; set; }
[DataMember]
public string attributeValue { get; set; }
}
Client Code:
Service.DirsyncServiceClient proxyClient;
proxyClient = Utilities.GetProxy("http://192.168.1.45/vDir/Service.svc");
Service.UpdateChanges u = new Service.UpdateChanges();
Service.AttributeChanges a = new Service.AttributeChanges();
a.attributeName = "Attribute1";
a.attributeValue = "Value1";
u.attributeChanges.Add(a);
proxyClient.SaveObject(u);
Anyonw know how to solve this?
You're using a generated client code.
The problem is that the client generates this code on base of the WSDL xlm. The code in the CTOR doesn't generated in the client because the client can't be aware of this code.
You have a few options-
1. Use a shared DLL with the data contract instead of generating it via a web reference.
2. Implement it yourself in a 'partial' class.
I am not able to pass List using WCF with wsHttpBinging. List is a property of FilterResponse class.
Getting the following error.
-Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
//Following is the code.
[DataContract(Namespace = "Abc.Wao.Entity.Response")]
[CollectionDataContract]`
public class FilterResponse : Alcoa.Wao.Entity.Response.Response
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists"), DataMember]
public List<FilterData> FilterData { get; set; }
}
[KnownType(typeof(FilterResponse))]
[CollectionDataContract]
[DataContract(Namespace = "Abc.Wao.Entity.Response")]
public class Response
{
public Response()
{ }
[DataMember]
public string AuthToken { get; set; }
[DataMember]
public string Fault { get; set; }
[DataMember]
public Exception Exception { get; set; }
[DataMember]
public string SessionContext { get; set; }
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class WaoService : IWaoService
{
public FilterResponse GetFilterDetails()
{
FilterResponse res = null;
//Call factory
res = Abc.Wao.Factory.CommonFactory.GetFilterDetails();
return res;
}
}
//------------------------------------------------------
[ServiceContract]
[ServiceKnownType(typeof(FilterResponse))]
[ServiceKnownType(typeof(Response))]
public interface IWaoService
{
[OperationContract]
FilterResponse GetFilterDetails();
}
Your property in the DataContract is missing a DataMember attribute:
[DataMember]
public List<FilterData> FilterData { get; set; }
I'm getting below shown error while returning the Activity object array.Not able understand where things are going wrong.Can any one help me with this .
Here is the error
End element 'ActivityTypeId' from namespace
'http://schemas.datacontract.org/2004/07/BusinessEntities' expected.
Found element 'a:Code' from namespace
'http://schemas.datacontract.org/2004/07/BusinessEntities'. Line 1,
position 450.
UI Related code:
protected void Page_Load(object sender, EventArgs e)
{
TimeSheetManagementServiceClient serviceClient = new TimeSheetManagementServiceClient("WSHttpBinding_ITimeSheetManagementService");
Activity[] activities=serviceClient.GetActivities();
GridView1.DataSource = activities;
GridView1.DataBind();
}
WCFService code
public class TimeSheetManagementService:ITimeSheetManagementService
{
public BusinessEntities.Activity[] GetActivities()
{
TimeSheetManagementDataController controller= new TimeSheetManagementDataController();
var activities = controller.GetActivities().Select(activity => new BusinessEntities.Activity()
{
Code = activity.Code,
Description = activity.Description,
Status =
(EntityStatus)
Enum.Parse(typeof(EntityStatus), ((activity.Status==true) ? 0 : 1).ToString()),
ActivityTypeId = new BusinessEntities.ActivityType()
{
Code=activity.ActivityType.Code,
Description = activity.ActivityType.Description,
Name = activity.ActivityType.Name
}
});
return activities.ToArray();
}
}
Service Contract
[ServiceContract]
interface ITimeSheetManagementService
{
[OperationContract]
Activity[] GetActivities();
}
Data Contract
[DataContract]
public class Activity
{
[DataMember]
public string Code { get; set; }
[DataMember]
public string Description { get; set; }
[DataMember]
public EntityStatus Status { get; set; }
[DataMember]
public ActivityType ActivityTypeId { get; set; }
}
[DataContract]
public enum EntityStatus
{
[EnumMember]
Active=0,
[EnumMember]
Inactive=1
}
[DataContract]
public class ActivityType
{
[DataMember]
public string Code { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Description { get; set; }
}
i`m not sure but i think the issue is the alphabetical order of the datamember of your Activity class. just for testing, consider specifying the order property in the Datamember attribute.
http://msdn.microsoft.com/en-us/library/ms729813%28v=vs.90%29.aspx
hope this will help
Is it possible to specify at runtime the sub-types of a specific abstract contract?
In the classic WCF/DataContract we have the KnownTypeAttribute and its constructor accepting a string representing the name of static function to invoke to get a set of Type:s.
[DataContract]
[KnownType("GetTypes")]
public abstract class AbstractContract
{
[DataMember] public int Prop1 { get; set; }
[DataMember] public string Prop2 { get; set; }
static IEnumerable<Type> GetTypes()
{
var list = new List<Type>();
list.Add(typeof(ConcreteContract1));
list.Add(typeof(ConcreteContract2));
return list;
}
}
[DataContract]
public class ConcreteContract1 : AbstractContract
{
[DataMember] public int Prop3 { get; set; }
}
[DataContract]
public class ConcreteContract2 : AbstractContract
{
[DataMember] public bool Prop3 { get; set; }
}
Is this scenario supported?
The scenario with GetTypes() isn't supported, partly due to how to v1 handles the generation/caching -however, in v2 (preview available) this is supoortable:
using System;
using System.Runtime.Serialization;
using ProtoBuf.Meta;
class Program
{
static void Main()
{
var model = TypeModel.Create();
var abst = model.Add(typeof(AbstractContract), true);
// define inheritance here...
abst.AddSubType(10, typeof(ConcreteContract1));
abst.AddSubType(11, typeof(ConcreteContract2));
model.CompileInPlace();
AbstractContract foo = new ConcreteContract1 { Prop1 = 123, Prop2 = "abc", Prop3 = 456 };
AbstractContract bar = (AbstractContract)model.DeepClone(foo);
Console.WriteLine(bar.Prop1);
Console.WriteLine(bar.Prop2);
Console.WriteLine(((ConcreteContract1)bar).Prop3);
}
}
[DataContract]
public abstract class AbstractContract
{
[DataMember(Order=1)]
public int Prop1 { get; set; }
[DataMember(Order=2)]
public string Prop2 { get; set; }
}
[DataContract]
public class ConcreteContract1 : AbstractContract
{
[DataMember(Order=1)]
public int Prop3 { get; set; }
}
[DataContract]
public class ConcreteContract2 : AbstractContract
{
[DataMember(Order=1)]
public bool Prop3 { get; set; }
}
Actually, with this approach you can take away all the attributes if you want (telling it explicitly instead). Note: you should cache and re-use the compiled model as far as possible - it is thread-safe, but generating it each time will be a bit more expensive.