How to use datacontract in C#? - c#

I have this interface both in server and client side:
namespace BH_Server {
[ServiceContract]
public interface BHInterface {
[OperationContract]
string GetName( string name );
[OperationContract]
Device GetDevice();
}
[DataContract]
public class Device {
private string dSN;
[DataMember]
public string SN {
get { return dSN; }
set { dSN = value; }
}
}
}
Also, I have this in server side:
public class CronServiceInterface : BHInterface {
public string GetName( string name ) {
return string.Format( "Hello {0}", name );
}
public Device GetDevice() {
Device d = new Device();
d.SN = "123456789";
return d;
}
}
And this on server side, also:
host = new ServiceHost( typeof( CronServiceInterface ), new Uri[] {
new Uri("net.pipe://localhost/")
} );
host.AddServiceEndpoint( typeof( BHInterface ), new NetNamedPipeBinding( NetNamedPipeSecurityMode.None ), "BhPipe" );
host.Open();
To create connection on client side, this code is used:
NetNamedPipeBinding binding = new NetNamedPipeBinding( NetNamedPipeSecurityMode.None );
ChannelFactory<BHInterface> channelFactory = new ChannelFactory<BHInterface>( binding );
EndpointAddress endpointAddress = new EndpointAddress( "net.pipe://localhost/BhPipe/" );
BHInterface iface = channelFactory.CreateChannel( endpointAddress );
Obviously not all the code is written here, I hope it is enough to see what is implemented.
Using Debug.WriteLine( iface.GetName("Tom") ); results "Hello Tom" in client side, but the following code won't work:
Device d;
d = iface.GetDevice();
Debug.WriteLine( string.Format( "Printing sn: {0}", d.SN ) );
It prints: "Printing sn: ".
I'm using .NET 4.5 and error is not thrown. I'm new in WCF topic.
Would somebody so kind explaining to me how could I pass the desired object to client?

To elaborate a bit more... Like the ServiceContract and OperationContract shows the prototypes veses implementation, so goes for the DataContract and DataMembers. You are placing implementation
get { return dSN; }
set { dSN = value; }
Where all is needed is the
public string SN {get;set;}

To solve this just remove the backing field for your property and have DataContract defined as
[DataContract]
public class Device {
[DataMember]
public string SN {get;set;}
}
The reason is that the value of dSN is not sent from the service to the client because it is not a [DataMember]. Other solution would be mark the private field with [DataMember] attribute but you should generally avoid such practice.
Also , remember to update service reference after any change to the data contracts as otherwise client will still see old contracts.

Huh, I found out!
I had to use attributes in my datacontracts!
namespace BH_Server {
[ServiceContract]
public interface BHInterface {
[OperationContract]
string GetName( string name );
[OperationContract]
Device GetDevice();
}
[DataContract( Name = "Device", Namespace = "" )]
public class Device {
[DataMember( Name = "SN", Order = 1 )]
public string SN { get; set; }
}
}
Now it works like a charm!

Related

wcf rest json return collection

I am attempting to build a Restful WCF Service which returns data in JSON format. My firsts methods work fine but when I try return a collection my test program receive the next exception:
Unable to write data to the transport connection. An existing connection was forcibly closed by the remote host.
My Service code:
[ServiceContract]
public interface IService
{
[OperationContract]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "/GetModes")]
OGetModesResponse OGetModes(OGetModesRequest oGetModes);
}
[DataContract]
public class OGetModesRequest
{
private String m_sTicket;
[DataMember]
public String prTicket
{
get { return m_sTicket; }
set { m_sTicket = value; }
}
}
[DataContract]
public class OGetModesResponse
{
[DataMember]
public string sTicket;
[DataMember]
public emStatus emStatus;
[DataMember]
public IList<CTMode> aoModes;
}
And my test program:
OGetModesRequest oGetModes = new OGetModesRequest { prTicket = sTicket };
ser = new DataContractJsonSerializer(typeof(OGetModesRequest));
mem = new MemoryStream();
ser.WriteObject(mem, oGetModes);
webClient = new WebClient();
webClient.Headers["Content-type"] = "application/json";
webClient.Encoding = Encoding.UTF8;
//Exception here
bData = webClient.UploadData("http://localhost:26104/Service.svc/GetModes", "POST", mem.ToArray());
stream = new MemoryStream(bData);
obj = new DataContractJsonSerializer(typeof(OGetModesResponse));
OGetModesResponse OResultModes = obj.ReadObject(stream) as OGetModesResponse;
I debug my services and works fine. What can be happening?
Thanks for help.
Edit (solution):
CTMode is a class used by managing object that I obtain using NHibernate so I create a new class serializable called CMode
[DataContract]
public class OGetModesResponse
{
[DataMember]
public string sTicket;
[DataMember]
public emStatus emStatus;
[DataMember]
public IList<CMode> aoModes;
}
[Serializable]
public class CMode
{
public Int32 nId;
public Int32 nCode;
public String sName;
}
Try to check inner exception and add some logging/ trace on the server.
There are few possibilities for your (generic) error as you may not be aware about inner exception:
object CTMode is missing DataContract, DataMember attribute.
object CTMode is an enum that missing attributes or has incorrect value that cannot be serialized
previous connection is not closed correctly
there is a proxy server on the way and you need to bypassed it

__type and inheritance with WCFService

[DataContract]
public abstract class BusMessage
{
[DataMember(Name = "encoding")]
public string Encoding { get; set; }
[DataMember(Name = "type")]
public virtual MessageType Type
{
get { return _type; }
private set { _type = value; }
}
}
[DataContract]
public class BusTextMessage : BusMessage
{
[DataMember(Name = "type")]
public override MessageType Type
{
get { return MessageType.Text; }
}
[DataMember(Name = "payload")]
public string Payload { get; set; }
}
[ServiceContract]
[ServiceKnownType("GetKnownTypes", typeof(Helper))]
public interface ICommunicationService
{
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "/SendMessage")]
string SendMessage(BusMessage jsonMessage);
}
}
When I send request with Postman chrome, if I don't add __type as "__type":"BusTextMessage:#TransportModels.Messages" the object won't be serialized properly because it doesn't know how to instantiate BusMessage class. I have already defined Type property which defines the type of message. Is there any possibility to override __type behaviour for example return proper implementation depending on Type property? I don't want anyone to put __type information to json manually so is there an option to edit json before deserialization and add __type property manually to json if it doesn't exist? For example I want to do something like this:
public void BeforeDeserialization(string json)
{
if(json doesnt include __type)
{
if(json property type(my property) is MessageType.Text)
add to json "__type":"BusTextMessage:#TransportModels.Messages"
///etc
}
}
I Found this methods but it doesn't seem to be usable:
[OnDeserializing()]
internal void OnDeserializingMethod(StreamingContext context)
{
}
I think you need to add the KnownType attribute to the BusMessage class.
[DataContract]
[KnownType(typeof(BusTextMessage)]
public class BusMessage
{
.
.
.
}
This is the quickest solution I discovered. I configure MessageInspector and handle AfterReceiveRequest. Then I check message format(XML,JSON). If it is XML(for example sent from any WCF Client written in C#, WCF is configured to send everything with XML's) then I accept that message because field __type will be automatically inserted by WCF mechanism. Otherwise I Check if it is JSON, for example sent from external client. If it doesn't contain property "__type" I check my property Type and generate proper __type value. For example if my Type is equal to Text I add __type property BusTextMessage:#TransportModels.Messages and insert it into JSON and then recreate the message. I couldn't find quicker and easier solution and it seems to be working. Handling AfterReceiveRequest I found at http://code.msdn.microsoft.com/windowsdesktop/WCF-REST-Message-Inspector-c4b6790b.
public class MessageTypeInspector : IDispatchMessageInspector
{
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
RecreateMessage(ref request);
return null;
}
}
private void RecreateMessage(ref Message message)
{
WebContentFormat messageFormat = this.GetMessageContentFormat(message);
var ms = new MemoryStream();
XmlDictionaryWriter writer = null;
switch (messageFormat)
{
case WebContentFormat.Default:
case WebContentFormat.Xml:
writer = XmlDictionaryWriter.CreateTextWriter(ms);
break;
case WebContentFormat.Json:
writer = JsonReaderWriterFactory.CreateJsonWriter(ms);
break;
case WebContentFormat.Raw:
this.ReadRawBody(ref message);
break;
}
message.WriteMessage(writer);
writer.Flush();
string messageBody = Encoding.UTF8.GetString(ms.ToArray());
if (messageFormat == WebContentFormat.Json && !messageBody.Contains("__type"))
messageBody = AddTypeField(messageBody);
ms.Position = 0;
ms = new MemoryStream(Encoding.UTF8.GetBytes(messageBody));
XmlDictionaryReader reader = messageFormat == WebContentFormat.Json ?
JsonReaderWriterFactory.CreateJsonReader(ms, XmlDictionaryReaderQuotas.Max) :
XmlDictionaryReader.CreateTextReader(ms, XmlDictionaryReaderQuotas.Max);
Message newMessage = Message.CreateMessage(reader, int.MaxValue, message.Version);
newMessage.Properties.CopyProperties(message.Properties);
message = newMessage;
}
private WebContentFormat GetMessageContentFormat(Message message)
{
WebContentFormat format = WebContentFormat.Default;
if (message.Properties.ContainsKey(WebBodyFormatMessageProperty.Name))
{
WebBodyFormatMessageProperty bodyFormat;
bodyFormat = (WebBodyFormatMessageProperty)message.Properties[WebBodyFormatMessageProperty.Name];
format = bodyFormat.Format;
}
return format;
}
private string AddTypeField(string jsonReply)
{
var typeRegex = new Regex("\"type\":(?<number>[0-9]*)");
Match match = typeRegex.Match(jsonReply);
if (match.Success)
{
int number = Int32.Parse(match.Groups["number"].Value);
var type = (MessageType)number;
var nameFormat = string.Format("Bus{0}Message", type);
string format = string.Format("\"__type\":\"{0}:#TransportModels.Messages\"", nameFormat);
jsonReply = "{" + string.Format("{0},{1}", format, jsonReply.Substring(1));
return jsonReply;
}
else
{
throw new Exception("Wrong message type.");
}
}

Change c# WebReference url address

Hi,
I have 2 clients with 2 different servers.
After generating wsdl classes I change url address for clients accordingly in SoapHttpClientProtocol consructor.
from
this.Url = "http://10.0.3.5:88/SomeName/dish
to
this.Url = "http://192.168.20.5:88/SomeOtherName/dish
But I can't change SoapDocumentMethodAttribute at runtime. Without changing it my method doesn't return DataSet just null. After changing all addresses in attribute everything works fine.
[System.Web.Services.Protocols.SoapDocumentMethodAttribute( "http://10.0.3.5:88/SomeName/EuroSoft/ProductTransferExecute", RequestNamespace = "http://10.0.3.5:88/SomeName/dish", ResponseNamespace = "http://10.0.3.5:88/SomeName/dish", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle =
System.Web.Services.Protocols.SoapParameterStyle.Wrapped )]
public System.Data.DataSet ProductTransferExecute( [System.Xml.Serialization.XmlElementAttribute( IsNullable = true )] string department, [System.Xml.Serialization.XmlElementAttribute( IsNullable = true )] string XMLproducts, out int sqlcode ) {}
Services are generated by Sybase Anywhere 9 database. Is it possible to change it dynamic? What needs to be identical for this to work?
Create a CustomSoapHttpClientProtocol:
public class CustomSoapHttpClientProtocol : SoapHttpClientProtocol
{
public string SoapActionUrl { get; private set; }
public CustomSoapHttpClientProtocol(string soapActionUrl)
{
this.SoapActionUrl = soapActionUrl;
}
protected override WebResponse GetWebResponse(WebRequest request)
{
const string soapAction = "SOAPAction";
if (request.Headers.Count > 0 && request.Headers.AllKeys.Contains(soapAction))
{
request.Headers[soapAction] = SoapActionUrl;
}
WebResponse response = base.GetWebResponse(request);
return response;
}
Then in your proxy class replace SoapHttpClientProtocol with your CustomSoapHttpClientProtocol.

Extract method in C# to use throughout project

Forgive the lengthy code here, and I also realise this may be a very basic fundamental question for any object-oriented developer, but I'm a front-end developer in at the deep end with .NET and trying to learn about classes and methods with an actual example. I've read resources to explain this stuff but immediately get stuck with the complexities of real-world code.
Basically I have a bunch of methods for adding comments to a web page and manipulating the status (marking as spam, deleting etc). Many of these methods call an 'EmailNotification' method, which sends an email to an administrator at each stage. It works great.
However, I'd like to use the 'EmailNotification' method elsewhere in the project, calling it from a different .cs file. When I try to do this it doesn't recognise the method because (I think!?) it's not a public static method.
Can anyone explain to me how to extract the EmailNotification method so that I can use it in different places around the code? I have tried creating a new class with this method inside it, but I just can't get it to work.
using System;
using System.Net.Mail;
namespace UComment.Domain
{
public class Comment
{
public delegate void CommentCreatedEventHandler(Comment sender, EventArgs e);
public delegate void CommentDeletedEventHandler(Comment sender, EventArgs e);
public delegate void CommentSpamEventHandler(Comment sender, EventArgs e);
public delegate void CommentApprovedEventHandler(Comment sender, EventArgs e);
public static event CommentCreatedEventHandler CommentCreated;
public static event CommentDeletedEventHandler CommentDeleted;
public static event CommentSpamEventHandler CommentSpam;
public static event CommentApprovedEventHandler CommentApproved;
protected virtual void OnCommentCreated(EventArgs e)
{
if (CommentCreated != null) CommentCreated(this, e);
}
protected virtual void OnCommentSpam(EventArgs e)
{
if (CommentSpam != null) CommentSpam(this, e);
}
protected virtual void OnCommentApproved(EventArgs e)
{
if (CommentApproved != null) CommentApproved(this, e);
}
protected virtual void OnCommentDelete(EventArgs e)
{
if (CommentDeleted != null) CommentDeleted(this, e);
}
public int Id { get; set; }
public int ParentNodeId { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Website { get; set; }
public bool Spam { get; set; }
public bool Approved { get; set; }
public DateTime Created { get; set; }
public string CommenText { get; set; }
public int StatusId { get; set; }
public Comment(int id)
{
Id = id;
var sqlHelper = DataLayerHelper.CreateSqlHelper(cms.GlobalSettings.DbDSN);
var reader = sqlHelper.ExecuteReader("select * from Comment where id = #id",
sqlHelper.CreateParameter("#id", id));
if(!reader.HasRecords) throw new Exception(string.Format("Comment with id {0} was not found", id));
reader.Read();
Name = reader.GetString("name");
ParentNodeId = reader.GetInt("nodeid");
Email = reader.GetString("email");
Website = reader.GetString("website");
Approved = reader.GetBoolean("approved");
Spam = reader.GetBoolean("Spam");
Created = reader.GetDateTime("created");
CommenText = reader.GetString("comment");
StatusId = reader.GetInt("statusid");
}
private Comment()
{
}
/// <summary>
/// Set as approved, mark as Not Spam - ignore HAM status
/// </summary>
public void MarkAsApproved()
{
var sqlHelper = DataLayerHelper.CreateSqlHelper(cms.GlobalSettings.DbDSN);
sqlHelper.ExecuteNonQuery(
"update comment set approved = 1, spam = 0, statusid = 2 where id = #id",
sqlHelper.CreateParameter("#id", Id));
OnCommentApproved(EventArgs.Empty);
// Send approval email
EmailNotification(1);
}
/// <summary>
/// Remove approval status. Ignore Spam and Ham states
/// </summary>
public void MarkAsNotApproved()
{
var sqlHelper = DataLayerHelper.CreateSqlHelper(cms.GlobalSettings.DbDSN);
sqlHelper.ExecuteNonQuery(
"update comment set approved = 0, statusid = 3 where id = #id",
sqlHelper.CreateParameter("#id", Id));
OnCommentApproved(EventArgs.Empty);
// Send rejection email
EmailNotification(2);
}
/// <summary>
/// Spam cannot be ham or approved
/// </summary>
public void MarkAsSpam()
{
var sqlHelper = DataLayerHelper.CreateSqlHelper(cms.GlobalSettings.DbDSN);
sqlHelper.ExecuteNonQuery(
"update comment set spam = 1, ham = 0, approved = 0, statusid = 3 where id = #id",
sqlHelper.CreateParameter("#id", Id));
OnCommentSpam(EventArgs.Empty);
// No email notification required - spammer not worthy of a reason for rejection
}
/// <summary>
/// Ham is "not spam" - approved comments from Akismet.
/// </summary>
public void MarkAsHam()
{
var sqlHelper = DataLayerHelper.CreateSqlHelper(cms.GlobalSettings.DbDSN);
sqlHelper.ExecuteNonQuery(
"update comment set spam = 0, ham = 1 where id = #id",
sqlHelper.CreateParameter("#id", Id));
// No email notification required, simply marking spam as ham
}
public void Delete()
{
if (Id < 1) return;
var sqlHelper = DataLayerHelper.CreateSqlHelper(cms.GlobalSettings.DbDSN);
sqlHelper.ExecuteNonQuery("delete from comment where id = #id", sqlHelper.CreateParameter("#id", Id));
Id = -1;
OnCommentDelete(EventArgs.Empty);
// Permanent deletion
}
public void Reject()
{
if (Id < 1) return;
var sqlHelper = DataLayerHelper.CreateSqlHelper(cms.GlobalSettings.DbDSN);
sqlHelper.ExecuteNonQuery("update comment set statusid = 3 where id = #id", sqlHelper.CreateParameter("#id", Id));
//Id = -1;
//OnCommentDelete(EventArgs.Empty);
// Send rejection email
EmailNotification(2);
}
public static Comment MakeNew(int parentNodeId, string name, string email, string website, bool approved, bool spam, DateTime created, string commentText, int statusId)
{
var c = new Comment
{
ParentNodeId = parentNodeId,
Name = name,
Email = email,
Website = website,
Approved = approved,
Spam = spam,
Created = created,
CommenText = commentText,
StatusId = statusId
};
var sqlHelper = DataLayerHelper.CreateSqlHelper(cms.GlobalSettings.DbDSN);
c.Id = sqlHelper.ExecuteScalar<int>(
#"insert into Comment(mainid,nodeid,name,email,website,comment,approved,spam,created,statusid)
values(#mainid,#nodeid,#name,#email,#website,#comment,#approved,#spam,#created,#statusid)",
sqlHelper.CreateParameter("#mainid", -1),
sqlHelper.CreateParameter("#nodeid", c.ParentNodeId),
sqlHelper.CreateParameter("#name", c.Name),
sqlHelper.CreateParameter("#email", c.Email),
sqlHelper.CreateParameter("#website", c.Website),
sqlHelper.CreateParameter("#comment", c.CommenText),
sqlHelper.CreateParameter("#approved", c.Approved),
sqlHelper.CreateParameter("#spam", c.Spam),
sqlHelper.CreateParameter("#created", c.Created),
sqlHelper.CreateParameter("#statusid", c.StatusId));
c.OnCommentCreated(EventArgs.Empty);
if (c.Spam)
{
c.OnCommentSpam(EventArgs.Empty);
}
if (c.Approved)
{
c.OnCommentApproved(EventArgs.Empty);
}
return c;
}
public override string ToString()
{
return #"ParentNodeId " + ParentNodeId + #"
Name " + Name + #"
Email " + Email + #"
Website " + Website + #"
Approved " + Approved + #"
Spam " + Spam + #"
Created "+ Created + #"
CommenText " + CommenText + Environment.NewLine;
}
/// <summary>
/// Send email notification
/// </summary>
public void EmailNotification(int notificationType)
{
var uCommentAdminEmail = Config.GetUCommentSetting("uCommentAdminEmail");
MailAddress to = null;
MailAddress from = new MailAddress(uCommentAdminEmail);
string subject = null;
string body = null;
switch (notificationType)
{
case 1:
// Comment approved
to = new MailAddress("me#mydomain.com");
subject = "Comment approved";
body = #"The comment you posted has been approved";
break;
case 2:
// Comment rejected
to = new MailAddress("me#mydomain.com");
subject = "Comment rejected";
body = #"The comment you posted has been rejected";
break;
}
MailMessage message = new MailMessage(from, to);
message.Subject = subject;
message.Body = body;
SmtpClient client = new SmtpClient();
try
{
client.Send(message);
}
catch (Exception ex)
{
Console.WriteLine("Exception caught in EmailNotification: {0}", ex.ToString());
}
finally
{
//
}
}
}
}
Thanks for any pointers folks!
You can:
Extract it to a static method on static class
Create a singleton class that has an instance method
Create a class and interface for MessageSender and use DI to inject it where it's needed.
It depends on the size of the project: for small ones 1. may be enough, for big and complex (and if you have DI in place) 3 would be required.
What you have here is a public method, but because it's not declared as static (public static void EmailNotification...), it cannot be used without creating an instance of the class that it lives in.
using System;
namespace UComment.Domain
{
public class MyOtherClass
{
public void MyMethod()
{
Comment c = new Comment();
c.EmailNotification(1);
}
}
}
You could declare the method static which would let you call it like this:
using System;
namespace UComment.Domain
{
public class MyOtherClass
{
public void MyMethod()
{
Comment.EmailNotification(1);
}
}
}
If you're trying to use it from a different namespace then you would need to include the namespace either by a using statement or by specifying the full namespace inline.
using System;
using UComment.Domain;
namespace UComment.OtherNamespace
{
public class MyOtherClass
{
public void MyMethod()
{
Comment c = new Comment();
c.EmailNotification(1);
}
}
}
Or
using System;
namespace UComment.OtherNamespace
{
public class MyOtherClass
{
public void MyMethod()
{
UComment.Domain.Comment c = new UComment.Domain.Comment();
c.EmailNotification(1);
}
}
}
You are correct in thinking that if you wish to make this a common method, it should independent of the Comment class. The same limitations that I've just described apply to doing that. In addition, you'll have to make sure that any appropriate using statements are on the new class and that the dependencies within the EmailNotification are accounted for as well.
Your class makes too many things!
Split it in different types, each one has to solve only one type of problem according to Separation of concerns.
Same thing for the email sending, create an EmailSender class (or another name) and centralize the Send method there.
You can also create an interface (e.g. ISmtpClientFactory) to pass to the EmailSender class to abstract the concrete system to send emails and improve the testing experience.
Only on the production environment you really send emails, in the test environment you can use a fake factory to simulate the sending.
public class EmailSender
{
private readonly ISmtpClientFactory factory;
public EmailSender(ISmtpClientFactory factory)
{
this.factory = factory;
}
public void Send(MailMessage message)
{
using (var client = factory.Create())
{
using (message)
{
client.Send(message);
}
}
}
}
new EmailSender(new SmtpClientFactory()).Send(AdviceMessageFactory.Create(...));
You could put it in it's own class (like you already tried) and make the method static.
If this new class was EmailHelper, you would call the method like so:
EmailHelper.EmailNotification(1);
Depending on the namespace of the new class, you may also need a using statement at the top of every file you use it in.
It doesn't look like It should cause any issue If you create a (public) class and have that method in it. That method should accept all the properties it needs to send an email. You can create an instance of that class and call that method.

Neo4jClient Create and Update a Relationship

I have a Neo4j Graphdatabase with access via the Neo4jClient. (It is a .NET client for the REST api of Neo4j)
There is the beginning of a documentation.
What I have done
The connection to the database works.
Client = new GraphClient(new Uri("http://localhost:7474/db/data"));
Client.Connect();
This way I can insert Nodes...
Client.Create(new myNodeClass { name = "Nobody" });
... and query them.
Node<myNodeClass> Node = Client.Get<WordNode>(138);
return Node.Data.name;
What I want to do
I simply want to add and update relationships between Nodes. (The type of relationship have to be numeric.)
Unfortunately there is no documentation about relationships yet.
There is a command named CreateRelationship. But I can't get it work.
Client.CreateRelationship(Neo4jClient.NodeReference<TSourceNode>, TRelationship);
Can you give me an example of adding and updating (numeric) relationships?
There's a lot to be found in the test cases... Such as this:
http://hg.readify.net/neo4jclient/src/4693da483a90/Test/ApiUsageIdeas.cs
I was stuck too then I realized I needed to specify the type parameter of the source node reference parameter in the CreateRelationship method.
In this example, I have created the relationship. I have not yet updated the relationship.
Disclosure(It works on my machine as a console application running visual studio 2012, YMMV)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using Neo4jClient;
namespace Neo4jClientExample
{
class MyConsoleProgram
{
private GraphClient Client {get;set; }
static void Main(string[] args)
{
try{
GraphClient client = new GraphClient(new Uri("http://localhost:7474/db/data"));
client.Connect();
Us us = new Us { Name = "We are Us" };
NodeReference<Us> usRef = client.Create(us);
Console.WriteLine("us node.id: {0}", usRef.Id);
var queryUs = client.Cypher.Start("n", "node(" + usRef.Id + ")").Return<Node<Us>>("n");
Console.WriteLine("Us node name: {0}\n", queryUs.Results.AsEnumerable<Node<Us>>().First().Data);
AllYourBase allYourBase = new AllYourBase { Name = "We are all your base" };
NodeReference<AllYourBase> allYourBaseRef = client.Create(allYourBase);
Console.WriteLine("AllYourBase node.id: {0}",allYourBaseRef.Id);
var queryAllYourBase = client.Cypher.Start("n", "node(" + allYourBaseRef.Id + ")").Return<Node<AllYourBase>>("n");
Console.WriteLine("AllYourBase node name: {0}\n", queryAllYourBase.Results.AsEnumerable<Node<AllYourBase>>().First().Data);
RelationshipReference areBelongToRef = client.CreateRelationship(allYourBaseRef, new AreBelongTo(usRef));
var query = client.Cypher.Start("allyourbase", "node(" + allYourBaseRef.Id + ")").Match("allyourbase-[:ARE_BELONG_TO]->us").Return<Node<AllYourBase>>("allyourbase");
query.ExecuteWithoutResults();
Console.WriteLine("Result of querying for all your base that belongs to us: {0}", query.Results.AsEnumerable<Node<AllYourBase>>().First().Data.Name);
}
catch(Exception ex)
{
Console.WriteLine("{0}", ex.Message);
Console.WriteLine("{0}", ex.InnerException);
}
Console.ReadKey();
}
}
public class Us
{
public string Name {get; set;}
public Us()
{
}
}
public class AllYourBase
{
public string Name { get; set; }
public AllYourBase()
{
}
}
public class AreBelongTo : Relationship, IRelationshipAllowingSourceNode<AllYourBase>,
IRelationshipAllowingTargetNode<Us>
{
public AreBelongTo(NodeReference targetNode)
: base(targetNode)
{}
public const string TypeKey = "ARE_BELONG_TO";
public override string RelationshipTypeKey
{
get { return TypeKey; }
}
}
you could have a look at the tests, http://hg.readify.net/neo4jclient/src/4693da483a90/Test/RelationshipTests.cs or contact the author on the Neo4j mailing list, groups.google.com/group/neo4j ?

Categories