Send DataBase table via observable collection through WCF service and consume it in windowws Phone app - windows

I want to send an observablecollection object through a WCF service and receive it in windows phone 8 app.
the service Is as below.
public ObservableCollection<State> GetName()
{
StateEntities objEntities = new StateEntities();
ObservableCollection<State> stateCollection = new ObservableCollection<State>();
foreach (State s in objEntities.States)
{
stateCollection.Add(s);
}
return stateCollection;
}
State is a Class having data from the table. The contract is given below
public interface IHost
{
[OperationContract]
string DoWork();
[OperationContract]
ObservableCollection<State> GetName();
}
Now I want to consume the service in a windows phone app.
A button click should trigger the service consumption , get data from the service as observable collection and feed it into a gridview.
public sealed partial class MainPage : Page
{
ServiceReference1.HostClient proxy;
public MainPage()
{
proxy = new HostClient();
this.InitializeComponent();
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
ObservableCollection<State> stateCollection = new ObservableCollection<State>();
stateCollection = await proxy.GetNameAsync();
dataGrid.ItemsSource = stateCollection;
}
}
but it is throwing and exception in the await line.
This is the exception.
An exception of type 'System.ServiceModel.CommunicationException'
occurred in mscorlib.dll but was not handled in user code
Additional information: An error occurred while receiving the HTTP
response to "ttp://localhost:65338/Host.svc." This could be due to the
service endpoint binding not using the HTTP protocol. This could also
be due to an HTTP request context being aborted by the server
Can anybody suggest an alternative or solution ?

Related

Store Workflow Activity Data When Publishing

I Need to store a specific activity data in another collection in database whenever a user publish a workflow in elsa.
I dont find any documentation, Please suggest me some resource or suggestion to achieve this. I have try to implement this with middleware. The Middleware code is
namespace WorkFlowV3
{
// You may need to install the Microsoft.AspNetCore.Http.Abstractions package into your project
public class CustomMiddleware
{
private readonly RequestDelegate _next;
static HttpClient client = new HttpClient();
public CustomMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
//Write Custom Logic Here....
client.BaseAddress = new Uri("#");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
string path = "/api/test-middleware-call";
HttpResponseMessage response = await client.GetAsync(path);
await _next(httpContext);
}
}
// Extension method used to add the middleware to the HTTP request pipeline.
public static class CustomMiddlewareExtensions
{
public static IApplicationBuilder UseCustomMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<CustomMiddleware>();
}
}
}
But in this process, I cant fetch the specific activity data.
The easiest way to store information in your own DB in response to the "workflow published" event is by implementing a notification handler (from MediatR) that handles the WorkflowDefinitionPublished notification.
For example:
public class MyWorkflowPublishedhandler : INotificationhandler<WorkflowDefinitionPublished>
{
private readonly IMyDatabaseStore _someRepository;
public MyWorkflowPublishedhandler(IMyDatabaseStore someRepository)
{
_someRepository = someRepository;
}
public async Task Handle(WorkflowDefinitionPublished notification, CancellationToken cancellationToken)
{
var workflowDefinition = notification.WorkflowDefinition;
// Your logic to do a thing.
}
}
To register this handler, from your Startup or Program class, add the following code:
services.AddNotificationHandler<MyWorkflowPublishedhandler>();
Your handler will be invoked every time a workflow gets published.

get access to Adapter and Configuration for IBot

I am using Twitter Adapter Sample.
In class TwitterAdapterSampleBot:IBot
I want to get access to IBotFrameworkHttpAdapter adapter, IConfiguration configuration and ILogger logger, which are created in Startup->ConfigureServices method
I tried simple implement constructor :
public class TwitterAdapterSampleBot : IBot
{
public TwitterAdapterSampleBot(IBotFrameworkHttpAdapter adapter, IConfiguration configuration)
But got internal exception on startup:
System.InvalidOperationException: Unable to resolve service for type 'Microsoft.Bot.Builder.Integration.AspNet.Core.IBotFrameworkHttpAdapter' while attempting to activate 'TwitterAdapter_Sample.TwitterAdapterSampleBot'.
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType, Type implementationType, CallSiteChain callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(Type serviceType, Type implementationType, CallSiteChain callSiteChai
This "IBotFrameworkHttpAdapter" interface using to express the relationship between an mvc api Controller and a Bot Builder Adapter. So you need to resolve the dependency issue with it's implementation.
IBotFrameworkHttpAdapter is implemented in "BotFrameworkHttpAdapter" ( Bot Builder Adapter implementation ) class.
ConfigureServices in Asp.Net Core Startup Class:
services.AddSingleton<IBotFrameworkHttpAdapter, BotFrameworkHttpAdapter>();
You can implement the above scenario in another way for example create a botframework custom adapter error handler class with the implementation of BotFrameworkHttpAdapter.
Microsoft docs example:
public class AdapterWithErrorHandler : BotFrameworkHttpAdapter
{
private static log4net.ILog logger
= log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public AdapterWithErrorHandler(
ICredentialProvider credentialProvider,
ConversationState conversationState = null)
: base(credentialProvider)
{
OnTurnError = async (turnContext, exception) =>
{
// Log any leaked exception from the application.
logger.Error($"Exception caught : {exception.Message}");
// Send a catch-all apology to the user.
await turnContext.SendActivityAsync("Sorry, it looks like something went wrong.");
if (conversationState != null)
{
try
{
// Delete the conversationState for the current conversation to prevent the
// bot from getting stuck in a error-loop caused by being in a bad state.
// ConversationState should be thought of as similar to "cookie-state" in a Web pages.
await conversationState.DeleteAsync(turnContext);
}
catch (Exception e)
{
logger.Error($"Exception caught on attempting to Delete ConversationState : {e.Message}");
}
}
};
}
}
ConfigureServices in Asp.Net Core Startup Class:
// Create the Bot Framework Adapter with error handling enabled.
services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithErrorHandler>();
Reference:
Microsoft V4 docs
BotFrameworkHttpAdapter docs

ShowTypingMiddleware broke my bot when deployed - BotFramework V4

I'm trying to use the ShowTypingMiddleware, a custom middleware already given by BotFramework (see here: https://github.com/microsoft/botbuilder-dotnet/blob/master/libraries/Microsoft.Bot.Builder/ShowTypingMiddleware.cs) to send an typing message to my user while the bot is processing his request. I'm using the BotFramework V4.
It all works locally, but not when I publish it on Azure's WebChat.
I've followed the example in Microsoft's samples, where they create an adapter that adds the desired middleware to the bot pipeline (the sample I've used is here: https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/17.multilingual-bot. The custom adapter I'm referring to is AdapterWithErrorHandler.cs, and it adds the TranslationMiddleware to the pipeline).
Running locally, everything works as planned. The problem is: when I'm publishing it to Azure, the webchat stop working. It throws the following exception:
7‎/‎21‎/‎2019‎ ‎1‎:‎07‎:‎33‎ ‎PM There was an error sending this message to your bot: HTTP status code Unauthorized
‎7‎/‎21‎/‎2019‎ ‎1‎:‎07‎:‎33‎ ‎PM There was an error sending this message to your bot:
HTTP status code Unauthorized
In my StartUp.cs's ConfigureServices, I've injected my custom adapter and my middleware:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
// Create the credential provider to be used with the Bot Framework Adapter.
services.AddSingleton<ICredentialProvider, ConfigurationCredentialProvider>();
// Create the Bot Framework Adapter.
services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithTypingAndErrorHandler>();
// Create the bot as a transient. In this case the ASP Controller is expecting an IBot.
services.AddTransient<IBot, MyBot>();
services.AddSingleton<ShowTypingMiddleware>();
}
My AdapterWithTypingAndErrorHandler is as follows:
public class AdapterWithTypingAndErrorHandler : BotFrameworkHttpAdapter
{
public AdapterWithTypingAndErrorHandler(
IConfiguration configuration,
ILogger<BotFrameworkHttpAdapter> logger,
ShowTypingMiddleware showTypingMiddleware) : base(logger: logger)
{
if (showTypingMiddleware == null)
throw new NullReferenceException($"Could not load '{nameof(showTypingMiddleware)}' in custom adapter.");
AddAdapterToPipeline(showTypingMiddleware);
OnTurnError = async (turnContext, exception) =>
{
logger.LogError($"Exception caught : {exception.Message}");
await turnContext.SendActivityAsync("Sorry, something went wrong :/");
};
}
private void AddAdapterToPipeline(ShowTypingMiddleware showTypingMiddleware)
=> Use(showTypingMiddleware);
}
And I'm using it in my controller:
public class BotController : ControllerBase
{
private readonly IBotFrameworkHttpAdapter Adapter;
private readonly IBot Bot;
public BotController(IBotFrameworkHttpAdapter adapter, IBot bot)
{
Adapter = adapter;
Bot = bot;
}
[HttpPost]
public async Task PostAsync()
{
await Adapter.ProcessAsync(Request, Response, Bot);
}
}
As I said, everything works fine, locally, but when I publish it, the WebChat throws the Unauthorized exception. If I use the default Adapter (the BotFrameworkHttpAdapter.cs one), instead of my customized, it all works fine too.
What should I do?

Alternative to HttpRequestMessage SetContext method

I have this code from codeplex
private async Task ExecuteChangeSet(
ChangeSetRequestItem changeSet,
IList<ODataBatchResponseItem> responses,
CancellationToken cancellation)
{
ChangeSetResponseItem changeSetResponse;
// Create a new ShoppingContext instance, associate it with each of the requests, start a new
// transaction, execute the changeset and then commit or rollback the transaction depending on
// whether the responses were all successful or not.
using (ShoppingContext context = new ShoppingContext())
{
foreach (HttpRequestMessage request in changeSet.Requests)
{
request.SetContext(context);
}
The complete sample code can be found here.
I downloaded the project and it is using .net framework 4.5
but in .NET Framework 4.6.1 the SetContext method is no longer present
I want to know how can I achieve the same in framework version 4.6.1?
I am basically creating a OData V3 Service which will be hosted in IIS.
You can go with creating your own functionality for setting the context and retrieve it where needed, with HttpRequestMessage extensions like:
Example class:
public static class HttpRequestMessageExtensions
{
private const string Context = "ShoppingContext";
public static void SetContext(this HttpRequestMessage request, ShoppingContext context)
{
request.Properties[Context] = context;
}
public static ShoppingContext GetContext(this HttpRequestMessage request)
{
object context;
if (request.Properties.TryGetValue(Context, out context))
{
return (ShoppingContext) context;
}
return null;
}
}
Usage:
//Setting context
request.SetContext(context);
//reading context
var context = request.GetContext();

Google Web Toolkit (GWT) EventBus event firing/handling

Background Story:
I am developing a GWT application, using the standard MVP design pattern, and also using RPC to get data from my custom data handling servlet (does a lot behind the scenes). Anyway, my goal is to create a very simple custom caching mechanism, that stores the data returned from the RPC callback in a static cache POJO. (The callback also sends a custom event using the SimpleEventBus to all registered handlers.) Then when I request the data again, I'll check the cache before doing the RPC server call again. (And also send a custom event using the EventBus).
The Problem:
When I send the event from the RPC callback, everything works fine. The problem is when I send the event outside the RPC callback when I just send the cached object. For some reason this event doesn't make it to my registered handler. Here is some code:
public void callServer(final Object source)
{
if(cachedResponse != null)
{
System.err.println("Getting Response from Cache for: "+ source.getClass().getName());
//Does this actually fire the event?
eventBus.fireEventFromSource(new ResponseEvent(cachedResponse),source);
}
else
{
System.err.println("Getting Response from Server for: "+ source.getClass().getName());
service.callServer(new AsyncCallback<String>(){
#Override
public void onFailure(Throwable caught) {
System.err.println("RPC Call Failed.");
}
#Override
public void onSuccess(String result) {
cachedResponse = result;
eventBus.fireEventFromSource(new ResponseEvent(cachedResponse),source);
}
});
}
}
Now I have two Activities, HelloActivity and GoodbyeActivity (taken from: GWT MVP code)
They also print out messages when the handler is called. Anyway, this is the output I get from the logs: (Not correct)
Getting Response from Cache for: com.hellomvp.client.activity.HelloActivity
Response in GoodbyeActivity from: com.hellomvp.client.activity.HelloActivity
Getting Response from Cache for: com.hellomvp.client.activity.GoodbyeActivity
Response in HelloActivity from: com.hellomvp.client.activity.GoodbyeActivity
What I expect to get is this:
Getting Response from Cache for: com.hellomvp.client.activity.HelloActivity
Response in HelloActivity from: com.hellomvp.client.activity.HelloActivity
Getting Response from Cache for: com.hellomvp.client.activity.GoodbyeActivity
Response in GoodbyeActivity from: com.hellomvp.client.activity.GoodbyeActivity
And I will get this expected output if I change the above code to the following: (This is the entire file this time...)
package com.hellomvp.client;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.hellomvp.events.ResponseEvent;
public class RequestManager {
private EventBus eventBus;
private String cachedResponse;
private HelloServiceAsync service = GWT.create(HelloService.class);
public RequestManager(EventBus eventBus)
{
this.eventBus = eventBus;
}
public void callServer(final Object source)
{
if(cachedResponse != null)
{
System.err.println("Getting Response from Cache for: "+ source.getClass().getName());
service.doNothing(new AsyncCallback<Void>(){
#Override
public void onFailure(Throwable caught) {
System.err.println("RPC Call Failed.");
}
#Override
public void onSuccess(Void result) {
eventBus.fireEventFromSource(new ResponseEvent(cachedResponse),source);
}
});
}
else
{
System.err.println("Getting Response from Server for: "+ source.getClass().getName());
service.callServer(new AsyncCallback<String>(){
#Override
public void onFailure(Throwable caught) {
System.err.println("RPC Call Failed.");
}
#Override
public void onSuccess(String result) {
cachedResponse = result;
eventBus.fireEventFromSource(new ResponseEvent(cachedResponse),source);
}
});
}
}
}
So the point it out, the only change is that I created a new RPC call that does nothing, and send the event in its callback, with the cached data instead, and it causes the application to work as expected.
So the Question:
What am I doing wrong? I don't understand why 'eventBus.fireEvent(...)' Needs to be in an RPC Callback to work properly. I'm thinking this is a threading issue, but I have searched Google in vain for anything that would help.
I have an entire Eclipse project that showcases this issue that I'm having, it can be found at: Eclipse Problem Project Example
Edit: Please note that using eventBus.fireEventFromSource(...) is only being used for debugging purposes, since in my actual GWT Application I have more than one registered Handler for the events. So how do you use EventBus properly?
If I understand your problem correctly you are expecting calls to SimpleEventBus#fireEventFromSource to be routed only to the source object. This is not the case - the event bus will always fire events to all registered handlers. In general the goal of using an EventBus is to decouple the sources of events from their handlers - basing functionality on the source of an event runs counter to this goal.
To get the behavior you want pass an AsyncCallback to your caching RPC client instead of trying to use the EventBus concept in a way other than intended. This has the added benefit of alerting the Activity in question when the RPC call fails:
public class RequestManager {
private String cachedResponse = null;
private HelloServiceAsync service = GWT.create(HelloService.class);
public void callServer(final AsyncCallback<String> callback) {
if (cachedResponse != null) {
callback.onSuccess(cachedResponse);
} else {
service.callServer(new AsyncCallback<String>(){
#Override
public void onFailure(Throwable caught) {
callback.onFailure(caught);
}
#Override
public void onSuccess(String result) {
cachedResponse = result;
callback.onSuccess(cachedResponse);
}
});
}
}
}
And in the Activity:
clientFactory.getRequestManager().callServer(new AsyncCallback<String>() {
#Override
public void onFailure(Throwable caught) {
// Handle failure.
}
#Override
public void onSuccess(String result) {
helloView.showResponse(result);
}
});

Resources