Hello.
I'm trying to build a client using .NET/C# that is capable of
communicating with an existing Webservice written in Java using Apache
Axis. Now, I've encountered a problem trying to retrieve binary data
(i.e. downloading files) which is sent by the service using the "SOAP
with attachments" format (as per
http://www.w3.org/TR/SOAP-attachments), i.e. as a MIME
multipart/related message. Apparently, the.NET Webservice library does
not seem to understand this form of message, at least I've not found a
way to make it accept one. The WSE doesn't help either, from what I
gather, it only provides support for DIME, which in turn the Web
Service is unable to provide.
The only promising approach I've found so far would be to create a
SoapExtension class (similar to what is described in the article at
http://msdn.microsoft.com/msdnmag/i...ds/default.aspx)
which, when added to the WebMethods that return MIME messages,
intercepts the response stream, parses the MIME content, extracts the
XML body and replaces the original MIME content with it and ... well, I
admit I'm not that far yet, but I suppose I just have to save the
attachments somewhere and find a way to pass them to the client calling
the method.
However, this seems to be a lot of work compared to the relative ease
with which it was possible to interface with other WebService methods
that didn't involve attachments, especially because it would require me
to write my own MIME parser... So if there's an easier way, I'd love to
hear about it. Any suggestions would be welcome. Thanks.
Receiving a MIME attachment from a webservice.
Bind SOAP response to Gridview using proxy code (request for sample code)
Being a junior ASP Net developer I would like to bind the SOAP response from a web service in ASP Net C# to a gridview via the web proxy.
Following SOAP response:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<GetQueueStatsResponse xmlns="http://www.tix.nl/CtiWebService">
<GetQueueStatsResult xmlns:a="http://schemas.datacontract.org/2004/07/Cti.WebServices" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:QueueInfo>
<a:Name>IP Office Phone: 4201</a:Name>
<a:Statistics>
<a:QueueStat>
<a:AverageWaitTime>0</a:AverageWaitTime>
<a:CallCount>0</a:CallCount>
</a:QueueStat>
<a:QueueStat>
<a:AverageWaitTime>0</a:AverageWaitTime>
<a:CallCount>0</a:CallCount>
</a:QueueStat>
<a:QueueStat>
<a:AverageWaitTime>20</a:AverageWaitTime>
<a:CallCount>2</a:CallCount>
</a:QueueStat>
<a:QueueStat>
<a:AverageWaitTime>14</a:AverageWaitTime>
<a:CallCount>4</a:CallCount>
</a:QueueStat>
<a:QueueStat>
<a:AverageWaitTime>81</a:AverageWaitTime>
<a:CallCount>22</a:CallCount>
</a:QueueStat>
</a:Statistics>
<a:WaitingCalls>
<a:WaitingCall>
<a:CallStart>2018-06-06T16:17:52.3621524+02:00</a:CallStart>
<a:CalledID>4201</a:CalledID>
<a:CallerID>3939</a:CallerID>
</a:WaitingCall>
<a:WaitingCall>
<a:CallStart>2018-06-06T16:19:12.734228+02:00</a:CallStart>
<a:CalledID>4201</a:CalledID>
<a:CallerID>0356991500</a:CallerID>
</a:WaitingCall>
</a:WaitingCalls>
</a:QueueInfo>
<a:QueueInfo>
<a:Name>IP Office Phone: 4202</a:Name>
<a:Statistics>
<a:QueueStat>
<a:AverageWaitTime>0</a:AverageWaitTime>
<a:CallCount>0</a:CallCount>
</a:QueueStat>
<a:QueueStat>
<a:AverageWaitTime>0</a:AverageWaitTime>
<a:CallCount>0</a:CallCount>
</a:QueueStat>
<a:QueueStat>
<a:AverageWaitTime>0</a:AverageWaitTime>
<a:CallCount>0</a:CallCount>
</a:QueueStat>
<a:QueueStat>
<a:AverageWaitTime>0</a:AverageWaitTime>
<a:CallCount>0</a:CallCount>
</a:QueueStat>
<a:QueueStat>
<a:AverageWaitTime>118</a:AverageWaitTime>
<a:CallCount>3</a:CallCount>
</a:QueueStat>
</a:Statistics>
<a:WaitingCalls/>
</a:QueueInfo>
<a:QueueInfo>
<a:Name>IP Office Phone: 4204</a:Name>
<a:Statistics>
<a:QueueStat>
<a:AverageWaitTime>0</a:AverageWaitTime>
<a:CallCount>0</a:CallCount>
</a:QueueStat>
<a:QueueStat>
<a:AverageWaitTime>0</a:AverageWaitTime>
<a:CallCount>0</a:CallCount>
</a:QueueStat>
<a:QueueStat>
<a:AverageWaitTime>0</a:AverageWaitTime>
<a:CallCount>0</a:CallCount>
</a:QueueStat>
<a:QueueStat>
<a:AverageWaitTime>0</a:AverageWaitTime>
<a:CallCount>0</a:CallCount>
</a:QueueStat>
<a:QueueStat>
<a:AverageWaitTime>38</a:AverageWaitTime>
<a:CallCount>13</a:CallCount>
</a:QueueStat>
</a:Statistics>
<a:WaitingCalls/>
</a:QueueInfo>
</GetQueueStatsResult>
</GetQueueStatsResponse>
</s:Body>
</s:Envelope>
Following Web Application I am able only to bind the Name field to the gridview, do you have some sample code to loop through the SOAP response elements,
namespace WebApplication1
{
public partial class WebForm1 : System.Web.UI.Page
{
public object XMLReader { get; private set; }
protected void Page_Load(object sender, EventArgs e)
{
using (var proxy = new WebApplication1.ServiceReference2.CtiWebServiceClient())
{
ServiceReference2.QueueInfo[] data = proxy.GetQueueStats();
GridView1.DataSource = data;
GridView1.DataBind();
For example how to loop through the elements, access the element AverageWaitTime, how to do a count of the number of waiting calls using the proxy code (XML code below is working)? Thank you in advance for your response.
document.Load(Server.MapPath("~/xmlstart/test.xml"));
XmlNamespaceManager manager = new XmlNamespaceManager(document.NameTable);
manager.AddNamespace("a", "http://schemas.datacontract.org/2004/07/Cti.WebServices");
XmlNodeList xnList = document.SelectNodes("//a:QueueStat", manager);
int nodes = xnList.Count;
foreach (XmlNode xn in xnList)
{
AverageWaitTime.Text += xn["a:AverageWaitTime"].InnerText + "<br />";
CallCount.Text += xn["a:CallCount"].InnerText + "<br />";
}
LabelWaitingCallCountHuntgroep1.Text = nodes2.ToString();
Web Reference code is as follows:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace WebApplication1.ServiceReference2 {
using System.Runtime.Serialization;
using System;
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="QueueInfo", Namespace="http://schemas.datacontract.org/2004/07/Cti.WebServices")]
[System.SerializableAttribute()]
public partial class QueueInfo : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged {
[System.NonSerializedAttribute()]
private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string NameField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private WebApplication1.ServiceReference2.QueueStat[] StatisticsField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private WebApplication1.ServiceReference2.WaitingCall[] WaitingCallsField;
[global::System.ComponentModel.BrowsableAttribute(false)]
public System.Runtime.Serialization.ExtensionDataObject ExtensionData {
get {
return this.extensionDataField;
}
set {
this.extensionDataField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string Name {
get {
return this.NameField;
}
set {
if ((object.ReferenceEquals(this.NameField, value) != true)) {
this.NameField = value;
this.RaisePropertyChanged("Name");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public WebApplication1.ServiceReference2.QueueStat[] Statistics {
get {
return this.StatisticsField;
}
set {
if ((object.ReferenceEquals(this.StatisticsField, value) != true)) {
this.StatisticsField = value;
this.RaisePropertyChanged("Statistics");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public WebApplication1.ServiceReference2.WaitingCall[] WaitingCalls {
get {
return this.WaitingCallsField;
}
set {
if ((object.ReferenceEquals(this.WaitingCallsField, value) != true)) {
this.WaitingCallsField = value;
this.RaisePropertyChanged("WaitingCalls");
}
}
}
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName) {
System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
if ((propertyChanged != null)) {
propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="QueueStat", Namespace="http://schemas.datacontract.org/2004/07/Cti.WebServices")]
[System.SerializableAttribute()]
public partial class QueueStat : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged {
[System.NonSerializedAttribute()]
private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private int AverageWaitTimeField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private int CallCountField;
[global::System.ComponentModel.BrowsableAttribute(false)]
public System.Runtime.Serialization.ExtensionDataObject ExtensionData {
get {
return this.extensionDataField;
}
set {
this.extensionDataField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public int AverageWaitTime {
get {
return this.AverageWaitTimeField;
}
set {
if ((this.AverageWaitTimeField.Equals(value) != true)) {
this.AverageWaitTimeField = value;
this.RaisePropertyChanged("AverageWaitTime");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public int CallCount {
get {
return this.CallCountField;
}
set {
if ((this.CallCountField.Equals(value) != true)) {
this.CallCountField = value;
this.RaisePropertyChanged("CallCount");
}
}
}
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName) {
System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
if ((propertyChanged != null)) {
propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="WaitingCall", Namespace="http://schemas.datacontract.org/2004/07/Cti.WebServices")]
[System.SerializableAttribute()]
public partial class WaitingCall : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged {
[System.NonSerializedAttribute()]
private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private System.DateTime CallStartField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string CalledIDField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string CallerIDField;
[global::System.ComponentModel.BrowsableAttribute(false)]
public System.Runtime.Serialization.ExtensionDataObject ExtensionData {
get {
return this.extensionDataField;
}
set {
this.extensionDataField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public System.DateTime CallStart {
get {
return this.CallStartField;
}
set {
if ((this.CallStartField.Equals(value) != true)) {
this.CallStartField = value;
this.RaisePropertyChanged("CallStart");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string CalledID {
get {
return this.CalledIDField;
}
set {
if ((object.ReferenceEquals(this.CalledIDField, value) != true)) {
this.CalledIDField = value;
this.RaisePropertyChanged("CalledID");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string CallerID {
get {
return this.CallerIDField;
}
set {
if ((object.ReferenceEquals(this.CallerIDField, value) != true)) {
this.CallerIDField = value;
this.RaisePropertyChanged("CallerID");
}
}
}
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName) {
System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
if ((propertyChanged != null)) {
propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://www.tix.nl/CtiWebService", ConfigurationName="ServiceReference2.ICtiWebService")]
public interface ICtiWebService {
[System.ServiceModel.OperationContractAttribute(Action="http://www.tix.nl/CtiWebService/ICtiWebService/GetQueueStats", ReplyAction="http://www.tix.nl/CtiWebService/ICtiWebService/GetQueueStatsResponse")]
WebApplication1.ServiceReference2.QueueInfo[] GetQueueStats();
[System.ServiceModel.OperationContractAttribute(Action="http://www.tix.nl/CtiWebService/ICtiWebService/GetQueueStats", ReplyAction="http://www.tix.nl/CtiWebService/ICtiWebService/GetQueueStatsResponse")]
System.Threading.Tasks.Task<WebApplication1.ServiceReference2.QueueInfo[]> GetQueueStatsAsync();
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface ICtiWebServiceChannel : WebApplication1.ServiceReference2.ICtiWebService, System.ServiceModel.IClientChannel {
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class CtiWebServiceClient : System.ServiceModel.ClientBase<WebApplication1.ServiceReference2.ICtiWebService>, WebApplication1.ServiceReference2.ICtiWebService {
public CtiWebServiceClient() {
}
public CtiWebServiceClient(string endpointConfigurationName) :
base(endpointConfigurationName) {
}
public CtiWebServiceClient(string endpointConfigurationName, string remoteAddress) :
base(endpointConfigurationName, remoteAddress) {
}
public CtiWebServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress) {
}
public CtiWebServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress) {
}
public WebApplication1.ServiceReference2.QueueInfo[] GetQueueStats() {
return base.Channel.GetQueueStats();
}
public System.Threading.Tasks.Task<WebApplication1.ServiceReference2.QueueInfo[]> GetQueueStatsAsync() {
return base.Channel.GetQueueStatsAsync();
}
}
}
WebMethod to accept XML from HTTP Post
2 days I've been on this and I don't think it should be too difficult, but it seems to be.
I am writing a web service to provide web methods. For example, I have a method called AddCustomer. It sits there and waits for a client to connect to it. The idea is that the client will send me an HTTP Post with XML as the content type. I am having trouble setting this up.
[WebMethod] public string AddCustomer(string xmlCustomer) { return (String)PostCustomerInternal(xmlCustomer); }
I do not know if my parameter type is correct, so if I shouldn't be picking up a string, tell me. You can see this function just calls an internal function called PostCustomerInternal. I don't know why, but that is how I have been told they want it. Now, the next function:
public string PostCustomerInternal(string xmlCustomer) { string documentContents = ""; HttpContext context; using (Stream receiveStream = context.Request.InputStream) // This line has an error because it doesn't know what context is (neither do I, I found this code) { using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8)) { documentContents = readStream.ReadToEnd(); } } return documentContents; }
The example XML I have been given that will be posted is this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><customersT><customer><custId>TEST1201</custId><custName>Test Company 1201</custName><groupCode>XXX</groupCode></customer></customersT>
It's actually a lot longer than that, but I removed tonnes of extra nodes. The point is, to make a customer record in my end of the system requires these 3 bits of data.
I even have a test class to put the data:
namespace WcfService1.Classes { public class TestCust { public TestCust() { } public int Id { get; set; } public string CustId { get; set; } public string CustName { get; set; } public string GroupCode { get; set; } } }
So, the question is, how do I get a WebMethod to pick up XML that is posted to it? It isn't being passed on the querystring. It is in the HTTP Header. To test, when I got the thing to compile earlier, I tried using PostMan to send it XML but it didn't like it. Currently using SoapUI to see if I have any more luck. I don't really want to have to write a test client to send it because I don't know how to do that either. Every error I get moans about SOAP. I am assuming that when I pass the XML that I have, it is converted into a SOAP envelope? I have been going round and round in circles with this and it should be easy. When I allow the function to take multiple string parameters instead of working with HTTP Posts with XML and run it up in Chrome I can see the different parameters listed and in the generated web page it asks me to fill in the blanks, and press a button called Invoke. I invoke it after putting in the data from the above XML and hey presto, the customer gets created, so the back end is working. How the hell and I supposed to work with XML? I've seen some great examples where a couple of lines of code reads an XML file and chucks the entire contents into an object from a class they've written. How can I put the data from my XML into the class I've written?
Please help, before I throw this machine out of the window.
HTTP Post to Web Service containing a file
My understanding of web services is at best ok. In principle it is calling a function across the web to gain a service and get a response. I've had some awesome help from someone on this forum in getting the HTTP post containing XML to work, and it does. This might be a dumb question, but when doing a web service call and passing in XML in the body, is it possible to send the XML as a file rather than in the body? To me it doesn't make a great deal of sense doing it that way but the question has been asked today so I thought I'd post the query on here.
Exception thrown: 'System.Net.WebException' in System.dll The remote name could not be resolved:
I have a WCF Service hosted in IIS on a Windows 10 IoT Enterprise machine on a private network (no domain). When i make calls to my service from the client it is unable to resolve my computer name as it is on my companies domain.Is there a way to tell WCF to use the ip of the incoming request? Using the local hosts file is a non starter.
Currently site binding are IP: *, Host Name: "", Port:80.
Service Model Config:
<system.serviceModel><protocolMapping><remove scheme="http" /><add scheme="http" binding="wsDualHttpBinding" bindingConfiguration="CamWindowBinding"/><remove scheme="net.tcp" /></protocolMapping><services><service name="CompanyName.EIVisionServer"><endpoint address="""" binding="wsDualHttpBinding" bindingConfiguration="CamWindowBinding" name="EICamWindowEndpoint" contract="CompanyName.Vision.Services.IEICamWindowContract" /><endpoint address="""" binding="wsDualHttpBinding" bindingConfiguration="CamWindowBinding" name="CC24Endpoint" contract="CompanyName.Vision.Services.ICC24ServiceContract" /><host><baseAddresses><add baseAddress="http://192.168.1.200/EIVisionServer/" /></baseAddresses></host></service></services><bindings><wsDualHttpBinding><binding name="CamWindowBinding" receiveTimeout="24.20:31:23.6470000" maxReceivedMessageSize="2147483647" messageEncoding="Mtom"><readerQuotas maxArrayLength="2147483647" /><reliableSession inactivityTimeout="24.20:31:23.6470000" /><security mode="None"><message clientCredentialType="None" /></security></binding></wsDualHttpBinding></bindings><client><endpoint address="http://192.168.1.200/EIVisionServer.svc" binding="wsDualHttpBinding" bindingConfiguration="CamWindowBinding" contract="CompanyName.Vision.Services.IEICamWindowContract" name="EICamWindowEndpoint" /><endpoint address="http://192.168.1.200/EIVisionServer.svc" binding="wsDualHttpBinding" bindingConfiguration="CamWindowBinding" contract="CompanyName.Vision.Services.ICC24ServiceContract" name="CC24Endpoint" /></client><behaviors><serviceBehaviors><behavior name=""><useRequestHeadersForMetadataAddress><defaultPorts><add scheme="http" port="80" /></defaultPorts></useRequestHeadersForMetadataAddress><serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" /><serviceDebug includeExceptionDetailInFaults="true" /></behavior></serviceBehaviors></behaviors><serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /></system.serviceModel>
Thanks,
Ryan
Web API with referenced to Managed Code 32bit
The Web API I'm creating links to Sage 300. When you reference the 2 DLLs that you need to connect to Sage's API, they are 32bit DLLs. If I set the project properties to be x86, running it loads the browser and then immediately exists with:
'dotnet.exe' (CoreCLR: DefaultDomain): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.1.0\System.Private.CoreLib.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
The program '[14832] dotnet.exe' has exited with code -532462766 (0xe0434352).
If I set it to Any CPU I get:
System.BadImageFormatException: 'Could not load file or assembly 'ACCPAC.Advantage, Version=6.5.0.10, Culture=neutral, PublicKeyToken=4d7048ecf2312a7c'. An attempt was made to load a program with an incorrect format.'
Now I know this is because the Sage DLLs are 32bit. In Visual Studio 2017 there is this option:
Tools
-> Options
-> Projects and Solutions
-> Web Projects
-> Uncheck "Use the 64 bit version of IIS Express for web sites and projects"`
It is unchecked. I checked it to see if it made a difference. It didn't. Any thoughts?
.NET Core Web Api trying to post to another web serivce
I've been building a web api. It picks up the XML from the client. I can read the XML. I need to the data into Sage 300. Sage 300 seems to have a full Web API which I only just found out about. I can build JSON objects and post them. This is the code that posts to Sage:
public static async Task CreateCustomer(string uri, customersT customers) { var customer = new { CustomerNumber = customers.Items[0].custNo, ShortName = customers.Items[0].custNo, CustomerName = customers.Items[0].custAddresses[0].name, GroupCode = "RTL" }; await SendRequest(new HttpMethod("POST"), uri + @"AR/ARCustomers", customer); }
The code to post to Sage comes from a sample project. It required me to install 2 packages. Newtonsoft.Json and Microsoft.Net.Http. I did that but I get a warning and the post fails because think there is an incompatibility.
In the project Dependencies under NuGet Microsoft.Net.HTTP has a yellow triangle, as does Microsoft.Bcl. The warnings are:
1>E:\LSProjects\ACLWebApi\ACLWebApi\ACLWebApi.csproj : warning NU1701: Package 'Microsoft.Bcl 1.1.10' was restored using '.NETFramework,Version=v4.6.1' instead of the project target framework '.NETCoreApp,Version=v2.1'. This package may not be fully compatible with your project. 1>E:\LSProjects\ACLWebApi\ACLWebApi\ACLWebApi.csproj : warning NU1701: Package 'Microsoft.Net.Http 2.2.29' was restored using '.NETFramework,Version=v4.6.1' instead of the project target framework '.NETCoreApp,Version=v2.1'. This package may not be fully compatible with your project.
Any ideas on what I should do? In my mind, I'm just taking the XML and pulling out the data I want, constructing a JSON object and sending it, but I guess the post is failing due to the above warnings.
Any ideas on what packages I should install?
Returning responses from Web Api
My web api needs to return a response. Can't seem to get it right. Here is the code for the controller.
//Controller Code // POST api/<controller> [HttpPost] //public IActionResult Post([FromBody] customersT customers) public string Post([FromBody] customersT customers) { SageHelper sageHelper; if(!ModelState.IsValid) { return "Invalid XML"; //BadRequest(ModelState); } else { sageHelper = new SageHelper(customers); } return sageHelper.ReturnValue; //Ok(); }
Here is the helper class that will do the post to Sage
public static async Task CreateCustomer(string uri, customersT customers) { var customer = new { CustomerNumber = customers.Items[0].custNo, ShortName = customers.Items[0].custNo, CustomerName = customers.Items[0].custAddresses[0].name, GroupCode = "RTL" }; await SendRequest(new HttpMethod("POST"), uri + @"AR/ARCustomers", customer); } public static async Task<object> SendRequest(HttpMethod method, string requestUri, object payload = null) { HttpContent content = null; string responsePayload = ""; // Serialize the payload if one is present if (payload != null) { var payloadString = JsonConvert.SerializeObject(payload); content = new StringContent(payloadString, Encoding.UTF8, "application/json"); } // Create the Web API client with the appropriate authentication using (var httpClientHandler = new HttpClientHandler { Credentials = new NetworkCredential("USER", "PASSWORD") }) using (var httpClient = new HttpClient(httpClientHandler)) { // Create the Web API request var request = new HttpRequestMessage(method, requestUri) { Content = content }; // Send the Web API request try { var response = await httpClient.SendAsync(request); responsePayload = await response.Content.ReadAsStringAsync(); var statusNumber = (int)response.StatusCode; response.StatusCode); if (statusNumber < 200 || statusNumber >= 300) { // Console.WriteLine(responsePayload); throw new ApplicationException(statusNumber.ToString()); } } catch (Exception e) { Environment.Exit(0); } } return string.IsNullOrWhiteSpace(responsePayload) ? null : JsonConvert.DeserializeObject(responsePayload); }
When the HTTP post hits the controller, it sends the request off to the SageHelper object which processes the data and pushes into Sage. The SendRequest method returns a string which I actually don't want for this project. Where it gets the response.statusCode from the response object, I am trying to get that set into a public property of the SageHelper class
public string ResponseCode { get; set; }
Normally, I would just put ResponseCode = response.statusCode; in the SendRequest method but I can't see the property from that method.
Publishing a Web Api in IIS
Hi,
To publish an ASP.NET Core web service in IIS, I'm trying to get the steps sorted. I have it working on the development server and for testing I need to make that available on the same server. In Visual Studio it was running in IISExpress. During development I was running the API in HTTPS under IISExpress.
Now I want to put it into IIS and I'm having trouble. I did a build release and published to a folder on the file system. I created the folder as E:\ACL\WebApi and that is where is published to. In that folder are 5 files.
ACLWebApi.deps.json
ACLWebApi.dll
ACLWebApi.pdb
ACLWebApi.runtimeconfig.json
web.config
This server is Windows 2016 and has IIS installed and it is up and running and has other web applications on it. When I applied that and went in to change the settings on IIS, each module I double click on, I get a dialog box up that says
There was an error while performing this operation
Details:
Filename:\\?\E:\ACL\ACLWebApi\web.config
Error:
Any ideas?
Logging from a web api
With the web api I am developing, I need to output data to a log file. I know I can add stuff to the stdout log file, but I would rather like to output to a dedicated log file. My web service does not have a web.config in the project in Visual Studio, but it does when I publish it. If I wanted to have it so the log file location is specified in the web.config, or another config file, what is the best way to go about this? As the web service is multi-threaded, does that have an impact on logging?
Consuming webservice from class library
Hi,
I have to make a class library with a service reference in it. All the communication with the web service has to go via this class library. Now when i make a second application(winforms) to call the methodes in the class library that make call to the web service, i get the error:
Could not find default endpoint element that references contract ' ServiceReferenceMailbox.IMailboxService' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
Now when i copy the app.config content of the class library project in my winforms clien app, it works, but this is not what i want, the class library has to use it's own app.config
How can solve this?
Kind regards,
Kabida
Basic config files
I'm not looking for anything complex here but, every time I read another page about this, it starts wading into stuff that is way too much for what I need. My web service creating in ASP.NET Core 2.1 needs to have a config file. In simpler times, I would have a config.xml or something. It will contain info such as:
<?xml version="1.0" encoding="utf-8" ?><configuration><appSettings><add key="UserId" value="user1" /><add key="UserPassword" value="Password123" /><add key="InterfaceVersion" value="1.0" /><add key="InterfaceName" value="WebApi" /><add key="TargetServer" value="localhost" /><add key="UserHTTPS" value="N" /><add key="LogFilePath" value="./ApiLogs/" /></appSettings></configuration>
When the web api is called, it needs to read the values from this config file. Don't worry about the password being in plain text. I have 2 controllers in my api that pick up HTTPPost data. During that call, the config needs to be read to pick up the info in it. That cannot be complicated can it? Can someone point me in the right direction or give me an example?
Server did not recognize the value of HTTP Header SOAPAction
Hello,
I have a webservice developed with VS2008. It runs ok on my browser but when the client tries it, I receive this error message
Server did not recognize the value of HTTP Header SOAPAction
Please advice,
thank you
WCF TestClient: How to display Fault Exception instead of "Failed to invoke the service."
Hi,
i wanna test my SOAP WCF Server.
So i start my Visual Studio Project from the Service1.svc File into the WCF Testclient.
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
public string GetDataFail(int value)
{
throw new FaultException("TestError");
}
}
The Soap Response from GetDataFail
is:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header />
<s:Body>
<s:Fault>
<faultcode>s:Client</faultcode>
<faultstring xml:lang="de-DE">TestError</faultstring>
</s:Fault>
</s:Body>
</s:Envelope>
The Problem is that the WCF Test client cant handle the fault exception, instead it trows "Failed to invoke the service." ...
Is there any way to display the FaultException in the WCF Test Client? or is this intended behavior?
Return XML in response body
My web service sits between a client and another web service. It converts the clients requests into another request to pass on to Sage 300 and returns the response back. Most of the time it is for pushing data in or updating it. I'm working on getting data from the Sage system back to the client.
In the GetBalancesController I have: this function:
// GET api/<controller> public string Get([FromQuery] string c = "", string s = "")
It is returning a string at the moment. When the client makes a request it will be in the form:
https://localhost:44316/api/GetBalances?s=DEVDAT&c=1200
The parameters are not important. What is important is that when this URI is requested, my webservice constructs a call into Sage 300 to get what it needs. After a bit of work, it gets back the data I want and I alter it to what I need. If I serialise the data to an XML string I get this:
<?xml version="1.0" encoding="utf-16"?><CustomersBalances xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://accord.co.uk"><Value><CustomerBalances><CustomerNumber>1200</CustomerNumber><Terms>0</Terms><CreditLimitCustomerCurrency>10000</CreditLimitCustomerCurrency><BalanceDueInCustomerCurrency>5177.85</BalanceDueInCustomerCurrency><BalanceDueInFunctionalCurrency>7269.49</BalanceDueInFunctionalCurrency></CustomerBalances></Value></CustomersBalances>
That's great. But if I just return this to the Get function, it returns the XML as content rather than in the response body. How can I get the XML I've created from the return from Sage back to the client in the response body?
Thanks.
WCF disable proxy creation for security
just read this link https://stackoverflow.com/questions/5671885/what-happens-if-i-set-httpgetenabled-false
1) tell me what i need to do disable proxy creation of wcf service ? do i need to remove mex endpoint from config file
<endpoint address="mex" binding="mexBasicHttpBinding" contract="IMetadataExchange"/>
and also need to set false to httpGetEnabled="false" ?
if i am right then how 3rd part client will be using my service ? what i need to give them as a result they should be able to call my service ?
How many service contact i can create in a single wcf service project ?
thanks
Reading appsettings.json from controllers
I need to store some settings in appsettings.json. I've read and re-read several pages and I've got almost nowhere, other than confused. I've read the MS articles and I'm still having trouble. Here is an example appsettigns.json:
{"appSettings": {"UserId": "User1","UserPassword": "Password123","IVersion": "1.0","EPName": "TargetAPI","Hostname": "localhost","UserHTTPS": "N","LogFilePath": "./Logs/" } }
Here is the Startup class:
public class Startup { public IConfigurationRoot Configuration { get; set; } public void ConfigureServices(IServiceCollection services) { var mvcBuilder = services.AddMvc(); mvcBuilder.AddXmlSerializerFormatters(); services.AddOptions(); services.Configure<IISOptions>(options => { options.AutomaticAuthentication = false; options.ForwardClientCertificate = false; }); services.Configure<ACLApplicationSettings>(Configuration.GetSection("ACLApplicationSettings"); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseMvc(); app.Run(async (context) => { await context.Response.WriteAsync("No function called."); }); } }
The controller has this at the top:
[Route("api/[controller]")] [ApiController] public class CustomersController : ControllerBase { private readonly IOptions<ACLApplicationSettings> settings; public CustomersController(IOptions<ACLApplicationSettings> config) { settings = config; }
Now later in the class I would expect to be able to access the settings by typing:
settings.Value.ACLSettings.UserId
If I write the above line below the line in the constructor I can access the values. Outside of the constructor I cannot. What is going on? All I want to do is read settings that are held in an external file!
Deserialize Soap Request Message from File to Object
Hi,
this is my incoming XML SOAP Request Message:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:han="http://schemas.datacontract.org/2004/07/ASDF_WCF"><soapenv:Header/><soapenv:Body><tem:GetDataUsingDataContract><tem:composite><han:MyParam1>5</han:MyParam1></tem:composite></tem:GetDataUsingDataContract></soapenv:Body></soapenv:Envelope>
[ServiceContract] public interface IService1 { [OperationContract] ComplexResponse1 GetDataUsingDataContract(ComplexParams1 composite); } [DataContract] public class ComplexParams1 { [DataMember] public int MyParam1 { get; set; } }
Calling the service works fine.
Now i saved the incoming Request SOAP XML to a file.
I want to be able to process it again later.
How can i Deserialize the Soap Message into ComplexParams1?
i tryed already, but couldn't get to work :
Message m = Message.CreateMessage(XmlReader.Create("C:\\testSvc\\login.xml"), int.MaxValue, MessageVersion.Soap11); SoapReflectionImporter importer = new SoapReflectionImporter(new SoapAttributeOverrides(), "urn:PlotiIntf-IPloti"); XmlTypeMapping mapp = importer.ImportTypeMapping(typeof(ComplexParams1)); XmlSerializer xmlSerializer = new XmlSerializer(mapp); //typeof(T), xr var o = (ComplexParams1)xmlSerializer.Deserialize(m.GetReaderAtBodyContents());
i'd prefer a generic solution like the one above, so its not too verbose.
I'd like to deserialize the original XML.
Thanks for help!
Testing Webservice with Custom SOAP Header in Postman Client
Hi,
I am learning authentication in web service so following an article in code project, but stuck at testing in Postman. I don't know how to pass custom SOAP header (username and password) in postman client.
Here is the link of article I am reading:
https: //ww w.codeproject.com/Articles/27365/Authenticate-NET-Web-Service-with-Custom-SOAP-Head
[WebMethod] [SoapDocumentMethod(Binding = "TestService")] [SoapHeader("consumer",Required=true)] public string GetBalance() { if (checkConsumer()) return consumer.userName + " had 10000000 credit"; else return "Error in authentication"; } private bool checkConsumer() { // In this method you can check the username and password // with your database or something // You could also encrypt the password for more security if (consumer != null) { if (consumer.userName == "Ahmed" && consumer.password == "1234") return true; else return false; } else return false; }
Please help ASAP!
IIS 500 Error WCF Service and Failed Request Tracing not info
I have a WCF service running in IIS 8.5 on Windows Server 2012 R2 with AppPool Integrated.
I open url in the server: http://localhost:50123/MyService.svc
I have **HTTP 500 Internal Server Error**. (IExplorer cannot show the page)
I have not found the problem in Event logs, IIS Logs.
I apply this steps: https://peter.hahndorf.eu/blog/iislogging.html
Disable IE “Friendly HTTP error messages”
<customErrors mode=”Off” />
<httpErrors errorMode="Detailed" />
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
I use WCF tracing, but not view the error messsage.
I setup "**Failed Request Tracing**", for All content, verbose error logging, HTTP errors in range 400-600.
I open fr000001.xml file from *%systemdrive%\inetpub\logs\FailedReqLogFiles\W3SVC1*
I only view **MODULE_SET_RESPONSE_ERROR_STATUS Warning:**
> ModuleName ManagedPipelineHandler
> Notification 128
> HttpStatus 500
> HttpReason Internal Server Error
> HttpSubStatus 0
> ErrorCode 0
> ConfigExceptionInfo
> Notification EXECUTE_REQUEST_HANDLER
> ErrorCode The operation completed successfully. (0x0)
Error 500:
> HttpStatus 500
> HttpReason Internal Server Error
and successfully ?
> ErrorCode The operation completed successfully. (0x0)
**Not more info about the error.**
About the error:
I have and WCF Inspector with IDispatchMessageInspector
Like https://patrickdesjardins.com/blog/wcf-inspector-for-logging
The error is about attribute `logFileName="c:\log.txt"`
**If the path exists, all is OK.
If the path NOT exists, I get Http 500 Error.**
<extensions>
<behaviorExtensions>
<add name="myLogBehavior"
type="MyServiceA.LogFileBehaviorExtensionElement, MyServiceA" />
</behaviorExtensions>
</extensions>
<endpointBehaviors>
<behavior name="behavior1">
<myLogBehavior logFileName="c:\log.txt" />
</behavior>
</endpointBehaviors>
This means there is an unhanded exception with in the code.
Event viewer, IIS Logs, WCF tracing, Failed Request Tracing not shown the error message, why? How get the full error message ? OS not logging the error in anyway ?