Hey there im am running into a situation with the ServiceDescription importer.
In the code (which is pasted below) i am trying to import and compile a service reference from a WSDL file (stored locally) sadly due to customer implications i am not allowed to share this wsdl file.
However all the code runs trough well however the following line:
ServiceDescriptionImportWarnings warnings = importer.Import(nm, unit);
constantly keeps returning: ServiceDescriptionImportWarnings.NoCodeGenerated
could someone tell me if and where i am going wrong with this code ?
public string[] GenerateProxyAssembly(string pathOrURL)
{
Stream stream = File.OpenRead(pathOrURL);
ServiceDescription desc = ServiceDescription.Read(stream);
//find out the number of operations exposed by the web service
//store the name of the operations inside the string array
//iterating only through the first binding exposed as
//the rest of the bindings will have the same number
int i = 0;
Binding binding = desc.Bindings[0];
OperationBindingCollection opColl = binding.Operations;
string[] listOfOperations = new string[opColl.Count];
foreach (OperationBinding operation in opColl)
{
listOfOperations[i++] = operation.Name;
}
//initializing a ServiceDescriptionImporter object
ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
//set the protocol to SOAP 1.1
importer.ProtocolName = "Soap12";
//setting the Style to Client in order to generate client proxy code
importer.Style = ServiceDescriptionImportStyle.Client;
//adding the ServiceDescription to the Importer object
importer.AddServiceDescription(desc, null, null);
importer.CodeGenerationOptions = CodeGenerationOptions.GenerateNewAsync;
//Initialize the CODE DOM tree in which we will import the
//ServiceDescriptionImporter
CodeNamespace nm = new CodeNamespace("test");
CodeCompileUnit unit = new CodeCompileUnit();
unit.Namespaces.Add(nm);
//generating the client proxy code
ServiceDescriptionImportWarnings warnings = importer.Import(nm, unit);
if (warnings == 0)
{
//set the CodeDOMProvider to C# to generate the code in C#
System.IO.StringWriter sw = new System.IO.StringWriter();
CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
provider.GenerateCodeFromCompileUnit(unit, sw, new CodeGeneratorOptions());
//creating TempFileCollection
//the path of the temp folder is hardcoded
TempFileCollection coll = new TempFileCollection(#"C:\wmpub\tempFiles");
coll.KeepFiles = false;
//setting the CompilerParameters for the temporary assembly
string[] refAssembly = { "System.dll", "System.Data.dll",
"System.Web.Services.dll", "System.Xml.dll" };
CompilerParameters param = new CompilerParameters(refAssembly);
param.GenerateInMemory = true;
param.TreatWarningsAsErrors = false;
param.OutputAssembly = "WebServiceReflector.dll";
param.TempFiles = coll;
//compile the generated code into an assembly
//CompilerResults results = provider.CompileAssemblyFromDom(param, unitArr);
CompilerResults results = provider.CompileAssemblyFromSource(param, sw.ToString());
this.assem = results.CompiledAssembly;
}
//return the list of operations exposed by the web service
return listOfOperations;
}
You don't share enough information, but i'll try to anwser.
Protocol could be the issue, i had similar problem, removing this line solved the problem
importer.ProtocolName = "Soap12";
So in my case, i was trying to connect to Soap 1.1 service with wrong protocol setting.
Soap 1.1 is default value.
Please check documentation:
https://learn.microsoft.com/en-us/dotnet/api/system.web.services.description.servicedescriptionimporter.protocolname?view=netframework-4.8
Related
This is a snipped of the c# client I created to query the tensorflow server I set up using this tutorial: https://tensorflow.github.io/serving/serving_inception.html
var channel = new Channel("TFServer:9000", ChannelCredentials.Insecure);
var request = new PredictRequest();
request.ModelSpec = new ModelSpec();
request.ModelSpec.Name = "inception";
var imgBuffer = File.ReadAllBytes(#"sample.jpg");
ByteString jpeg = ByteString.CopyFrom(imgBuffer, 0, imgBuffer.Length);
var jpgeproto = new TensorProto();
jpgeproto.StringVal.Add(jpeg);
jpgeproto.Dtype = DataType.DtStringRef;
request.Inputs.Add("images", jpgeproto); // new TensorProto{TensorContent = jpeg});
PredictionClient client = new PredictionClient(channel);
I found out that most classes needed to be generated from proto files using protoc
The only thing which I cant find is how to construct the TensorProto. The error I keep getting is : Additional information: Status(StatusCode=InvalidArgument, Detail="tensor parsing error: images")
There is a sample client (https://github.com/tensorflow/serving/blob/master/tensorflow_serving/example/inception_client.py) byt my Python skills are not sufficient to understand the last bit.
I also implemented that client in another language (Java).
Try to change
jpgeproto.Dtype = DataType.DtStringRef;
to
jpgeproto.Dtype = DataType.DtString;
You may also need to add a tensor shape with a dimension to your tensor proto. Here's my working solution in Java, should be similar in C#:
TensorShapeProto.Dim dim = TensorShapeProto.Dim.newBuilder().setSize(1).build();
TensorShapeProto shape = TensorShapeProto.newBuilder().addDim(dim).build();
TensorProto proto = TensorProto.newBuilder()
.addStringVal(ByteString.copyFrom(imageBytes))
.setTensorShape(shape)
.setDtype(DataType.DT_STRING)
.build();
ModelSpec spec = ModelSpec.newBuilder().setName("inception").build();
PredictRequest r = PredictRequest.newBuilder()
.setModelSpec(spec)
.putInputs("images", proto).build();
PredictResponse response = blockingStub.predict(r);
I try to create a new EPT (project server 2013) using C# CSOM library.
But It has following error occurred.
"PJClientCallableException: EnterpriseProjectTypeInvalidCreatePDPUid"
Couple of article tell to change the "IsCreate=true". But it does not success for me. Here is the code what I have done.
public void CreateEnterpriseProjectType(Guid eptGuid, string eptName, string eptDescription)
{
ProjectContext pwaContext = new ProjectContext(this.PWA_URL);
EnterpriseProjectTypeCreationInformation eptData = new EnterpriseProjectTypeCreationInformation();
eptData.Id = eptGuid;
eptData.Name = eptName;
eptData.Description = eptDescription;
eptData.IsDefault = false;
eptData.IsManaged = true;
eptData.WorkspaceTemplateName = "PROJECTSITE#0";
eptData.ProjectPlanTemplateId = Guid.Empty;
eptData.WorkflowAssociationId = Guid.Empty;
eptData.Order = 4;
List<ProjectDetailPageCreationInformation> projectDetailPages = new
List<ProjectDetailPageCreationInformation>() {
new ProjectDetailPageCreationInformation() {
Id = pwaContext.ProjectDetailPages[1].Id, IsCreate = true }
};
eptData.ProjectDetailPages = projectDetailPages;
pwaContext.Load(pwaContext.EnterpriseProjectTypes);
pwaContext.ExecuteQuery();
EnterpriseProjectType newEpt = pwaContext.EnterpriseProjectTypes.Add(eptData);
pwaContext.EnterpriseProjectTypes.Update();
pwaContext.ExecuteQuery();
}
Can anyone explain the issue or provide the working code part.
I would like to suggest the following:
Define an enterprise project type:
string basicEpt = "Enterprise Project"; // Basic enterprise project type.
int timeoutSeconds = 10; // The maximum wait time for a queue job, in seconds.
And then, when you create the new project, work like this:
ProjectCreationInformation newProj = new ProjectCreationInformation();
newProj.Id = Guid.NewGuid();
newProj.Name = "Project Name";
newProj.Description = "Test creating a project with CSOM";
newProj.Start = DateTime.Today.Date;
// Setting the EPT GUID is optional. If no EPT is specified, Project Server
// uses the default EPT.
newProj.EnterpriseProjectTypeId = GetEptUid(basicEpt);
PublishedProject newPublishedProj = projContext.Projects.Add(newProj);
QueueJob qJob = projContext.Projects.Update();
// Calling Load and ExecuteQuery for the queue job is optional.
// projContext.Load(qJob);
// projContext.ExecuteQuery();
JobState jobState = projContext.WaitForQueue(qJob, timeoutSeconds);
When the last line of that piece of code ends, the project must be created and published in order to define tasks or whatever.
I don't know what is happening to your code, seems great.
Hope it helps to you,
I can't add the web reference from a wsdl file. I am getting an error.
But it is working normally with SoapUI.
"RPC Message getFaturaResponse in operation getKurumSTFatura has an invalid body name getFaturaResponse. It must be getKurumSTFaturaResponse"
abonePortTypeClient client = new abonePortTypeClient();
if (client.State != CommunicationState.Faulted)
{
string outresult = string.Empty;
var param35 = new AboneClient.SahaIsemri();
param35.tesisatno = 1;
param35.emirturu = 7;
param35.altemirturu = 5;
param35.elemankodu = 3208;
string resultstring = null;
var SahaIsemri = new AboneClient.SahaIsemri();
client.ClientCredentials.UserName.UserName = "XXX";
client.ClientCredentials.UserName.Password = "XXX";
var aaa = client.putSahaIsemri(param35, out resultstring, out SahaIsemri);
}
It refers that the references generated by wsdl does not match.
getFaturaResponse in operation getKurumSTFatura has an invalid body name getFaturaResponse. It must be getKurumSTFaturaResponse
You need to change the Operation in the service or you need to manually change in the reference.cs file.
Search for the particular method and rename the response as above!
#Sajeetharan's answer is fine, but I had some problems finding what I had to rename. Just in case it can help someone, you have to look for the WrapperName in the MessageContractAttribute. In the example above, it would be something like:
[System.ServiceModel.MessageContractAttribute(WrapperName="getKurumSTFatura", WrapperNamespace="xxxx", IsWrapped=true)]
public partial class getFaturaResponse {
I am having problem to consume a WebService programmatically, using the WSDL under a squid proxy. My application is build in c# .net. I compile an Assembly from the XML, after import the service descripton using this:
// a namespace and compile unit are needed by importer
CodeNamespace codeNamespace = new CodeNamespace();
CodeCompileUnit codeUnit = new CodeCompileUnit();
codeUnit.Namespaces.Add(codeNamespace);
ServiceDescriptionImportWarnings importWarnings = descriptionImporter.Import(codeNamespace, codeUnit);
if (importWarnings == 0) // no warnings
{
// create a c# compiler
CodeDomProvider compiler = CodeDomProvider.CreateProvider("CSharp");
// include the assembly references needed to compile
string[] references = new string[2] { "System.Web.Services.dll", "System.Xml.dll" };
CompilerParameters parameters = new CompilerParameters(references);
// compile into assembly
CompilerResults results = compiler.CompileAssemblyFromDom(parameters, codeUnit);
foreach (CompilerError oops in results.Errors)
{
// trap these errors and make them available to exception object
throw new Exception("Compilation Error Creating Assembly");
}
// all done....
return results.CompiledAssembly;
}
else
{
// warnings issued from importers, something wrong with WSDL
throw new Exception("Invalid WSDL");
}
The problem is when i call the method Invoke(obj, args). Proxy cut the connection, if i call the WSDL using external address, like http://My_external_ip/my_webService.asmx. If i call using internal address, works fine.
When i add a webReference, manually, i use to do some thing like:
WebService WS = new WebService();
WS.Proxy = Proxy.credentials;
it work, but i couldn't find where to give the proxy credentials when using Assembly.
Thanks guys.
#Various,
You probebly want to write some code like this
WebService WS = new WebService();
WS.Proxy = wwwproxy("http://someproxy:8080";
WebProxy wwwproxy(string ptProxyURI)
{
var aProxy = New WebProxy;
aProxy.Credentials = CredentialCache.DefaultCredentials;
aProxy.BypassProxyOnLocal = True;
aProxy.Address = New Uri(ptProxyURI);
Return aProxy;
}
Hope it helps.
Cheers
given a url that references an asmx how would i go about displaying all of their method names?
if assembly="http://.../something/something.asmx" and i was trying to display the method names of that service what should i do now that i have gotten myself this far? i cant seem to find a solution among the hundreds of examples ive looked at
public TestReflection(string assembly)
{
Assembly testAssembly = Assembly.LoadFrom(assembly);
Type sType = testAssembly.GetType();
MethodInfo[] methodInfos = typeof(Object).GetMethods();
foreach (MethodInfo methodInfo in methodInfos)
{
Console.WriteLine(methodInfo.Name);
}
}
typeof(Object).GetMethods()
youre asking for all the methods of type object
you need to call GetMethods() on the type you want to get the methods of.
Try this:
public TestReflection(string assembly)
{
Assembly testAssembly = Assembly.LoadFrom(assembly);
Type sType = testAssembly.GetType("NamespaceOfYourClass.NameOfYourClassHere", true, true);
MethodInfo[] methodInfos = sType.GetMethods();
foreach (MethodInfo methodInfo in methodInfos)
{
Console.WriteLine(methodInfo.Name);
}
}
The idea is that in your original code, you're trying to get the methods by using typeof(Object), which will retrieve the methods of the Object type, which is not what you want.
You need to know what class the methods you're trying to grab are in. If you don't know that, replace testAssembly.GetType(... with testAssembly.GetTypes() and iterate through all the types, and getting the methods for each one.
You know, reflection aside, you can actually query the webservice's WSDL to get a list of methods. It may simplify your problem. If you're set on using reflection you'll have to find the type in the assembly and grab the methods using the other methods described in the other answers here.
You would need to look for method decorated with the [WebMethod] attribute on classes that inherit from System.Web.Services.WebService.
The code would look something like this (not tested):
public TestReflection(string assembly)
{
Assembly testAssembly = Assembly.LoadFrom(assembly); // or .LoadFile() here
foreach (Type type in testAssembly.GetTypes())
{
if (type.IsSubclassOf(typeof(System.Web.Services.WebService)))
{
foreach (MethodInfo methodInfo in type.GetMethods())
{
if (Attribute.GetCustomAttribute(methodInfo, typeof(System.Web.Services.WebMethodAttribute)) != null)
{
Console.WriteLine(methodInfo.Name);
}
}
}
}
}
so i figured out how to get what i wanted it goes something like this
[SecurityPermissionAttribute(SecurityAction.Demand, Unrestricted = true)]
internal static void LoadWebService(string webServiceAsmxUrl)
{
ParseUrl(webServiceAsmxUrl);
System.Net.WebClient client = new System.Net.WebClient();
// Connect To the web service
System.IO.Stream stream = client.OpenRead(webServiceAsmxUrl + "?wsdl");
// Now read the WSDL file describing a service.
ServiceDescription description = ServiceDescription.Read(stream);
///// LOAD THE DOM /////////
// Initialize a service description importer.
ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
importer.ProtocolName = "Soap12"; // Use SOAP 1.2.
importer.AddServiceDescription(description, null, null);
// Generate a proxy client.
importer.Style = ServiceDescriptionImportStyle.Client;
// Generate properties to represent primitive values.
importer.CodeGenerationOptions = System.Xml.Serialization.CodeGenerationOptions.GenerateProperties;
// Initialize a Code-DOM tree into which we will import the service.
CodeNamespace nmspace = new CodeNamespace();
CodeCompileUnit unit1 = new CodeCompileUnit();
unit1.Namespaces.Add(nmspace);
// Import the service into the Code-DOM tree. This creates proxy code that uses the service.
ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit1);
if (warning == 0) // If zero then we are good to go
{
// Generate the proxy code
CodeDomProvider provider1 = CodeDomProvider.CreateProvider("CSharp");
// Compile the assembly proxy with the appropriate references
string[] assemblyReferences = new string[5] { "System.dll", "System.Web.Services.dll", "System.Web.dll", "System.Xml.dll", "System.Data.dll" };
CompilerParameters parms = new CompilerParameters(assemblyReferences);
CompilerResults results = provider1.CompileAssemblyFromDom(parms, unit1);
// Check For Errors
if (results.Errors.Count > 0)
{
foreach (CompilerError oops in results.Errors)
{
System.Diagnostics.Debug.WriteLine("========Compiler error============");
System.Diagnostics.Debug.WriteLine(oops.ErrorText);
}
Console.WriteLine("Compile Error Occured calling webservice. Check Debug ouput window.");
}
// Finally, add the web service method to our list of methods to test
//--------------------------------------------------------------------------------------------
object service = results.CompiledAssembly.CreateInstance(serviceName);
Type types = service.GetType();
List<MethodInfo> listMethods = types.GetMethods().ToList();
}
}
Paste http://.../something/something.asmx in your browser and it will give you a list of all the methods and its parameters?