send data from silverlight to asp.net (or php?) when the user click on a button - asp.net

If I click on a button of my Silverlight app, another third-party web app must gets some data.
My experience, until now, has been to create web service functions that you can call when you need, but in this case I have to give the possibility to the customer to "handle the click event on the button". In the actual case the third-party app is ASP.Net, but, if it were possible, I would like to do something portable.
Before to start with some crazy idea that will comes in my mind, I would ask: How would you do that?
Pileggi

I Use This Class To Create And Post a Form Dynamically
public class PassData
{
public static PassData Default = new PassData();
public void Send(string strUrl, Dictionary<string, object> Parameters, string ContainerClientID = "divContainer")
{
var obj = HtmlPage.Document.GetElementById(ContainerClientID);
if (obj != null)
{
HtmlElement divContainer = obj as HtmlElement;
ClearContent((HtmlElement)divContainer);
HtmlElement form = HtmlPage.Document.CreateElement("form");
form.SetAttribute("id", "frmPostData");
form.SetAttribute("name", "frmPostData");
form.SetAttribute("target", "_blank");
form.SetAttribute("method", "POST");
form.SetAttribute("action", strUrl);
if (Parameters != null)
foreach (KeyValuePair<string, object> item in Parameters)
{
HtmlElement hidElement = HtmlPage.Document.CreateElement("input");
hidElement.SetAttribute("name", item.Key);
hidElement.SetAttribute("value", item.Value.ToString());
form.AppendChild(hidElement);
}
divContainer.AppendChild(form);
form.Invoke("submit");
ClearContent((HtmlElement)divContainer);
}
}
private void ClearContent(System.Windows.Browser.HtmlElement obj)
{
foreach (HtmlElement item in obj.Children)
{
obj.RemoveChild(item);
}
}
}
divContainer is id of a div in html

Related

ASP.NET MVC 5 Page Controlled by Active Directory Group

Is it possible to create a page (View) that is strictly controlled by an Active Directory Group?
There is no login for this page, if you are a member of the "VIP" Active Directory group, then the page is rendered, otherwise if not then you can't see it.
First get your current users windows log in
var windowsUserName= HttpContext.Current.User.Identity.WindowsLogin();
Then get all the AD groups for your user using the System.DirectoryServices
using System.DirectoryServices;
public List<string> GetUsersActiveDirectoryGroups(string windowsUserName)
{
try
{
var allUserGroups = new List<string>();
if (windowsUserName == null) return allUserGroups;
var domainConnection = new DirectoryEntry();
var samSearcher = new DirectorySearcher
{
SearchRoot = domainConnection,
Filter = "(samAccountName=" + windowsUserName + ")"
};
samSearcher.PropertiesToLoad.Add("displayName");
var samResult = samSearcher.FindOne();
if (samResult == null) return allUserGroups;
var theUser = samResult.GetDirectoryEntry();
theUser.RefreshCache(new[] { "tokenGroups" });
_bet365EmployeeFullName = theUser.Properties["CN"].Value.ToString();
foreach (byte[] resultBytes in theUser.Properties["tokenGroups"])
{
var mySid = new SecurityIdentifier(resultBytes, 0);
var sidSearcher = new DirectorySearcher
{
SearchRoot = domainConnection,
Filter = "(objectSid=" + mySid.Value + ")"
};
sidSearcher.PropertiesToLoad.Add("name");
var sidResult = sidSearcher.FindOne();
if (sidResult != null)
{
allUserGroups.Add((string)sidResult.Properties["name"][0]);
}
}
return allUserGroups;
}
You now need to map which groups have access to which view in the application.
Once done, the next step is the restricting of the viewing of "Views".
You need to set up a permissions filter that uses the MVC AuthorizeAttribute. Something like the below.
public class PermissionsFilter : AuthorizeAttribute
{
private readonly string _viewName;
public PermissionsFilter(string viewName)
{
_viewName = viewName;
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
//Check to see if users groups has access to the view
//If not redirect to unauthorized page
}
}
I accomplish the above by have a user object held in session. This contains a list of all the application permissions my user has access too. This is the mapping you need to do. I have all my view names stored in the database along with an ID of which AD groups can access them.
Then finally in the controller, decorate the get action for the view accordingly.
[HttpGet]
[PermissionsFilter("ViewName")]
public ActionResult ReturnMyView(int currentFolderID)
{
return View(); //Etc..
}
Well hope that helps!

Caching Results in a Static Variable

I'm using a Linq query to retrieve entities from an SQL server using the Entity Framework. When I update an entitiy, the EF is caching the result. I suspect this is because the ObjectContext is in a static variable (below). The only way to refresh the data using my code below is to call a method and set _db to null when there might be stale data displayed (Eg: in a GridView). Is there a way to just prevent it from caching, or to add some sort of end request handler to call this method on my data layer instead of needing to detect when there may be stale data displayed?
private static ServiceEntities _db;
protected static ServiceEntitiesDb
{
get
{
if (_db == null)
{
_db = new ServiceEntities();
_db.Contacts.MergeOption = MergeOption.OverwriteChanges; // failed
}
return _db;
}
}
public static IEnumerable<Contact> GetContactsByName(string name) {
var items = Db.Contacts;
var filteredName = items.Where(i => (i.Name??string.Empty).IndexOf(name) >=0);
return filteredName;
}
The slightly verbose solution (which I wanted to avoid) is to wrap it in a using block. Ie:
public static IEnumerable<Contact> GetContactsByName(string name) {
var items = Db.Contacts;
var filteredName = items.Where(i => (i.Name??string.Empty).IndexOf(name) >=0);
return filteredName;
}
Becomes
public static IEnumerable<Contact> GetContactsByName(string name) {
using (var db = new SomeContext()) {
var items = db.Contacts;
var filteredName = items.Where(i => (i.Name??string.Empty).IndexOf(name) >=0);
return filteredName;
}
}

fubumvc - simple forms validation using IFailureValidationPolicy

I've been trying to implement form validation correctly and a discussion on fubu mailing list has been the most helpful (http://groups.google.com/group/fubumvc-devel/browse_thread/thread/d54b135fe0254653/12180cd86e9dc50b).
I'm still not entirely clear on certain points, I'm a newbie so I'm going through some yak shaving.
It seems like the example given in the discussion performed the validation within the controller itself using IsValid(model).
I'm trying to avoid this by decorating my input model with validation attributes such as Required and then use the validation configuration to Transfer on failure (via a policy).
this.Validation(x => {
x.Actions
.Include(call => call.HasInput && call.InputType().Name.EndsWith("Input"));
x.Failures
.ApplyPolicy<AccountValidationFailedPolicy>();
});
And here's the class that implments the policy:
public class AccountValidationFailedPolicy : IValidationFailurePolicy {
public bool Matches(ValidationFailure context) {
return (context.InputType() == typeof (RegisterAccountInput));
}
public void Handle(ValidationFailure context) {
var incomingRequest = (RegisterAccountInput) context.InputModel;
var failedValidation = new RegisterationFailedNotification {
CVV = incomingRequest.CVV,
AcceptTerms = incomingRequest.AcceptTerms,
Countries = incomingRequest.Countries,
PhoneNumber = incomingRequest.PhoneNumber,
PIN = incomingRequest.PIN
};
FubuContinuation.TransferTo(failedValidation);
}
}
Handle simply tries to Transfer to another action via a new model, copying the values into the new model so that I can redisplay them again on the form.
I must be doing something wrong here, because it's not transferring anywhere.
I have a class with this method which I was hoping would handle it.
public AccountViewModel New(RegisterationFailedNotification notification) {
....
}
Am I on track here, or is there something fundamental that I'm not getting? Perhaps a policy is not the thing to do here?
#stantona
The policy mechanism will work here. I'll spare you the details about how I plan to make this simpler (very soon), and note that your use of FubuContinuation.TransferTo simply creates a FubuContinuation -- it doesn't execute it.
Here's what you need:
public class AccountValidationFailedPolicy : IValidationFailurePolicy {
private readonly IFubuRequest _request;
private readonly IValidationContinuationHandler _handler;
public AccountValidationFailedPolicy(IFubuRequest request, IValidationContinuationHandler handler) {
_request = request;
_handler = handler;
}
public bool Matches(ValidationFailure context) {
return (context.InputType() == typeof (RegisterAccountInput));
}
public void Handle(ValidationFailure context) {
var incomingRequest = (RegisterAccountInput) context.InputModel;
var failedValidation = new RegisterationFailedNotification {
CVV = incomingRequest.CVV,
AcceptTerms = incomingRequest.AcceptTerms,
Countries = incomingRequest.Countries,
PhoneNumber = incomingRequest.PhoneNumber,
PIN = incomingRequest.PIN
};
var continuation = FubuContinuation.TransferTo(failedValidation);
_request.Set(continuation);
_handler.Handle();
}
}

Unable to hook into PropertyChanged event using MVVM-Light

Greetings, creating my first MVVM based WPF app and trying to figure out why I'm unable to hook into the PropertyChanged event of a dependency property.
Code in the parent view model:
void createClients()
{
var clients = from client in Repository.GetClients()
select new ClientViewModel(Repository, client);
foreach (var client in clients)
{
client.PropertyChanged += onClientPropertyChanged;
}
Clients = new ViewableCollection<ClientViewModel>(clients);
Clients.CollectionChanged += onClientsCollectionChanged;
}
// Never gets called
void onClientPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Name")
{
//...
}
}
ViewableCollection is a simple extension of ObservableCollection to encapsulate a View.
In the ClientViewModel the setters are being called but RaisePropertyChanged isn't working as I would expect, because onClientPropertyChanged isn't being invoked. Both view models inherit from ViewModelBase.
public string Name
{
get { return client.Name; }
set
{
if (value == client.Name) return;
client.Name = value;
RaisePropertyChanged("Name");
}
}
If I wire up PropertyChanged to a method inside the ClientViewModel then it is being fired, so I'm stumped as to why this isn't working in the parent view model. Where am I going wrong?
This SO question explains the problem; ObservableCollection protects the PropertyChanged event.
One solution is to use MVVM-Light Messenger:
void createClients()
{
var clients = from client in Repository.GetClients()
select new ClientViewModel(Repository, client);
Clients = new ViewableCollection<ClientViewModel>(clients);
Clients.CollectionChanged += onClientsCollectionChanged;
Messenger.Default.Register<PropertyChangedMessage<string>>(this, (pcm) =>
{
var clientVM = pcm.Sender as ClientViewModel;
if (clientVM != null && pcm.PropertyName == "Name")
{
// ...
}
});
}
createClients() should be refactored, but for consistency with the question code I'll leave it in there. Then a slight change to the property setter:
public string Name
{
get { return client.Name; }
set
{
if (value == client.Name) return;
string oldValue = client.Name;
client.Name = value;
RaisePropertyChanged<string>("Name", oldValue, value, true);
}
}

How to use ASP.Net server controls inside of Substitution control?

while the method we use in Substitution control should return strings, so how is it possible to use a donut caching in web forms on a server control which should be rendered server side?
for example Loginview control?
UPDATE
This is now a fully working example. There a few things happening here:
Use the call back of a substitution control to render the output of the usercontrol you need.
Use a custom page class that overrides the VerifyRenderingInServerForm and EnableEventValidation to load the control in order to prevent errors from being thrown when the usercontrol contains server controls that require a form tag or event validation.
Here's the markup:
<asp:Substitution runat="server" methodname="GetCustomersByCountry" />
Here's the callback
public string GetCustomersByCountry(string country)
{
CustomerCollection customers = DataContext.GetCustomersByCountry(country);
if (customers.Count > 0)
//RenderView returns the rendered HTML in the context of the callback
return ViewManager.RenderView("customers.ascx", customers);
else
return ViewManager.RenderView("nocustomersfound.ascx");
}
Here's the helper class to render the user control
public class ViewManager
{
private class PageForRenderingUserControl : Page
{
public override void VerifyRenderingInServerForm(Control control)
{ /* Do nothing */ }
public override bool EnableEventValidation
{
get { return false; }
set { /* Do nothing */}
}
}
public static string RenderView(string path, object data)
{
PageForRenderingUserControl pageHolder = new PageForUserControlRendering();
UserControl viewControl = (UserControl) pageHolder.LoadControl(path);
if (data != null)
{
Type viewControlType = viewControl.GetType();
FieldInfo field = viewControlType.GetField("Data");
if (field != null)
{
field.SetValue(viewControl, data);
}
else
{
throw new Exception("ViewFile: " + path + "has no data property");
}
}
pageHolder.Controls.Add(viewControl);
StringWriter result = new StringWriter();
HttpContext.Current.Server.Execute(pageHolder, result, false);
return result.ToString();
}
}
See these related questions:
Turn off page-level caching in a
user control
UserControl’s RenderControl is
asking for a form tag in (C#
.NET)
One thing Micah's answer left out is that the substitution function must be static, accept a HttpContext parameter, and return a string. See this msdn page for more info.
I've also extended Micah's helper class to be a little more flexible.
Markup
<asp:Substitution ID="Substitution1" MethodName="myFunction" runat="server" />
Implemenation
public static string myFunction(HttpContext httpContext){
ViewManager vm = new ViewManager();
//example using a Button control
Button b = new Button();
b.Text = "click me"; //we can set properties like this
//we can also set properties with a Dictionary Collection
Dictionary<string,object> data = new Dictionary<string,object>();
data.add("Visible",true);
String s = vm.RenderView(b,data); //don't do anything (just for example)
//we can also use this class for UserControls
UserControl myControl = vm.GetUserControl("~mypath");
data.clear();
data.add("myProp","some value");
return vm.RenderView(myControl,data); //return for Substitution control
}
Class
using System.IO;
using System.ComponentModel;
public class ViewManager
{
private PageForRenderingUserControl pageHolder;
public ViewManager()
{
pageHolder = new PageForRenderingUserControl();
}
public UserControl GetUserControl(string path)
{
return (UserControl)pageHolder.LoadControl(path);
}
public string RenderView(Control viewControl, Dictionary<string, object> data)
{
pageHolder.Controls.Clear();
//Dim viewControl As UserControl = DirectCast(pageHolder.LoadControl(Path), UserControl)
if (data != null) {
Type viewControlType = viewControl.GetType();
dynamic properties = TypeDescriptor.GetProperties(viewControl);
foreach (string x in data.Keys) {
if ((properties.Item(x) != null)) {
properties.Item(x).SetValue(viewControl, data[x]);
}
}
}
pageHolder.Controls.Add(viewControl);
StringWriter result = new StringWriter();
HttpContext.Current.Server.Execute(pageHolder, result, false);
return result.ToString();
}
private class PageForRenderingUserControl : Page
{
public override void VerifyRenderingInServerForm(Control control)
{
// Do nothing
}
public override bool EnableEventValidation {
get { return false; }
// Do nothing
set { }
}
}
}
Thanks again to Micah for the code
I'm fairly certain you can't do this - the Substitution control will only allow you to insert a string into an outputcached page.
This makes sense if you think about the whole output of a server control, which could be a <table> that'll disrupt all your carefully crafted markup and/or something that requires a load of <script> injected into the page - whereas injecting a single string is something that's relatively straightforward.

Resources