I have a need to pass an HTTP header for each an every RIA Service request being made from a Silverlight app. The value of the header needs to come from the app instance, and not from a cookie. I know this can be accomplished by putting it in the DTOs, but it's not an option because a lot of our service calls use Entities and change sets, so there's no base class to tie into for all requests. So I'm looking for a centralized and safe means to pass something back with each request so the developers do not have to worry with it. A custom HTTP header would work fine, but I don't know how to intercept the outbound request to set it.
Anyone have any ideas I can try?
On the lower level you can add HTTP headers with the help of an IClientMessageInspector. Try starting from this post on SL forum.
The next step depends on your use cases.
If the value of the header must be the same for any method called by the DomainContext, then you may just extend the context using partial class, add a property for the header value and use that property in the inspector.
If you need to pass a different value for each method call, you'd probably need to wrap your DomainContext into another class and add an argument to each method of the context that will accept the header value and pass it to the inspector somehow. Needless to say, without a code-generator this would be hard.
Here's an adapted sample from the SL forum for the first case:
public sealed partial class MyDomainContext
{
public string HeaderValue { get; set; }
partial void OnCreated()
{
WebDomainClient<IMyDomainServiceContract> webDomainClient = (WebDomainClient<IMyDomainServiceContract>)DomainClient;
CustomHeaderEndpointBehavior customHeaderEndpointBehavior = new CustomHeaderEndpointBehavior(this);
webDomainClient.ChannelFactory.Endpoint.Behaviors.Add(customHeaderEndpointBehavior);
}
}
public class CustomHeaderEndpointBehavior : IEndpointBehavior
{
MyDomainContext _Ctx;
public CustomHeaderEndpointBehavior(MyDomainContext ctx)
{
this._Ctx = ctx;
}
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { }
public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
clientRuntime.MessageInspectors.Add(new CustomHeaderMessageInspector(this._Ctx));
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher) { }
public void Validate(ServiceEndpoint endpoint) { }
}
public class CustomHeaderMessageInspector : IClientMessageInspector
{
MyDomainContext _Ctx;
public CustomHeaderMessageInspector(MyDomainContext ctx)
{
this._Ctx = ctx;
}
public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState) {}
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel)
{
string myHeaderName = "X-Foo-Bar";
string myheaderValue = this._Ctx.HeaderValue;
HttpRequestMessageProperty property = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name];
property.Headers[myHeaderName] = myheaderValue;
return null;
}
}
Related
I have an azure function that takes in these parameters (source container, source filename, destination folder, and destination container) and unzips the source filename in the folder in the destination container. There are several actions in the Logic App workflow following the Azure Unzip action that are not completed because the Logic app would timeout after completing the unzipping due to the file size. So Azure function was revamped to be a durable function and I am trying to implement it into my Logic app via the polling action. According to this site, https://medium.com/#jeffhollan/calling-long-running-functions-from-logic-apps-6d7ba5044701, I can use the built-in Azure Functions action but I have no idea what the actual workflow should look like. I am looking for a step by step graphic demonstration on how to implement the durable function via the polling action pattern in my Logic App like depicted on this page, https://yourazurecoach.com/2018/08/19/perform-long-running-logic-apps-tasks-with-durable-functions/ (which shows how to implement it via the webhook action pattern). Any help would be greatly appreciated. Thanks in advance.
After you executing built-in Azure Functions in Logic APP, you will get 202 status code. Then you can handle your business in QueueTrigger.
You can have a look at this sample:
using System.IO;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.WebJobs.Host;
using Newtonsoft.Json;
using System.Threading;
using System.Net.Http;
using System;
namespace HttpToQueueWebhook
{
public static class HttpTrigger
{
[FunctionName("HttpTrigger")]
public static IActionResult Run(
[HttpTrigger(AuthorizationLevel.Function, "post")]HttpRequest req,
TraceWriter log,
[Queue("process")]out ProcessRequest process)
{
log.Info("Webhook request from Logic Apps received.");
string requestBody = new StreamReader(req.Body).ReadToEnd();
dynamic data = JsonConvert.DeserializeObject(requestBody);
string callbackUrl = data?.callbackUrl;
//This will drop a message in a queue that QueueTrigger will pick up
process = new ProcessRequest { callbackUrl = callbackUrl, data = "some data" };
return new AcceptedResult();
}
public static HttpClient client = new HttpClient();
/// <summary>
/// Queue trigger function to pick up item and do long work. Will then invoke
/// the callback URL to have logic app continue
/// </summary>
[FunctionName("QueueTrigger")]
public static void Run([QueueTrigger("process")]ProcessRequest item, TraceWriter log)
{
log.Info($"C# Queue trigger function processed: {item.data}");
//Thread.Sleep(TimeSpan.FromMinutes(3));
//ProcessResponse result = new ProcessResponse { data = "some result data" };
//handle your business here.
client.PostAsJsonAsync<ProcessResponse>(item.callbackUrl, result);
}
}
public class ProcessRequest
{
public string callbackUrl { get; set; }
public string data { get; set; }
}
public class ProcessResponse
{
public string data { get; set; }
}
}
More details, you can refer to this answer logic apps web hook to chalkboard API timeout error.
The Display.ElementSelected event I get in my Alexa Skill,
how does the event get triggered? And how do Handle it in C#? Can you provide a working example.
I implemented an ElementSelected class in my project and I parse the request i receive from Alexa looking for it, but nothing returns. I don't think I'm doing this correctly. This is my class
namespace Alexa.NET.Request.Type
{
public class ElementSelectedRequest : Request
{
private const string type = "Display.ElementSelected";
protected ElementSelectedRequest()
{
this.Type = type;
}
[JsonProperty("token")]
public string Token { get; set; }
}
}
I've seen all the java and javascript examples on github and I still don't understand how it works exactly.
I want to send a form parameter from Chrome Advanced REST Client, however, it comes as null. This my resource class
IKeywordResource.java
#Path("")
public interface IKeywordResource {
#POST
#Path("/upload")
#Consumes("multipart/form-data")
public List<Keyword> uploadKeywords(MultipartFormDataInput uploadFile,
#FormParam("list_format") String listFormat) throws IOException;
}
KeywordResource
public class KeywordResource implements IKeywordResource {
#Inject
public KeywordService keywordService;
#Override
public List<Keyword> uploadKeywords(MultipartFormDataInput uploadFile,
#FormParam("list_format") String listFormat) throws IOException {
return keywordService.upload(uploadFile, listFormat);
}
}
And this is how I send the POST request and define the form parameter.
However, as I said list_format comes as null that I dont know why. I will appreciate for any kind of help
You are trying to map the request payload twice. You can either map all parameters to a MultipartFormDataInput object and retrieve your parameter with uploadFile.getFormDataMap().get("list_format"); or you map each parameter with #FormParam.
I have the following Wcf Data Service:
public class WcfDataService : DataService<WcfDataServiceContext>
{
public static void InitializeService(DataServiceConfiguration config)
{
config.SetEntitySetAccessRule("*", EntitySetRights.All);
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
config.UseVerboseErrors = true;
}
[WebGet]
public IQueryable<Person> GetPeopleByName(string name)
{
WcfDataServiceContext context = this.CurrentDataSource;
var match = from p in context.People
where p.FirstName == name
select p;
return match;
}
I can access the custom method from the browser like this:
http://127.0.0.1:8080/DataService/WcfDataService.svc/GetPeopleByName?name='Daniel'
How can I call that method and get that list of Person from a Silverlight application?
I'm using Visual Studio 2012, Silverlight 5, .NET Framework 4.0.
As far as I remember whe using Silverlight you cannot connect to a different server than the one the Silverlight app came from so you would just use a relative Uri. If you would like to use WCF Data Services client you can take a look here: http://forums.silverlight.net/t/208481.aspx - there is a code snippet that shows it. However AFAIK WCF Data Services client does not support Service Operation so you may need to use XmlReader to be able to query and parse the response of the GetPeopleByName function.
I did it before I can share.Service Reference your domain:8080/DataService/WcfDataService.svc then
For Person object use [DataContract] attribute for properties of Peson use [global::System.Runtime.Serialization.DataMemberAttribute()] By this way you say Serialize and create proxies to Bus side. Notice this attributes because it really works!
//Here is the interface attributes are important
namespace AHBSBus.Web.Services
{
[ServiceContract]
public interface IChatService
{
[OperationContract]
bool LogIn(Guid userID,Guid roomID);
[OperationContract]
bool LogOut(Guid userID,Guid roomID);
[OperationContract]
IEnumerable<VW_CHATUSERDETAIL> GetLatestMessages(Guid userID,Guid roomID,Guid lastSyncMessageID);
[OperationContract]
bool SendMessage(Guid fromID, Guid roomID, Guid toID, string message);
[OperationContract]
IEnumerable<ChatUser> GetLoggedInUsers(Guid roomID);
[OperationContract]
bool IsLogin(Guid roomID,Guid userID);
}
}
//Implementation of service
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public partial class ChatService:IChatService
{
//Here goes
}
In my Silverlight client I have a partial class created by setting a WCF reference. I've extended this class adding a few RelayCommand properties. I need to initialize these properties which I would normally do in the constructor. However it seems that the constructor is not being called, which I believe is a result of of VTS However I'm also unsuccessful in using the OnDeserialized attribute.
What is the prescribed way to initialize client side data members of a WCF class.
I've created a sample project and everything works as expected. If this code doesn't help - post your data contract and client code.
namespace SilverlightApplication3.ServiceReference1
{
public partial class SomeModel
{
public string ExtendedProperty { get; set; }
[OnDeserializing]
public void OnDeserializingMethod(StreamingContext context)
{
this.ExtendedProperty = "Ok";
}
}
}
Service method call:
var proxy = new ServiceReference1.Service1Client();
proxy.DoWorkCompleted += (s,e) => Debug.WriteLine(e.Result.ExtendedProperty); //Ok
proxy.DoWorkAsync();