Using the same class library in windows application and web service - winforms

I working with:
Class Library: Model.dll
using System;
using System.Collections.Generic;
using System.Text;
namespace root
{
public class Customer
{
private int _Id;
public int Id
{
get { return _Id; }
set { _Id = value; }
}
private string _Name;
public string Name
{
get { return _Name; }
set { _Name = value; }
}
}
}
ASP.NET Web Service with reference to Model.dll so i can use in web method:
[WebMethod]
public string HelloWorld(root.Customer customer) {
return "Hello World";
}
Windows Application with reference to both Model.dll and Web Service (1).
root.Customer newCustomer = new Customer();
newCustomer.Id = 1;
newCustomer.Name = "Name";
ws.Service ws = new root.ws.Service();
ws.HelloWorld(newCustomer);
^ problem here
Error: Argument '1': cannot convert from 'root.Customer' to 'root.ws.Customer'
(1) Right click -> And Web Reference -> Web services in this solution -> Click Service.asmx ->
Enter Web reference name: ws -> Click Add reference
Updated: I can change line in generated Reference.cs file from
public string HelloWorld(Customer customer)
to
public string HelloWorld(root.Customer customer)
So function will be looking for real model instead of proxy object, but is not real answer.
I don't event think about editing this file after each web reference update.
How to force this for using real model?

I am afraid that reusing types in automatically generated ASMX proxies is impossible.
There are three options.
1) write your own code generator that will act like the wsdl.exe i.e. build a proxy of your web service but reusing your specified types
(rather difficult)
2) write your own code rewriter that will rewrite proxies generated automatically to use your own types. You'd invoke such rewriter each time after you build up your reference to the web service
(still tedious)
3) switch to WCF web services. a WCF service on a basicHttpBinding is semantically equivalent to a ASMX web service (uses the same communication protocol based on http + soap) but the WCF service metadata contain more information about types so that the proxy generator is able to "reuse types from referenced assemblies".
(suggested approach)

If you switch away from asmx and start using WCF's svc model, you can share a library between the server and client without much fuss at all. If that is an option, there are plenty of resources to help you out with WCF online.

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.

WCF RIA Services DomainService error: ContractDescription has zero operations; a contract must have at least one operation

I am developing a small instant messaging application that makes use of few DomainServices on the server side. Trying to access the domain service URL, I encounter the following error:
"ContractDescription 'AppInitService' has zero operations; a contract must have at least one operation".
The domain service Url is this one:
http://givemeword.net/chat/Services/IM-Chat-UI-Web-DomainServices-AppInitService.svc
You can find the domain service class below:
namespace Chat.UI.Web.DomainServices
{
[EnableClientAccess()]
public class AppInitService : DomainService
{
private System.Security.Principal.IPrincipal _user;
private readonly Chat.UI.Web.Services.AppInitService _appInitService;
public AppInitService()
{
_appInitService = new Chat.UI.Web.Services.AppInitService();
}
public InitUserSettingsDTO InitUserSettings(Guid userId)
{
var initUserSettingsDTO = new InitUserSettingsDTO();
return initUserSettingsDTO;
}
}
}
As you can see, I am using a complex type as the return type of the only function of the domain service.
What I can not figure out is why on my testing Windows Server 2012 (not a development machine, just a virtual machine used for testing) or on my development machine everything runs without any problem, but on the hosting account it raise the error above.
Does anyone has any idea about this?
Thank you
Try adding the [Invoke] attribute to your InitUserSettings method:
[Invoke]
public InitUserSettingsDTO InitUserSettings(Guid userId)
{
var initUserSettingsDTO = new InitUserSettingsDTO();
return initUserSettingsDTO;
}
Make sure your web.config is set up as described here: http://msdn.microsoft.com/en-us/library/ff426912(v=vs.91).aspx
Being exasperated with this strange situation and the low support I received from the web hosting company, I have tried the same thing with another web provider. As I was thinking, it was working this time with no problems, so my assumption that the original provider had poor support for WCF RIA Services (or maybe other unidentified problem) was correct.

WCF sending information to WPF application

I want to send data from WCF to my desktop application while executing a service method.
The WCF service is hosted in windows service.
For example: In my service I am counting from 1 to 100 and when I am hitting 10,20,30 etc I want to set that value on my textbox.
This may be done using duplex channels services:
http://msdn.microsoft.com/en-us/library/ms731064.aspx
Be careful however : this will not work if the server can't reach the client : for example if you are behind a proxy.
I've simpy passed that with get/set like below: (Maybe someone will search smthing similar in future)
public class CallbackHandler : WCFService.IWCFServiceCallback
{
public ListBox LtBox { get; set; }
public void Message(string result)
{
LtBox.Items.Add(result);
}
}
InstanceContext instanceContext = new InstanceContext(new CallbackHandler() { LtBox=this.ltBox });
Where ltBox is my Listbox in desktop application.
Thanks all for help.

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.

How do I call custom methods in a Wcf Data Service from a Silverlight application?

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
}

Resources