I am currently building an SSIS integration package and as part of this I need to access a webservice. Does anybody know of any C# code that can be used to provide variable values to a webservice and then also GET the value that the web service returns.
The SSIS Web Service Task isn't quite as dynamic as I need it to be. The parameters I need to provide are:
• serverName
• databaseName
• hardwareFingerprint
• userName
Try instead adding a Script Task. Within the code editor, right click on References and choose 'Add Web Reference'. Type in the web service endpoint URI, give it a name local to your project and click 'Add Reference'.
Within your ScriptMain.cs file, add a using statement to point to your new web reference, instantiate the service and make the call.
Some example code:
using Company.WebServices;
namespace ST_abcdef.csproj
{
[System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
public void Main()
{
WebService1 webService1 = new WebService1();
var result = webService1.methodA("param1", "param2");
// process result
}
}
}
Related
I have a C# solution with multiple projects in it.
There is one project called Console which run as a service and this project has a reference to the hostSoftware project (hostSoftware doesn't have a reference to Console, obviously).
I want to transfer a bool value from Console to hostSoftware.
Console: Checks the license and I want to send the bool value to hostSoftware for further checks.
var StatusParameters1 = new StatusParameters();
{
StatusParameters1.Name = "Log";
int returnCode = 0;
bool logStatus = LHandler.GetLogStatus(out LogStatus);
var status = LHandler.ReadLFile(out returnCode);
if (logStatus)
{
if (status.SoftLisenceInfoList[0].SoftId2 == Constants.SoftwareId2)
{
StatusParameters1.Value = LogStatus;
}
else
{
StatusParameters1.Value = false;
}
hostSoftware: I want StatusParameters1.Value in my host project MainWindow.xaml.cs file.
Note: I tried to use a delegate but got this error:
No matching constructor found on type MainWindow
Is there any other approach?
EDIT:
I just discovered that there is another project called ServerService which communicated with Console Project and hostSoftware is communicating with ServerService so the data flow is : Console -> ServerService -> hostSoftware.
ServerService is a service which is being used as Service References in hostSoftware
I can understand that you want your service to verify the client, and then the client can call your service. If so, you can refer to Extending WCF, You can choose a suitable way to add security verification to your service.
I am new to wpf and wcf C# application development and stuck into updating the class where wcf service is referenced. For example, Service has a class of testDbConnect and has various service operation contracts functions defined and implemented in iservice.cs and service.cs. Then in wpf class , this service is added as a reference and works perfect when calls the service functions by button click operation. Like this is what I am testing on button click.
Service1Client service = new Service1Client();
if (service.Testdb() == 1) //Testdb is the function in service which is only returning 1
{
MessageBox.Show("Hello there");
}
The problem I am facing, It perfectly starts service and show the message box( hello there) on button click but when I am updating the code even inside the button click , it still keep showing the hello there message box and not updating code. Maybe there is some proxy generation included but I am not understanding it. It'll be great If someone could explain me in easy words and tell me how It could be solved. Thanks
Based on the way you're consuming your WCF Service you need to update your services references.
Suppose you need to rename int Testdb(); in your service for int TestDb();. You go to your contract (IService1.cs), change the signature to match:
IService1.cs
[ServiceContract]
public interface IService1
{
[OperationContract]
int TestDb();
}
Then go to your service and update your method:
Service1.cs
public class Service1 : IService1
{
public int TestDb()
{
return 1;
}
}
Then, on the server side your good to go, but you need to update your service reference on your client app, so your proxies reflect the new method signature. So in your client app you expand Service References folder, right-click ServiceReference1 - or the name of your service reference - node and select Update Service Reference.
Let Visual Studio update the service reference and then you should be able to call the TestDb method by the new name.
Hope this helps!
I can't seem to find an example of generating proxies from WSDLs with shared types but without having any XSDs to go along with them. Can anyone please mark this as duplicate and point me to an example please?
Here are 2 services, each has its own namespace and a common type. The only thing that is publicly accessible are their WSDLs, there is no type's XSD or its .dll to pass to wsdl.exe /sharedtypes or svcutils and without it I end up with identical class Foo that I can't pass in to SetFoo and class Foo1.
The best I could come up with is generating proxies programmatically and detecting duplicates via CodeDOM, ignoring DataContract/WebServiceBinding namespaces, but it's a huge mess...
[WebService(Namespace = "http://tempuri.org/FOO1")]
public class Service1 : WebService
{
[WebMethod]
public Foo GetFoo()
{
return new Foo();
}
}
[WebService(Namespace = "http://tempuri.org/FOO2")]
public class Service2 : WebService
{
[WebMethod]
public void SetFoo(Foo foo)
{
}
}
public class Foo
{
public int Bar { get; set; }
}
There is a way of doing this, which is outlined here.
In your case you can skip the first step, generate the proxy from service 1 and then use the /r flag on svcutil to reference the service 1 proxy assembly when you generate your service 2 proxy.
This will ensure your service 2 proxy will use the same instance of Foo from your service 1 proxy.
However, have you considered just hosting a single service with two operations? It would save you a lot of work.
Edit: Also have a look at this post:
http://blogs.msdn.com/b/youssefm/archive/2009/10/09/reusing-types-in-referenced-assemblies-with-svcutil-s-r-switch.aspx
First off, you need to set the [DataContract(Namespace="some namespace here")] for all common service data types, otherwise when the WSDL and XSDs are generated then you will have objects from two difference namespace --- this is absolutely essential. The namespace value will only apply to the types defined in the XSD and not in the WSDL. XSD = data, WSDL = service.
The XSDs and WSDL and generated if, and only if, you have the META service behavior set - add this behavior and then you can navigate to the URL. The URL of the META service behavior will then have a link to your WSDLs and XSDs.
I use the following piece of code to self-host services in windows services rather than through IIS, however the same principals apply....
/// <summary>
/// Enables meta data output for a service host.
/// </summary>
/// <param name="host">The service host.</param>
/// <remarks>Must be invoked prior to starting the service host.</remarks>
public static void SetupMetaDataBehaviour(ServiceHost host)
{
ServiceMetadataBehavior metaDataBehaviour = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (metaDataBehaviour == null)
{
metaDataBehaviour = new ServiceMetadataBehavior();
metaDataBehaviour.HttpGetEnabled = true;
host.Description.Behaviors.Add(metaDataBehaviour);
}
else
{
metaDataBehaviour.HttpGetEnabled = true;
}
}
after adding your two web references:
double click on the second web service reference
in the object browser navigate to the definition of Foo
right click on Foo and choose go to definition
delete the definition for the class Foo
add a using statement for the namespace of webservice one
find and replace all instances of <namespace-of-service-reference-2>.Foo with just Foo
This should fix your problem as it forces the autogenerated code for both service references to use the same class declaration.
I'm running two instances of VS2010 on my local machine. One instance is running my Web Service (written in C#). The other instance is running my MVC web app (also C#). The MVC web app has a reference to the web service. I can successfully invoke web service methods from within the MVC app.
In my web service is a PageNavigation class:
// PageNavigation.cs
using System;
using System.Collections.Generic;
using System.Text;
public class PageNavigation
{
public string Page_Number { get; set; }
public string Page_Count { get; set; }
public PageNavigation()
{
Page_Number = "1";
Page_Count = "2";
}
}
By default, this should return an object with auto-implemented properties when I call the class constructor:
WebService.PageNavigation pageNavigation = new WebService.PageNavigation();
This works when constructing a PageNavigation object elsewhere in the web service.
pageNavigation.Page_Number
"1"
pageNavigation.Page_Count
"2"
However, running the same line of code on the MVC isn't giving the same result; the object's properties are all null values.
pageNavigation.Page_Number
null
pageNavigation.Page_Count
null
Is this the expected behavior? Is there a way to populate the properties with default values as intended? If more information is needed please let me know and I will update the question.
The service reference only sees the schema of your object, not business logic; in your case, your service reference just created a shell data type in the MVC application. When you create a service reference, it's actually creating another type with the same property names and types as the type defined in the service.
For your particular scenario (simply providing default property values and not more general business logic), you should be able to apply the [System.ComponentModel.DefaultValue] attribute to your properties in order for the class generator to recognize that these properties should be populated with a default value.
Incidentally, if the service reference were reusing existing types (if you had this type in a common library that was referenced both by the service and the application, for example), then your business logic would be intact.
An alternative would be to implement a factory pattern, whereby you call a function on the web service that instantiates (and optionally populates) the data object, then returns it to the client.
Yes, this is expected behaviour. The MVC site is not actually using your PageNavigation class. It is a simple copy (generated when you add the web service reference) containing of all the properties, but none of the methods, including the constructor.
You could work around this by refactoring your service so the entities are in a separate assembly and then you can reuse this assembly on the client as an option when you generate the proxy.
If you insist on using the same types between client and service, then on the "Advanced" tab of the "Add Service Reference" dialog, you can choose to reuse the types in your server assembly.
I would move that class out of the service and into a class library project referenced by the service and by the client.
And I wouldn't do this for such a small reason as default values. this violates SOA by coupling the service and the client. It will obviously not work for clients which are not running .NET.
What serializer are you using to deserialize the response from the server? Some of them (like the DataContractSerializer for example) do not call the default constructor.
The solution that you should use if you are in fact using DataContractSerializer is to use the OnDeserialized attribute like this:
using System.Runtime.Serialization;
public class PageNavigation
{
public string Page_Number { get; set; }
public string Page_Count { get; set; }
public PageNavigation()
{
Init();
}
[OnDeserialize]
void Init()
{
Page_Number = "1";
Page_Count = "2";
}
}
I created a WebService using the .NET 2.0 framework, a class based on an interface that has the WebServiceAttribute and hosting it using IIS and a ASMX file. The WebService currently loads its configuration from one XML file.
I'd like to create multiple instance of this service where each loads it own configuration.
By coping the ASMX file I can create a clone of the webservice under a different name which will be based on exact the same implementation. But it also loads the exact same configuration file which makes it rather useless.
So my question is: What is the best way to create an arbitrary number of WebServices that are based on one class, living in one IIS virtual directory where each is loading a different configuration file?
Solution
With the help of Pavel Chuchuva's answer I created the following code to handle the loading of the configuration:
public class WebConfigManager
{
public static T Load<T>() where T: new()
{
string location =
HttpContext.Current.Request.PhysicalPath + ".config";
if (HttpContext.Current.Cache[location] is T)
{
return (T)HttpContext.Current.Cache[location];
}
using (Stream s =
new FileStream(location, FileMode.Open, FileAccess.Read))
{
return (T)(HttpContext.Current.Cache[location] =
new XmlSerializer(typeof(T)).Deserialize(s));
}
}
}
// example of the usage of WebConfigManager
public class MyWebService : IMyWebService
{
Config config = WebConfigManager.Load<Config>();
...
Copy and paste .asmx file to create multiple instances of your web service (e.g. Service1.asmx, Service2.asmx and so on).
Load configuration file based on Context.Request.FilePath value:
public string LoadConfig()
{
string configPath = Server.MapPath(this.Context.Request.FilePath + ".xml");
using (XmlReader reader = XmlReader.Create(configPath))
{
// Will read Service1.asmx.xml, Service2.asmx.xml and so on
}
}
I suggest placing the asmx in different folders and placing a web.config in each of those folders with the setting for that specific instance of the web service. This is the easy and fast way
OR
you could use Web Service Enhancements 3.0 and create a WSE router, redirect a calls to a ASMX to that router and let the router forward the call to the right web service instance and pass additional config. This a more complex way of doing it but it enables u to use a single instance of the web service that's picks the right configuration based on the parameters the router passes it.
For more info on WSE3.0 I point you to the MSDN.
Hope this helps!