Work with WCF methods Async Call Result - wcf

I am using Silverlight 4 with WCF Services for my database interaction . I am facing one problem.
Function all in silverlight application.
ServiceReference1.WCFSLServicesClient wc = new ServiceReference1.WCFSLServicesClient();
private void button1_Click(object sender, RoutedEventArgs e)
{
_wait = new ManualResetEvent(false);
wc.SayHelloCompleted += new EventHandler<ServiceReference1.SayHelloCompletedEventArgs>(wc_SayHelloCompleted);
wc.SayHelloAsync("Mr. X");
//wait untill the call finish and then move next like
//Here I want to do some thing with result of above call. And then proceed to next task .
}
String Name = String.Empty;
void wc_SayHelloCompleted(object sender, ServiceReference1.SayHelloCompletedEventArgs e)
{
Name =e.Result;
}
But all methods calls in Silver light are Async so I am not able to Get this out.

Put whatever it is you want to do into another method and call that method from your Completed Handler.
void wc_SayHelloCompleted(object sender, ServiceReference1.SayHelloCompletedEventArgs e)
{
Name =e.Result;
MyNewMethod(Name);
}

Related

Is there a way to implement events in SignalR Core Hub?

In my Asp.Net Core application I receive updates from a .Net Client through SignalR Core. With these updates, I try to know the status of a background service that is running on the .Net client.
Some examples:
"Timer has been started successfully."
"Timer has been paused successfully."
"Timer has been resumed successfully."
"Timer could not be started."
I want to use these messages in my Asp.Net Core application and transfer them to the upper layer of my project (Logic layer) by sending events from the Hub (Data access layer).
I can't seem to figure out how to do this and I don't find any documentation regarding this problem.
public class TimerHub : Hub
{
public event EventHandler TimerCouldNotBeStarted;
// Method called by .Net Client
Task TimerStatusUpdate(string message)
{
switch (message)
{
case "Timer could not be started.":
OnTimerCouldNotBeStarted(EventArgs.Empty); // Raise event
break;
}
return Clients.All.SendAsync("EditionStatusUpdate", message);
}
protected virtual void OnTimerCouldNotBeStarted(EventArgs e)
{
TimerCouldNotBeStarted?.Invoke(this, e);
}
}
public class EditionEngine
{
private readonly IHubContext<TimerHub> _timerHubContext;
public EditionEngine(IHubContext<TimerHub> hubContext)
{
_timerHubContext = hubContext;
_timerHubContext.TimerCouldNotBeStarted += TimerNotStarted; // Event is not found in the TimerHub
}
private static void TimerNotStarted(object sender, EventArgs e)
{
Console.WriteLine("Event was raised by Hub");
}
}
In the code example above you can see what I'm trying to accomplish. The problem I'm having is that the event is not accessible in classes outside the hub so I cannot use it.
Change your TimerCouldNotBeStarted event to be a service that you put in DI. Then resolve the service in your Hubs constructor and use it in your methods.
public class TimerHub : Hub
{
private readonly TimeService _timer;
public TimerHub(TimerService timer)
{
_timer = timer;
}
Task TimerStatusUpdate(string message)
{
switch (message)
{
case "Timer could not be started.":
_timer.OnTimerCouldNotBeStarted(EventArgs.Empty); // Raise event
break;
}
return Clients.All.SendAsync("EditionStatusUpdate", message);
}
}

Event for cell add(jgraphx)

I need to make a action when the user make a new cell(drag and drop a cell from editorPallete).
graphComponent.addListener(mxEvent.ADD, new mxEventSource.mxIEventListener() {
#Override
public void invoke(Object sender, mxEventObject evt) {
System.out.println("event add");
}
} );
I do not receive any event for mxEvent.ADD, same result for mxEvent.ADD_CELLS.
You need to add the listener to the graph, not the graphComponent. You also need to use the CELLS_ADDED event instead of the ADD event. You can take a look at the api documentation for the mxGraph class to view a list of fired events for the class: http://jgraph.github.io/mxgraph/docs/js-api/files/view/mxGraph-js.html --> scroll down to the Events section
So your code should look something like this:
graphComponent.getGraph().addListener(mxEvent.CELLS_ADDED, new xEventSource.mxIEventListener() {
#Override
public void invoke(Object sender, mxEventObject evt) {
System.out.println("event add");
}
} );
Hope this helps,

How to setup Active Record Session in WCF

I'm trying to setup a session in Active Record for each WCF request. Here is the code:
[WebGet(UriTemplate = "ReadMessages?authUserId={authUserId}&authGuid={authGuid}&userId={userId}&lastMessageId={lastMessageId}&startDate={startDate}&endDate={endDate}")]
public IQueryable<Message> ReadMessages(int authUserId, string authGuid, uint userId, uint lastMessageId,
DateTime startDate, DateTime endDate)
{
UserUtility.Authenticate(authUserId, authGuid);
using (new SessionScope())
{
//get messages.
return from m in MessageData.FindAll(userId, lastMessageId, startDate, endDate)
select ConvertToView(m);
}
}
Even though I have the SessionScope using block, it still gives me a lazy load error because it's returning an IQueryable and so it's converting to a view, which triggers lazy loading, after it's out of the using block I'm guessing. Here is the error:
Initializing[xxx.Business.Schemas.CommonSchemas.Models.Messaging.Message#6575]-failed to lazily initialize a collection of role: xxx.Business.Schemas.CommonSchemas.Models.Messaging.Message.MessageStatusHistories, no session or session was closed
In my configuration, I have IsRunningWebApp as true.
var source = new InPlaceConfigurationSource();
source.IsRunningInWebApp = true;
If you're wondering why I'm returning IQueryable from a WCF web method, it's because I'm using the WCF Web API (http://wcf.codeplex.com/wikipage?title=WCF%20HTTP), which allows you to query your objects in the url querystring using ODATA.
What am I doing wrong? How do I create a session that lives long enough to lazy load the models as I convert them to views on return from the web methods?
I ended up getting it working using this in my Global.asax:
public void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Items.Add("ar.sessionscope", new SessionScope());
}
public void Application_EndRequest(object sender, EventArgs e)
{
try
{
var scope = HttpContext.Current.Items["ar.sessionscope"] as SessionScope;
if (scope != null)
scope.Dispose();
}
catch (Exception ex)
{
HttpContext.Current.Trace.Warn("Error", "EndRequest: " + ex.Message, ex);
}
}
Note: I also had to remove the using(new SessionScope()) from the web method, that will interfere with the solution above.

Error Object reference not set to an instance of an object on WCF Service

I am currently developing a WCF Publish Subscribe service. My Service has the following code,
public void PublishPost(string postSampleData)
{
PostChangeEventArgs e = new PostChangeEventArgs();
e.PostData = postSampleData;
PostChangeEvent(this, e);
}
and the code for the postChangeEvent is
public class PostChangeEventArgs : EventArgs
{
public string PostData;
}
and in my client file, i wrote this code in the main method,
class Program : IPostingContractCallback
{
static void Main()
{
InstanceContext site = new InstanceContext(null, new Program());
PostingContractClient client = new PostingContractClient(site);
WSDualHttpBinding binding = (WSDualHttpBinding)client.Endpoint.Binding;
String clientcallbackaddress = binding.ClientBaseAddress.AbsoluteUri;
clientcallbackaddress += Guid.NewGuid().ToString();
binding.ClientBaseAddress = new Uri(clientcallbackaddress);
client.Subscribe();
}
public void PostReceived(string postSampleData)
{
MessageBox.Show("PostChange(item {0})", postSampleData);
}
}
and for the code for my data source...
class Program : IPostingContractCallback
{
static void Main(string[] args)
{
InstanceContext site = new InstanceContext(new Program());
PostingContractClient client = new PostingContractClient(site);
client.PublishPost("testing");
Console.WriteLine();
Console.WriteLine("Press ENTER to shut down data source");
Console.ReadLine();
//Closing the client gracefully closes the connection and cleans up resources
client.Close();
}
public void PostReceived(string postSampleData)
{
Console.WriteLine("PostChange(item {0})",postSampleData);
}
}
After running the service, followed by the client, followed by the datasource, I'm suppose to receive a popup messagebox from my client. However there gives an error on the line
PostChangeEvent(this, e);
Object reference not set to an instance of an object.
Anyone know how to solve this?
It sounds like there's nothing subscribed to the event. To check for this, you should use:
var handler = PostChangeEvent;
if (handler != null)
{
handler(this, e);
}
That will stop the NullReferenceException, but of course it won't address why there were no subscribers... you haven't shown anything which subscribes to the event - what were you expecting to be subscribed?

Editing Data in Child Window with RIA Services and Silverlight 4

Is it possible to edit data in a SilverLight Child window when using RIA Services and Silverlight 4? It sounds like a simple enough question, but I have not been able to get any combination of scenarios to work.
Simply put, I am viewing data in a grid that was populated through a DomainDataSource. Instead of editing the data on the same screen (this is the pattern that ALL of the Microsoft samples seem to use), I want to open a child window, edit the data and return. Surely this is a common design pattern.
If anyone knows of a sample out there that uses this pattern, a link would be much appreciated.
Thanks,
Rick Arthur
This is a Microsoft sample that uses a ChildWindow. It uses RIA services, but not MVVM.
It doesn't fix a problem I'm having where entities get attached to my context before I want them to be, but does what you're looking for other than that.
Here's the relevant code to save you downloading the zip:
private void addNewEmployee_Click(object sender, RoutedEventArgs e)
{
EmployeeRegistrationWindow addEmp = new EmployeeRegistrationWindow();
addEmp.Closed += new EventHandler(addEmp_Closed);
addEmp.Show();
}
public partial class EmployeeRegistrationWindow : ChildWindow
{
public EmployeeRegistrationWindow()
{
InitializeComponent();
NewEmployee = new Employee();
addEmployeeDataForm.CurrentItem = NewEmployee;
addEmployeeDataForm.BeginEdit();
}
private void OKButton_Click(object sender, RoutedEventArgs e)
{
addEmployeeDataForm.CommitEdit();
this.DialogResult = true;
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
NewEmployee = null;
addEmployeeDataForm.CancelEdit();
this.DialogResult = false;
}
public Employee NewEmployee { get; set; }
}
The MVVM light Toolkit found here has messeging between viewmodels for more information check above site. Please write if u need an example.