How to set a proxy when using SoapPortClient? - c#

I'm trying to execute a function using a Soap Port Client object (from an external WebService), and I need to set a proxy (address and credentials) for it. Because when I test the app (not on localhost), the WS functionality doesn't work.
Namespace.WebService.SoapPortClient foo = new Namespace.WebService.SoapPortClient();
short cod_error;
string des_error;
string url = "";
int fooNumber = 10;
url = foo.Execute(fooNumber, out cod_error, out des_error);
...code continues
In the above example, I need to set a proxy for 'foo'. I've tried with foo.Proxy but this property doesn't exists in the SoapPortClient.
Thank you all!

After reading your comments and problem I realized that you are talking about WCF.
Regards to your latest problem:
Now I'm getting the following error: The content type text/HTML of the response message does not match the content type of the binding (text/XML; charset=utf-8)
My first suggestion would be to check that the user you're running the WCF client under has access to the resource.
Can't say much since it's very hard to say something without seeing the config file or code in general.

Related

Autodesk Forge Error trying to access the API online

I have a problem loading a 3D model on an online server, the error shown is related to accessing the Forge API, locally works smoothly however when mounted on the server or a website is made marks the following error "Failed to load resource: the server responded with a status of 404 (Not Found)", then "onDocumentLoadFailure() - errorCode:7".
As I comment, what I find stranger is that, locally, it works. Attached the segment of the code where it displays the error.
function getAccessToken() {
var xmlHttp = null;
xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", '/api/forge/toke', false); //Address not found
xmlHttp.send(null);
return xmlHttp.responseText;
}
Thank you very much in advance.
Are you sure the code you're running locally and the code you've deployed are really the same?
The getAccessToken function doesn't seem to be correct, for several reasons:
First of all, there seems to be a typo in the URL - shouldn't it be /api/forge/token instead of /api/forge/toke?
More importantly, the HTTP request is asynchronous, meaning that it cannot return the response immediately after calling xmlHttp.send(). You can find more details about the usage of XMLHttpRequest in https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest.
And finally, assuming that the function is passed to Autodesk.Viewing.Initializer options, it should return the token using a callback parameter passed to it (as shown in https://forge.autodesk.com/en/docs/viewer/v7/developers_guide/viewer_basics/initialization/#example).
With that, your getAccessToken should probably look more like this (using the more modern fetch and async/await):
async function getAccessToken(callback) {
const resp = await fetch('/api/forge/token');
const json = await resp.json();
callback(json.access_token, json.expires_in);
}
I've already found the issue. When I make the deploy I have to change the url where the request is made for the public or the name of the domain. For example: mywebsite.com/aplication-name/api/forge/token.

How to create an otrs ticket using a soap request

The lack of documentation on this subject coupled with the fact that I'm struggling with a learning curve on all fronts and making me really confused about where to start. I need to get this done using C# if possible. I apologize for the vagueness of this question, but I'm really lost. I would love links to comprehensive guides/references.
In my efforts to get this done, I've run into the following problems/questions:
I've created a web service using the otrs gui, with the operation CreateTicket, but requests via C# to my chosen namespace are returning 404 (not found). When I try to add a service reference or web reference with that namespace, I get the same error. However, when I plug that namespace into my browser as the url, it displays "customer.pl".
Can I send a soap request without adding the web service as a service reference in visual studio? Given the previous problem I'm having I can't do it that way. Would I just build the soap request string and write it to the web request's data stream with http://domain/rpc.pl as the uri?
If the answer to the previous question is yes... When trying the below code segment I get an internal server error (500) on the last line. However the header looks like a SOAP header which confuses me because I wouldn't have thought it got that far.
var document = new StringBuilder();
document.Append("<UserLogin>some user login</UserLogin>");
document.Append("<Password>some password</Password> ");
document.Append("<Ticket>");
document.Append("<Title>some title</Title> ");
document.Append("<CustomerUser>some customer user login</CustomerUser>");
document.Append("<Queue>some queue</Queue>");
document.Append("<State>some state</State>");
document.Append("<Priority>some priority</Priority>");
document.Append("</Ticket>");
document.Append("<Article>");
document.Append("<Subject>some subject</Subject>");
document.Append("<Body>some body</Body>");
document.Append("<ContentType>text/plain; charset=utf8</ContentType>");
document.Append("</Article>");
//var uri = new Uri("http://domain/injest");
var uri = new Uri("http://domain/rpc.pl");
var httpWebReq = (HttpWebRequest)WebRequest.Create(uri);
var bytePostData = Encoding.UTF8.GetBytes(document.ToString());
httpWebReq.Timeout = 5 * 1000;
httpWebReq.Method = "POST";
httpWebReq.ContentLength = bytePostData.Length;
httpWebReq.ContentType = "text/xml;charset=utf-8";
//httpWebReq.TransferEncoding=
//httpWebReq.ContentType = "application/xml";
//httpWebReq.Accept = "application/xml";
var dataStream = httpWebReq.GetRequestStream();
dataStream.Write(bytePostData, 0, bytePostData.Length);
dataStream.Close();
var httpWebResponse = (HttpWebResponse)httpWebReq.GetResponse();
Even if all you can offer is where to start, it would help me to know how to proceed, as I'm stumped.
You're using the rpc.pl endpoint which is part of the 'old' RPC-style interface.
You mention you added the web service via the GUI which means you're using the 'new' Generic Interface, which is indeed much easier from .Net.
The address of the endpoint is /otrs/nph-genericinterface.pl/Webservice/GenericTicketConnector or whatever you have called the web service in the admin section.

Add request headers with WebClient C#

I have the following code with which I download a web-page into a byte array and then print it with Response.Write:
WebClient client = new WebClient();
byte[] data = client.DownloadData(requestUri);
/*********** Init response headers ********/
WebHeaderCollection responseHeaders = client.ResponseHeaders;
for (int i = 0; i < responseHeaders.Count; i++)
{
Response.Headers.Add(responseHeaders.GetKey(i), responseHeaders[i]);
}
/***************************************************/
Besides of the response headers, I need to add request headers as well. I try to do it with the following code:
/*********** Init request headers ********/
NameValueCollection requestHeaders = Request.Headers;
foreach (string key in requestHeaders)
{
client.Headers.Add(key, requestHeaders[key]);
}
/***************************************************/
However it does not work and I get the following exception:
This header must be modified using the appropriate property.Parameter name: name
Could anybody help me with this? What's the correct way of adding request headers with WebClient?
Thank you.
The headers collection "protects" some of the possible headers as described on the msdn page here: http://msdn.microsoft.com/en-us/library/system.net.webclient.headers.aspx
That page seems to give all the answer you need but to quote the important part:
Some common headers are considered restricted and are protected by the
system and cannot be set or changed in a WebHeaderCollection object.
Any attempt to set one of these restricted headers in the
WebHeaderCollection object associated with a WebClient object will
throw an exception later when attempting to send the WebClient
request.
Restricted headers protected by the system include, but are not
limited to the following:
Date
Host
In addition, some other headers are also restricted when using a
WebClient object. These restricted headers include, but are not
limited to the following:
Accept
Connection
Content-Length
Expect (when the value is set to "100-continue"
If-Modified-Since
Range
Transfer-Encoding
The HttpWebRequest class has properties for setting some of the above
headers. If it is important for an application to set these headers,
then the HttpWebRequest class should be used instead of the WebRequest
class.
I suspect the reason for this is that many of the headers such as Date and host must be set differently on a different request. You should not be copying them. Indeed I would personally probably suggest that you should not be copying any of them. Put in your own user agent - If the page you are getting relies on a certain value then I'd think you want to make sure you always send a valid value rather than relying on the original user to give you that information.
Essentially work out what you need to do rather than finding something that works and doing that without fully understanding what you are doing.
Looks like you're trying to set some header which is must be set using one of the WebClient properties (CachePolicy, ContentLength or ContentType)
Moreover, it's not very good to blindly copy all the headers, you need to get just those you really need.

$.getJSON equivalent in Silverlight

I'm making the following call in jQuery, using jsonp as my data format, that I'd like to make directly in Silverlight:
$.getJSON('https://api.wordstream.com/authentication/login?callback=?',
{ 'username': un,
'password': pw
}, function (loginResults) {
API_SESSION_ID = loginResults['data']['session_id'];
$.getJSON('https://api.wordstream.com/keywordtool/get_keywords?callback=?',
{ 'session_id': API_SESSION_ID,
'seeds': keyword,
'max_results': 20
}, function (keywordResults) {
for (i = 0; i < +keywordResults['data'].length; i++) {
Keywords[i] = keywordResults['data'][i][0];
}
return(Keywords);
});
});
I tried something like this to handle the first $.getJSON (authenticating & returning my auth token):
WebClient downloader = new WebClient();
WebRequest.RegisterPrefix("https://", System.Net.Browser.WebRequestCreator.ClientHttp);
var client = new WebClient();
client.Credentials = new NetworkCredential("username", "password");
client.UseDefaultCredentials = false;
client.DownloadStringCompleted += new
DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
client.DownloadStringAsync(loginEndpoint);
When I try and run this I get the following error inside my downloadstringcompleted eventhandler:
{System.Security.SecurityException: Security error.
at System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClass5.<EndGetResponse>b__4(Object sendState)
at System.Net.Browser.AsyncHelper.<>c__DisplayClass4.<BeginOnUI>b__1(Object sendState)}
I've used WCF Ria Services in EF & SOAP services via .asmx files in the past, so I'm not a total stranger to the idea of web services. I am not sure if I need to be using the clientaccesspolicy or crossdomain files or not.
Any ideas on how to proceed?
Thanks,
Scott
What you trying to do in this series of questions has become clearer to me now.
Unless api.wordstream.com includes a ClientAccessPolicy xml (or the Flash equivalent) you will not be able to make requests to this api from Silverlight.
You have two options:
Call into Javascript to make these requests on behalf of the Silverlight app.
Create WCF service to on your server to make these requests on behalf od the Silverlight app.
I would recommend the first approach, however don't use getJSON. Instead use the standard ajax api in JQuery to fetch the JSON content asynchronously. When the final JSON content is available (still in string form) call into Silverlight from Javasript passing in the string.
What would be preferable is to create the appropriate set of .NET classes and collections that match the data from the api. You could then use DataContractJsonSerialializer to deserialize the received string into instances of your classes.
Sometimes creating a class structure can be a bit of a burden. Another approach is to use the set of objects in the System.Json namespace starting with JsonValue.Parse to load up the set of JsonObjects from the string. You can now navigate around the returned data using these `son objects and Linq where necessary.
Did a little digging and a test.
When you are calling an external domain, the cross-domain issue will occur and that's why you are seeing the Security error.
Remember that this is a Web application after all, it does run inside the browser!
To enable Silverlight to reach outside it's domain, give this article a try if you are doing a self hosted app.
http://blogs.msdn.com/b/carlosfigueira/archive/2008/03/07/enabling-cross-domain-calls-for-silverlight-apps-on-self-hosted-web-services.aspx

Why doesn't FTPWebRequest, or WebRequest in general accept a /../ path?

I am trying to automate some upload/download tasks from an ftp web server. When I connect to the server through client, or through Firefox even, in order to get to my directory, I have to specify a path like this:
ftp://ftpserver.com/../AB00000/incoming/files
If I try to access this:
ftp://ftpserver.com/AB00000/incoming/files
The server throws an error that the directory does not exist. So, the problem:
I am trying to create an FTPWebRequest with the first ftp address, but it always parses out the "/../" part and then my server says the path doesn't exist.
I've tried these:
Uri target = new Uri("ftp://ftpserver.com/../AB00000/incoming/files");
FtpWebRequest request = (FtpWebRequest)WebReqeuest.Create(target);
and
string target = "ftp://ftpserver.com/../AB00000/incoming/files";
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(target);
In the first bit, the path is already incorrect when the Uri object is instantiated, in the second bit, it's after the WebRequest.Create method. Any ideas what's going on?
EDIT:
Additionally, since I posted this, I have tried creating the URI with the no parse option. I have also tried something like this:
string ftpserver = "ftp://ftpserver.com/../";
string path = "12345/01/01/file.toupload";
Uri = new Uri(ftpserver, path, true);
And it always parses out the root part ("/../").
Try escaping the .. with something like:
Uri target = new Uri("ftp://ftpserver.com/%2E%2E/AB00000/incoming/files");
That works according to this blog which I found in this discussion.
Not really sure about it, but it may be for security reasons, since allowing "/../" URIs would potentially let people navigate freely on any server's file system.
Also, the official URI RFC states that when resolving an URI one of the steps performed is actually the removal of "/../" segments, so it's not a problem in the C# library but it's regular URI behavior.
Have you tried using the # symbol like so?
Uri target = new Uri(#"ftp://ftpserver.com/../AB00000/incoming/files");
FtpWebRequest request = (FtpWebRequest)WebReqeuest.Create(target);

Categories