Call a web service from a Windows Application - winforms

I am new to .NET and C#. I created a Web service, and I am able to view it from a Web page. When I try to call it from a Windows Application, I get the Exception 401 : unauthorized. Code compiles OK, but throws exception when running. This is the code from the Windows App. :
namespace BookStore
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// Create a new instance of a service
localhost.Service1 datasvc = new localhost.Service1();
// Create instance of dataset, using WebService method GetTitleAuthors.
DataSet myData = datasvc.GetTitleAuthors();
// Set DataGrid's datasource to the myData DataSet.
dataGridView1.DataSource = myData;
//Expand all rows.
//dataGridView1.Expand(-1);
//Expand DataTable
//dataGridView1.NavigateTo(0, "Authors");
}
}
}
PS : I am using Windows Authentication in the website that hosts the web service.

I believe there is a property on the generated proxy to the effect of UseDefaultCredentials try setting that to true.
datasvc.UseDefaultCredentials = true;
Although it's been a while I think this will force the service to pass windows credentials.

I don't know what type your Service1 object inherits so I can't say what properties or methods you have associated with it, but whenever I know you can make calls to you web service with using
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(URL);
And then either using
req.UseDefaultCredentials = true;
or
req.Credentials = new NetworkCredential(userName, password);

Related

Specflow-Share browser session between features if triggered between steps

I have implemented Specflow to reuse some steps across features as in this example -Specflow,Selenium-Share data between different Step definitions or classes .Since, in our project, we are integrating multiple features & reusing them. What is the best way to share browser session across features if its triggered in between steps as per the above approach?
My Scenario:
Once an application created, I need to launch new session, login different User-set different services and approve it.
But after logging in fails with below error on Step definition 4 in reused Whenstep of Given(Set the service to (.*)). That particular step is from different feature, hence the new session needs to be used in those steps. The LaunchURl method below is just launching the website with url, no new session created - This works fine
OpenQA.Selenium.WebDriverException : Unexpected error. System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it "IP here"
[Given(#"A New Application is added")]
public void GivenANewApplicationIsAdded()
{
Given("UK_The Service is set");
Given("User Navigated to New Application screen");
When("User fills up form as in data row 1");
Then("new SID generated");
}
[Given(#"New Browser Launched")]
public void GivenNewBrowserLaunched()
{
SeleniumContext sl = new SeleniumContext();
this.seleniumContext = sl;
}
[Given(#"Login is successful with ""(.*)"" and ""(.*)""")]
public void GivenLoginIsSuccessfulWithAnd(string userName, string password)
{
SuperTests spr = new SuperTests();
_driver = spr.LaunchURL(seleniumContext.WebDriver);
//seleniumContext.WebDriver = _driver;
LoginPage lg = new LoginPage(_driver);
lg.LoginProcess(userName, password);
}
[Given(#"Set the service to ""(.*)""")]
public void GivenSetTheServiceTo(string serviceId)
{
When("Select a Service from the option "+serviceId);
Then("The Services is changed to the one selected " + serviceId);
}
In other feature
[When(#"Select a Service from the option (.*)")]
public void WhenSelectAServiceFromTheOptionTestTeam(string p0)
{
HomePage mst = new HomePage(seleniumContext.WebDriver);
mst.SetServiceId(p0);
}
The 2 work around what we figured was
Create a new instance of binding class to call the methods or steps as shown below
[Given(#"Set the service to ""(.*)""")]
public void GivenSetTheServiceTo(string serviceId)
{
var serIdSteps = new UK_SetServiceIDSteps(seleniumContext);
serIdSteps.WhenUK_SelectAServiceFromTheOptionTest(serviceId);
serIdSteps.ThenUK_TheServicesIsChangedToTheOneSelected(serviceId);
}
or
tried this which worked as well- basically calling a new method to create a new session. for this I need not create any new instance for Binding class. Called the Step directly.
[Given(#"New Browser Launched")]
public void GivenNewBrowserLaunched()
{
SuperTests spr = new SuperTests();
_driver = spr.LaunchURL("Firefox");
seleniumContext.WebDriver = _driver;
}
public void GivenSetTheServiceTo(string serviceId)
{
When("UK_Select a Service from the option "+serviceId);
Then("UK_The Services is changed to the one selected " + serviceId);
}
Not sure, which is correct way of doing it? Trying to figure it out from Reusable steps point?The latter one is not advised as we need to change the type of browser to launch at multiple place.

Silverlight application ria service list files in service side

Having a silverlight application, intended to implement backup restore mechanism for the end user.
I have to get list of files in a specific directory resided in WebSite project via ria services.
By using which object I will be able to list files in specific directory of WebSite project.
Thanks for your attention.
You can use the Directory class to enumerate files on the server. Adding a method to your domain service to return the list of file names to the Silverlight client should be fairly trivial after that.
http://msdn.microsoft.com/en-us/library/system.io.directory(v=vs.100).aspx
The answer is some kind of hack. I was inspired by the method that I have used to send client IP address to the service.
In default.aspx add this param to your silverlight object :
<param name="initParams" value="clientIP=<%=Request.UserHostAddress%>,serverPath=<%=Server.MapPath(".")%>" />
And in silverlight application :
public string ClientIP=string.Empty;
public string ServerPath = string.Empty;
private void Application_Startup(object sender, StartupEventArgs e)
{
this.RootVisual = new MainPage();
try
{
ClientIP = e.InitParams["clientIP"].ToString();
ServerPath = e.InitParams["serverPath"].ToString();
}
catch
{
}
}
Consider that I sent client ip to the xap file for logging issues. You can omit it if you care.
and in Silverlight application call service method in this way :
ser.GetFileList(((App)(App.Current)).ServerPath, FilesListReceived, null);
And the service side :
public List<string> GetFileList(string baseDirectory)
{
var result = new List<BRFile>();
var files =Directory.EnumerateFiles( baseDirectory + "\\DBBackup" );
....
}
Good Luck.

Server Variables not making it from my ASP page to my Silverlight App

I have a basic .ASP page like this, which when hit redirects the user to my SL app after adding a value to the session variables
<!-- Default.htm -->
<html>
<%Session("valuekey")=somevalue%>
<Head>
<META http-equiv="Refresh" content="0; URL=/appdirectory/myapp.aspx?lsv=true"></HEAD>
<Body></Body>
</HTML>
When I get to my SL app hosted on myapp.aspx, the first think it does it check for the lsv QueryString. If it equals true, it calls a WCF service with code like
object x = HttpContext.Current.Session["valuekey"];
if(x == null)
{
ServiceError.Message = "No session variable found";
}
else
{
return x.ToString();
}
Does anyone know why the session variable that I just added on the ASP page before the redirect no longer exists when my SL app tried to fetch it?
This answer assumes there is a good reason why ASP classic enters into the equation in the first place. Perhaps its because Silverlight is being introduced into an existing ASP site. The problem is that most Silverlight Client-Server examples involve .NET WCF on the server.
The answer to your problem is don't use a WCF service to fetch your session data. Use a simple ASP page instead. It should be fairly straight-forward to use a simple XML structure to carry the session data you want to the Silverlight app. Use a DTO class that can be used to deserialise the XML into a simple class. Something like this:
(Caveat: air code)
<%
Dim dom: Set dom = CreateObject("MSXML2.DOMDocument.3.0")
dom.loadXML "<SessionData />"
AddElem dom.documentElement, "ValueKey", Session("valuekey")
AddElem dom.documentElement, "SomeOtherValue", Session("othervalue")
''# include other session values needed by client here.
Response.ContentType = "text/xml"
Response.CharSet = "utf-8"
dom.save Response
Sub AddElem(parent, name, value)
Dim elem: Set elem = parent.ownerDocument.createElement(name)
parent.appendChild elem
elem.text = value;
End Sub
%>
In Silverlight:
[DataContract]
public class SessionData
{
[DataMember(Order=1)]
public string ValueKey {get; set; }
[DataMember(Order=2)]
public string SomeOtherValue {get; set; }
public static void Fetch(Action<string> returnResult, Action<exception> fail)
{
WebClient client = new WebClient();
OpenReadCompletedEventHandler eh = null;
eh = (s, args) =>
{
try
{
var sr = new DataControlSerializer(typeof(SessionData));
returnResult((SessionData)sr.ReadObject(args.Result));
}
catch (Exception e)
{
fail(e);
}
finally
{
client.OpenReadAsyncCompleted -= eh;
}
};
client.OpenReadAsyncCompleted += eh;
client.OpenReadAsync(new Uri("../serviceFolder/sessionState.asp", UriKind.Relative));
}
}
Now in some UI or ViewModel you do
void SessionData_Available(SessionData sessionData)
{
_sessionData = sessionData;
// Other actions needed once session data has arrived.
}
void ReportProblem(Exception e)
{
// Some UI change to inform user of failed fetch
}
...
SessionData.Fetch(SessionData_Available, ReportProblem);
Your asp.net session variables are not available to Silverlight. They live in the server only.
Check this simple workaround. It might help you.

Accessing my own datalayer using RIA & Silverlight

Is it possible for me to connect to my own data provide via WCF RIA services?
I've created a small datalayer that connnects to DynamicAX datasource. I would like to use Silverlight 4 & RIA service to access that datalayer.
At it's most basic -I've done the following...
1) I've added an empty domainclass to the webproject and in that class I created a simple method to return a string...
[EnableClientAccess()]
public class ProjectService : DomainService
{
public string TestViaRIA()
{
return "Hello!";
}
}
2) I then added reference to the web project in my silvelight class and created a bit of code to try and invoke the method...
using ProjectApp.Web;
namespace ProjectApp.Views
{
public partial class ProjectControl : UserControl
{
public ProjectControl()
{
InitializeComponent();
ProjectContext ctx = new ProjectContext();
var x = ctx.TestViaRIA();
testTextBox.Text = x.ToString();
}
}
}
the returned value is "{System.ServiceModel.DomainServices.Client.InvokeOperation}".
I'm obviously doing something wrong here and I would appreciate some guidance on how I can achive this.
Add [Invoke] attribute on the method

Download a html file in Silverlight

I'm trying to use the WebClient class to download a html file from another website and present it as a text stream, But I'm getting a security error, what am I doing wrong, or is this another one of Silverlights security "Features"
[code]
namespace ImageScrape
{
public partial class Page : UserControl
{
public Page()
{
InitializeComponent();
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
WebClient cl = new WebClient();
cl.OpenReadCompleted += new OpenReadCompletedEventHandler(cl_OpenReadCompleted);
cl.OpenReadAsync(new Uri(#"http://www.google.co.uk/",UriKind.Absolute));
}
void cl_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
testTextBlock.Text = e.Result.ToString();
}
}
}
[/code]
EDIT
Thanks guys, I was really hoping I wouldn't have to create this as a WCF service as 1) I only know the basics and 2) The idea is that you can use this .xap without having to connect to a central server, mainly because for this I don't have a server that I could host a WCF service on.
Does anyone know a way to get around this, or anywhere that would host a WCF service for free?
I think there are security issues with going directly to another site from the silverlight client.
The best work around for this would be to move this code into a web service and then serve the content you require to client from there.

Resources