WebClient fails with remote server "NotFound" - silverlight

I'm building a wp7 app. I'm using WebClient to grab data from a server. In the past, it's been working, although all of a sudden it's failing.
static void downloadData(string uri, Action<object, DownloadStringCompletedEventArgs> onComplete)
{
Debug.WriteLine("Downloading: " + uri);
WebClient data = new WebClient();
data.DownloadStringCompleted += new DownloadStringCompletedEventHandler(onComplete);
data.DownloadStringAsync(new Uri(uri));
}
static void data_SectionDownloadCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error != null)
{
// throws NotFound
throw e.Error;
}
// ...
}
When I go to the URI in question in my browser, it works fine.
The exception:
"The remote server returned an error: NotFound." {System.Net.WebException}
What am I doing wrong here?
Update: I restarted the emulator, and now it works fine. Weird. Maybe it's an issue in the emulator? Hopefully I won't be able to reproduce it on the actual device.

NotFound is a generic error that basically means 'Error'. There is a real exception behind it that you need to dig to find. The easiest method I have found is Intellitrace which allows you to view every exception that ever happened on your web server. If you look just before your NotFound, you will find the real exception that backs it.
If Intellitrace is not an option, add more/better logging on your server and client. Google has many tips, a good example of deeper debugging:
http://www.mostlydevelopers.com/blog/post/2009/01/14/debugging-tips-ndash3b-the-remote-server-returned-an-error-notfound.aspx

I had similar experience with the emulator. I often open Internet Explorer and browse a site before I test any application that uses the network. Also, it is best not to change the IP address of the machine running the emulator, DHCP or manually. Lastly, I would suggest you handle any error scenarios with an error message displayed in a MessageBox.
HTH, indyfromoz

I get this occassionaly too. Even on real devices. A retry usually fixes it though.
Unfortunately this is one of the issues you need to be aware of and write code to cater for when working in an occassionally connected environment.

Related

gwt typerror ( cannot call method 'X' of null )

I have a very simple GWT app, containing a simple rpc callback for a database operation.
All it does is a retrieve a string from the database. This works fine locally. It retrieves the string trough a callback and displays it on the screen.
But when I deploy it to appengine, it doesn't work and gives me the error ' gwt typerror ( cannot call method 'X' of null ) '. I've tried debugging, logging etc but it gives me nothing and I'm desperately lost.
EntityService.Util.getInstance().getEntityName(
Function.getHash("john"), Function.getHash("name"),
Function.getHash("english"), new AsyncCallback<String>() {
#Override
public void onSuccess(String result) {
l.setText(result);
}
#Override
public void onFailure(Throwable caught) {
l.setText(caught.getMessage());
}
});
U guys have any clue what could be going on, or why I'm getting this error on appengine?
I've tried to only to connect the database on appengine deployed trough a callback and this works fine.
Thanks in advance!
It would be easier to debug such errors if you try using either of following solutions before pushing into appengine -
Solution 1 - Compile you application in pretty mode as long as you are not pushing into prod mode.
Pretty mode allows you easier debugging in web mode. The exceptions are readable.
Solution 2 - Integrate Webmode Exception handling - http://code.google.com/p/google-web-toolkit/wiki/WebModeExceptions
Both the solution add some runtime performance penalty and should be used in dev cycles. Once you have polished tested application Turn webmode exception and pretty compilation off.

Consume SOAP Web Service in Silverlight

I'm attempting to consume a SOAP service in a Silverlight 5 application and I'm completely lost. This is my first Silverlight app and only my second time using web services in a .NET application.
In a separate .NET application, the only way I was able to get it to work was by adding the WSDL as a Web Reference; the application would not build when I added it as a Service Reference. In talking to the WSDL provider, I discovered that the WSDL was compiled using the .NET 2.0 framework...hence the need to add it as a Web Reference.
From the research I've done thus far, I see that Silverlight doesn't support adding a Web Reference. So I tried adding it to the hosting ASP.NET application as a Web Reference then started the server.
Back in my Silverlight app, I selected the option to add a Service Reference and pointed to the WSDL file now at http://localhost:55265/Web%20References/THINKWebService/SLWebSvc_734_Upgrade.wsdl. Visual Studio seemed to pick it up just fine and generate the proxies.
Here's where I start to get stuck. If my research is correct, a WCF reference was created and should be used in that manner. I've never used WCF so I did some reading on how to send/receive requests and this is the best code I've come up with, based on examples in the MSDN library (I inserted it into a button click event so I would know exactly when the code was executing):
private void Button1Click(object sender, RoutedEventArgs e)
{
var client = new ThinkSoapClient();
var userLoginData = new user_login_data {login = "foo", password = "bar"};
var customerIdentifier = new customer_identifier {customer_id = 6677070};
// the debugger halts on this next line and
// references the "dsn"...it's the 4th argument
client.CustomerLoginInfoSelectAsync(userLoginData, customerIdentifier, "", "myDSN");
// I'm not sure if this next line is even needed
client.CustomerLoginInfoSelectCompleted += CustomerLoginInfoSelectCallback;
MessageBox.Show(string.Format("CustomerLoginInfoSelectAsync({0},{1})", userLoginData, customerIdentifier));
}
// here's the callback method
static void CustomerLoginInfoSelectCallback(object sender, CustomerLoginInfoSelectCompletedEventArgs e)
{
MessageBox.Show(string.Format("CustomerLoginInfoSelect Result: {0}", e.Result));
}
As I mentioned in the code above, the debugger halts when executing the client.CustomerLoginInfoSelectAsync method. Here's the error message: XmlSerializer attribute System.Xml.Serialization.XmlAttributeAttribute is not valid in dsn. Only XmlElement, XmlArray, XmlArrayItem and XmlAnyElement attributes are supported when IsWrapped is true.
From the research I've done, I think this error is being caused because the the SOAP action element contains an attribute dsn (not sure, though, if I would be getting this error if the sub-elements also had attributes).
I did a find/replace for IsWrapped=true to IsWrapped=false in Reference.cs but I got the same error but the last word was false instead of true.
I'm not sure if I'm making any sense as to what I'm after, so here's what the generated XML should look like in case it helps:
...
<customer_login_info_select_request dsn="myDSN">
<user_login_data>
<login>foo</login>
<password>bar</password>
</user_login_data>
<customer_identifier>
<customer_id>6677070</customer_id>
</customer_identifier>
<login/> <!--corresponds to the empty string in the call to CustomerLoginInfoSelectAsync-->
</customer_login_info_select_request>
...
So at this point, I'm completely lost. Any insights would be greatly appreciated. If there's any other info I can provide, please let me know.
While possible the normal solution would be to assume it is "just another data source" and use the Web reference on your Server side instead to provide data (and to provide insulation against future changes).
Silverlight App <=> Silverlight Web Services <= External/Legacy Web Service
Keep your Silverlight app slim and let the server do any heavy lifting for you.

CommunicationException when invoking Web Service from Silverlight 4

(Updated)
I've built a simple Silverlight 4 Bing Maps app using the VS2010 template.
Within the same solution I've got an ASP.NET project with a simple Web Service: ContentService.asmx.
I'm running both from my local machine for now.
I can invoke the Web Service from within an ASP.NET page with no problems.
However, try as I might, I can't get Silverlight to talk to it.
I try to invoke the Web Service from Silverlight as follows:
public BingMapAppPanel()
{
InitializeComponent();
BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
EndpointAddress endPoint = new EndpointAddress("http://localhost:49501/ContentService.asmx");
ContentServiceSoapClient contentService = new ContentServiceSoapClient(binding, endPoint);
contentService.GetAllCategoriesCompleted += new EventHandler<GetAllCategoriesCompletedEventArgs>(contentService_GetAllCategoriesCompleted);
contentService.GetAllCategoriesAsync();
}
void contentService_GetAllCategoriesCompleted(object sender, GetAllCategoriesCompletedEventArgs e)
{
MessageBox.Show(e.Result.Count.ToString());
}
It should output the count of the returned List object but instead it throws the following exception:
Bing Maps has encountered an exception. Please press CTRL+C to copy the error message text.
ErrorSource: Unhandled Exception.
ErrorType: System.Reflection.TargetInvocationException
ErrorMessage: An exception occurred during the operation, making the result invalid. Check InnerException for exception details.
ErrorCallStack:
at System.ComponentModel.AsyncCompletedEventArgs.RaiseExceptionIfNecessary()
at BingMapApp.Content.GetAllCategoriesCompletedEventArgs.get_Result()
at BingMapApp.BingMapAppPanel.contentService_GetAllCategoriesCompleted(Object sender, GetAllCategoriesCompletedEventArgs e)
at BingMapApp.Content.ContentServiceSoapClient.OnGetAllCategoriesCompleted(Object state)
InnerType: System.ServiceModel.CommunicationException
InnerMessage:
InnerCallStack:
at System.ServiceModel.AsyncResult.End[TAsyncResult](IAsyncResult result)
at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
at System.ServiceModel.ClientBase`1.ChannelBase`1.EndInvoke(String methodName, Object[] args, IAsyncResult result)
at BingMapApp.Content.ContentServiceSoapClient.ContentServiceSoapClientChannel.EndGetAllCategories(IAsyncResult result)
at BingMapApp.Content.ContentServiceSoapClient.BingMapApp.Content.ContentServiceSoap.EndGetAllCategories(IAsyncResult result)
at BingMapApp.Content.ContentServiceSoapClient.EndGetAllCategories(IAsyncResult result)
at BingMapApp.Content.ContentServiceSoapClient.OnEndGetAllCategories(IAsyncResult result)
at System.ServiceModel.ClientBase`1.OnAsyncCallCompleted(IAsyncResult result)
I've tried various crossdomain.xml and clientaccesspolicy.xml files, nothing works.
Any suggestions much appreciated - thanks.
Update
I changed the endpoint address to 127.0.0.1 instead of localhost and it worked!
EndpointAddress endPoint = new EndpointAddress("http://127.0.0.1:49501/ContentService.asmx");
Anyone know why?
I'm guessing you've added another Web project to your solution to host this WCF service? If so, it most likely is a cross domain issue, where the Silverlight application is attempting to communicate with a service on another domain than the one from which it originated (even though it's only the port number that differs. If possible, host the WCF service in the project that was created when you created the Silverlight application, and this will likely solve your problem. If you're still having trouble (or this wasn't the case), try using Fiddler to see what's happening behind the scenes. To get Fiddler to pick up the traffic however (it ignores localhost traffic), replace references to localhost in your URIs with ipv4.fiddler.
Hope this helps...
Chris Anderson
Note: I didn't see your edit before I posted this. That's a weird one!

Silverlight 4 OOB + Browser HTTP Stack + Client Certificates = FAIL?

I'm having an issue where IIS 7.5 (on Windows 7 64-bit) is failing when I call it from an out-of-browser Silverlight 4 app using SSL and a client certificate, with the message "The I/O operation has been aborted because of either a thread exit or an application request. (0x800703e3)". The request does make it to IIS. here is a sample from the failed request trace:
The I/O operation has been aborted because of either a thread exit or an application request. (0x800703e3) http://www.slipjig.org/IISError.gif
I am using the browser HTTP stack, because the client HTTP stack does not support client certificates. The client code attempting to hit the server is the Prism module loader. If I run the app out-of-browser but ignore client certs, or if I run the application in-browser but require client certs, it works fine. It seems to be the combination of the two that is causing the problem.
I tried the following to gather more info:
Used Fiddler to view the failing request. It works if Fiddler is running (presumably because Fiddler is handling the client certificate differently?);
Created an .aspx web form to serve up the module .xaps;
Created an HTTPModule to see if I could intercept the request before it failed;
Used a packet sniffer to see if I could tell if the client certificate was being sent correctly.
None of the above gave me much useful information beyond what I could see in the trace file, although the Fiddler thing is interesting.
Any ideas? Thanks in advance!
Mike
I beat my head against the wall for weeks on this problem. Here's what I learned and how I finally worked around it.
Prism's FileDownloader class uses System.Net.WebClient to load modules. In OOB mode, WebClient seems to use the same stack as IE, but it apparently either doesn't send the client certificate, or (more likely) doesn't correctly negotiate the SSL/client cert handshake with the server. I say this because:
I was able to successfully request .xap files using Firefox and Chrome;
I was not able to successfully request .xap files using IE;
IIS would fail with a 500, not a 403.
I couldn't get good visibility into what was actually happening over the wire; if I used Fiddler, it would work, because Fiddler intercepts communications with the server and handles the client certificate handshake itself. And trying to use a packet sniffer obviously wouldn't tell me anything because of SSL.
So - I first spent a lot of time on the server side trying to eliminate things (unneeded handlers, modules, features, etc.) that might be causing the problem.
When that didn't work, I tried modifying the Prism source code to use the browser's HTTP stack instead of WebClient. To do this, I created a new class similar in design to FileDownloader, implementing IFileDownloader, that used the browser stack. I then made some changes to XapModuleTypeLoader (which instantiates the downloader) to make it use the new class. This approach failed with the same error I was originally experiencing.
Then I started researching whether a commercial third-party HTTP stack might be available. I found one that supported the features I needed and that supported the Silverlight 4 runtime. I created another implementation of IFileDownloader that used that stack, and BOOM - it worked.
The good news with this approach is that not only can I use this to load modules, I can also use it to protect communications between the client and our REST API (a benefit we were going to give up, before).
I plan to submit a patch to Prism to allow the downloader to be registered or bound externally, as it's currently hard-coded to use its own FileDownloader. If anyone is interested in that or in the commercial HTTP stack I'm using, contact me (msimpson -at- abelsolutions -dot- com) for links and code samples.
And I must say this - I still don't know for sure whether the root problem is in the HTTP stack on the client side or the server side, but it's a FAIL on Microsoft's part nonetheless.
What we (Slipjig and I) found out this week is that there does appear to be a way around these issues, or at least, we're on the trail to determining whether there is a reliable, repeatable way. We're still not positive on that, but here's what we know so far:
At first pass, if you have code like this you can start making requests with either the Browser or Client stack:
First, place a "WebBrowser" control in your Silverlight XAML, and make it send a request to your HTTPS site.
This may pop up the certificate dialog box for the user. Big deal. Accept it. If you have only one cert, then you can turn an option in IE off to suppress that message.
private void Command_Click(object sender, RoutedEventArgs e) {
// This does not pop up the cert dialog if the option to take the first is turned on in IE settings:
BrowserInstance.Navigate(new Uri("https://www.SiteThatRequiresClientCertificates.com/"));
}
Then, in a separate handler invoke by the user, create an instance of your stack, either Client or Browser:
private void CallServer_Click(object sender, RoutedEventArgs e) {
// Works with BrowserHttp factory also:
var req = WebRequestCreator.ClientHttp.Create(new Uri("https://www.SiteThatRequiresClientCertificates.com/"));
req.Method = "GET";
req.BeginGetResponse(new AsyncCallback(Callback), req);
}
Finally, the Callback:
private void Callback(IAsyncResult result)
{
var req = result.AsyncState as System.Net.WebRequest;
var resp = req.EndGetResponse(result);
var content = string.Empty;
using (var reader = new StreamReader(resp.GetResponseStream())) {
content = reader.ReadToEnd();
}
System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
{
Results.Text = content;
});
}
I had the same issue and I fixed it by creating the certificate using makecert. Follow the steps from this article http://www.codeproject.com/Articles/24027/SSL-with-Self-hosted-WCF-Service and replace CN with your ip/domain. In my case I have tested the service on the local machine and run the commands as follows:
1) makecert -sv SignRoot.pvk -cy authority -r signroot.cer -a sha1 -n "CN=Dev Certification Authority" -ss my -sr localmachine
after running the first command drag the certificate from "Personal" directory to "Trusted Root Certification Authority"
2) makecert -iv SignRoot.pvk -ic signroot.cer -cy end -pe -n
CN="localhost" -eku 1.3.6.1.5.5.7.3.1 -ss my -sr
localmachine -sky exchange -sp
"Microsoft RSA SChannel Cryptographic Provider" -sy 12
In case you want to run the silverlight application on another machine, export the certificate created at step1 and then import it on any machine where you want your application to run.

Can silverlight detect or communicate across browser instances?

User starts up a silverlight application in their browser by navigating to a given URL.
User then opens another browser and starts up the same silverlight application by navigating to the same URL.
Can the second instance of the application detect that there is already an instance running on the same computer?
Can it detect itself if both applications are running within the same browser instance?
I would expect the answer to be 'no' but thought that i would ask it anyway. Otherwise i believe that i will have to setup a webservice and have each instance register itself and send requests to other instances from the same IP. does that sound reasonable?
I think you may be looking for LocalMessageSender and LocalMessageReceiver. I believe these are new classes in Silverlight 3 allowing two Silverlight applications running on the same local computer to communicate.
More detail: Communication Between Local Silverlight-Based Applications (msdn)
This will work, I've done it myself. This code from the Microsoft site demonstrates how you set up a LocalMessage 'receiver". If it throws an error, it is because another instance of the Silverlight app is already running.
public Receiver()
{
InitializeComponent();
LocalMessageReceiver messageReceiver =
new LocalMessageReceiver("receiver",
ReceiverNameScope.Global, LocalMessageReceiver.AnyDomain);
messageReceiver.MessageReceived += messageReceiver_MessageReceived;
try
{
messageReceiver.Listen();
}
catch (ListenFailedException)
{
output.Text = "Cannot receive messages." + Environment.NewLine +
"There is already a receiver with the name 'receiver'.";
}
}
I think you're right you can't do it cross-application, but you can do it within a single browser instance using cookies or Isolated Storage.

Resources