WCF REST service doesn't work on an IIS6 virtual server - c#

Problem is I have a very simple WCF REST service, which I wrote starting from the WCF Service application template.
I have one method, one class set up like this
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class MainService
{
[WebGet(UriTemplate = "{ricCode}")]
public IdentifierInfo GetByRicCode(string ricCode)
{
...
}
}
When ran from my machine I have no problems it works fine (typical).
My problem is that when I publish this to a website on IIS6 (set up for anonymous access and on a virtual server) all I get from the above method is a 400 - invalid request.
When I changed the method as a test to this
[WebGet(UriTemplate = "")]
public string GetByRicCode()
{
return "foo";
}
and ran in on the IIS6 server it worked fine.
Maybe I set up the virtual server wrong on IIS... any ideas please?

I figured out the problem, it was throwing an exception due to nested web.configs
How annoying.

Related

.asmx Service not working when publish for some services

I have a project that needs to integrate with legacy asmx services that contains business logic that I must use. I had problems making use of the channels so were allowed to add attributes to make the services rest.
Now here is the problem, I have tested all the services with post man locally and all calls work perfectly with rest as well as the old application still working. Hosting the web app on my local IIS also works. My problem is that when I publish to the server I have some services saying that [ScriptService] attribute is not there but they are there. Then other services works. What am I missing with IIS or publishing? Here is some Name changed code sections. Had to change due to NDA
//Working Service locally returns xml
[System.Web.Services.WebService(Namespace = "http://TheService.ServiceContracts/2006/09", Name = "MyWorkingService")]
[System.Web.Script.Services.ScriptService]
public class MyWorkingService : IMyWorkingService
{
[System.ServiceModel.Web.WebInvoke(Method = "POST",
RequestFormat = System.ServiceModel.Web.WebMessageFormat.Json,
ResponseFormat = System.ServiceModel.Web.WebMessageFormat.Json,
UriTemplate = "/PostMethod",
BodyStyle = System.ServiceModel.Web.WebMessageBodyStyle.Wrapped)]
[System.Web.Services.WebMethod]
public string PostMethod(MyPostObjectClass item)
{
//Business logic
}
}
//Failing Service; locally returns json
[System.Web.Services.WebService(Namespace = "http://TheService.ServiceContracts/2006/09", Name = "MyFailingService")]
[System.Web.Script.Services.ScriptService]
public class MyFailingService : IMyFailingService
{
[System.ServiceModel.Web.WebInvoke(Method = "POST",
RequestFormat = System.ServiceModel.Web.WebMessageFormat.Json,
ResponseFormat = System.ServiceModel.Web.WebMessageFormat.Json,
UriTemplate = "/GetDataFromObjectFilters",
BodyStyle = System.ServiceModel.Web.WebMessageBodyStyle.Wrapped)]
[System.Web.Services.WebMethod]
public MyResponseObject GetDataFromObjectFilters(ObjectFilterRequestClass item)
{
//Business logic
}
}
So I looked at my local IIS and the server IIS to try and figure out what is wrong. Matched up the handler mappings, ISAPI filters and the IIS features that is installed on my local to the server. Yet the server kept asking for the script service attribute even if it was on the class.
After a full weekend of no relax time, I ended up creating a new service project to add the services into and then started adding api controllers into the project to run alongside these services. Making use of the same name as the services to make changes less troublesome in the ui application.

How to call a ASP.Net C# WCFService on Android Studio?

Can anyone help me on how to call a C# WCF web service from Android Studio. My webservice is "http://192.168.1.100:93/MyService.svc?wsdl"
MyService.svc
namespace MyServiceApp
{
public class MyService : IMyService
{
public string Hello(string strName)
{
string strResult="";
strResult = "Hello " + strName;
return strTest;
}
}
}
IMyService.cs
namespace MyServiceApp
{
[ServiceContract]
public interface IMyService
{
[OperationContract]
string Hello(string strName);
}
}
There is no direct way to connect to WCF service from Android studio, but you can still consume it (WCF Service) as SOAP/POST.
To get you started - look at previous answer by Andy white - I'm using this approach as well and it is working quite well.
Note : You might want to inspect packets that service sends/gets via some tool like fiddler.
Alternatively for people that are using Xamarin (I know that it doesn't help in your situation, but it might be usefull for other people) - I would look at microsoft documentation (or SO if you like it more).

Connecting Android app to ASP.NET web service: java.net.MalformedURLException: Protocol not found

I am learning how to connect an Android app to ASP.NET web service from an online tutorial. When learning, I replaced their web service with one I had written on my own and ran it on a PC from Visual Studio. Then, I called the method 'Add' in the web service from the Android app but I am getting this error:
java.net.MalformedURLException: Protocol not found
I believe there is something wrong with the SOAP_ADDRESS field below.
public final String SOAP_ACTION = "http://tempuri.org/Add";
public final String OPERATION_NAME = "Add";
public final String WSDL_TARGET_NAMESPACE = "http://tempuri.org/";
public final String SOAP_ADDRESS = "12.145.142.45:50428/WebService.asmx";
This is the code of my web service.
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class WebService : System.Web.Services.WebService
{
public WebService()
{
//Uncomment the following line if using designed components
//InitializeComponent();
}
[WebMethod]
public int Add(int a, int b)
{
return a+b;
}
}
I think the error is showing up because I cannot specify IP addresses like that directly in Java code. So, my question is what is the correct SOAP_ADDRESS value for connecting the Android app to my ASP.NET web service?

HTTP status 404 error while calling WCF service from ASP.NET client after web service migration from ASP.NET to WCF

Currently we have a number of customers which use ASP.NET clients to call our various ASP.NET Web Services. We would like to migrate web services to WCF without touching customers' clients and their proxies. In addition we want to avoid using IIS for hosting services.
I've prepared simple prototype to examine if we are able to achieve such migration. This prototype works fine if only a simple namespace of web service is in use e.g. test.com. But because our ASP.NET services have namespaces like test.com/app1, test.com/app2 etc we need to build WCF services accordingly. Unfortunately when such address is used I get HTTP status 404 error while calling service's method.
After a few days of struggling I'm not sure if such migration is possible without hosting services on IIS (the IIS solution is http://msdn.microsoft.com/en-us/library/aa738697(v=vs.100).aspx).
Please, follow steps which I've done to prepare working prototype (with namespace test.com) and tell me where I'm wrong for extended namespace (like test.com/app).
1.
Initial ASP.NET web service:
[WebService(Namespace = "http://test.com")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class AspNetWebService : WebService
{
private static int _counter = 0;
[WebMethod]
public int Increment()
{
return _counter++;
}
}
2.
Deploy web service on IIS 7.0.
3.
Create simple ASP.NET client and generate proxy to web service (from step 1) by adding web reference in Visual Studio 2012 to asmx file of web service.
4.
Client calls Increment method properly, so I will not change this client to check if I may call WCF service.
5.
Create WCF service.
Contract:
[ServiceContract(Name = "IncrementService", Namespace = "http://test.com")]
public interface IIncrementService
{
[OperationContract(Action = "http://test.com/Increment")]
int Increment();
}
Service:
[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
public class IncrementService : IIncrementService
{
private static int _counter = 0;
public int Increment()
{
return _counter++;
}
}
Self hosted in:
static void Main(string[] args)
{
const string httpAddress = "http://test.com";
var host = new ServiceHost(typeof(IncrementService), new Uri(httpAddress));
try
{
var metadataBehavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (metadataBehavior == null)
metadataBehavior = new ServiceMetadataBehavior();
metadataBehavior.HttpGetEnabled = true;
host.Description.Behaviors.Add(metadataBehavior);
var httpBinding = new BasicHttpBinding();
httpBinding.Security.Mode = BasicHttpSecurityMode.None;
httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
host.AddServiceEndpoint(typeof(IIncrementService), httpBinding, httpAddress);
host.Open();
Console.ReadLine();
host.Close();
}
catch (Exception ex)
{
Console.WriteLine("An exception occurred: {0}", ex.Message);
host.Abort();
}
}
6.
Switch off IIS to be sure that ASP.NET web service doesn't work and start WCF service.
7.
Run the same client as before (without any changes or proxy regenerations) - it calls Increment properly.
So far so good... now I extend namespace.
8.
Add app name to namespace in ASP.NET web service as following:
[WebService(Namespace = "http://test.com/app")]
Switch on IIS again, switch off WCF service, regenerate proxy for client to work with new namespace - it calls Increment method properly again.
Change namespaces in WCF service as following:
Contract:
[ServiceContract(Name = "IncrementService", Namespace = "http://test.com/app")]
public interface IIncrementService
{
[OperationContract(Action = "http://test.com/app/Increment")]
int Increment();
}
In host application change httpAddress:
const string httpAddress = "http://test.com/app";
Switch off IIS, start WCF.
Try to call Increment method from the same client - exception occurs: The request failed with HTTP status 404: Not Found.
If I do not change httpAddress in step 10, then all works fine, but in such case I can host only one service on test.com domain. So this solution is not sufficient for us.
Finally I found the solution.
The httpAddress in step 10 should be set the same as URL of ASP.NET Web Service taken from ASP.NET client generated in step 3.
In my case, the URL of Web Service is (you may find it in client's app.config):
http://192.168.1.2/WS_simple/AspNetWebService.asmx
where WS_simple is ASP.NET application name hosted in IIS (created in step 2)
So I changed httpAddress to:
http://localhost/WS_simple/AspNetWebService.asmx
Maybe it's not nice address of WCF service but it works. So migration to WCF service without IIS with backward compatibility is done :)

How to debug a WCF service in a hosted solution?

I've created a fairly simply web service that has 1 method: UploadFile. Obviously, it works on my machine ©. However, once I upload it, the method return status 202 (Accepted). However, the file never arrives there and there are no errors that I can see. I've added logging to pretty much every second like of code, but it does not seem like the method actually executes.
How do I debug something like that?
Here is my server-side code for reference:
[ServiceContract]
interface IUploaderService
{
[OperationContract(IsOneWay = true)]
[WebInvoke(Method = "POST", UriTemplate = "/UploadFile?fileName={fileName}")]
void UploadFile(string fileName, Stream fileContents);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class UploaderService : IUploaderService //ServiceHostFactory
{
public void UploadFile(string fileName, Stream fileContents)
{
Log.Add("In UploadFile");
}
}
You have an interesting problem, and I played around with it and wrote a solution in the post at http://blogs.msdn.com/b/carlosfigueira/archive/2011/08/02/wcf-extensibility-system-diagnostic-tracing.aspx.
Basically, instead of tracing to a file (which is the usual way of doing tracing), you'd add a custom trace listener which would collect the traces from your application. You can use one of the databases provided by GoDaddy (MySql, SqlServer, EasyDB), or like in the code sample linked in the post, store the traces in memory and expose them via another WCF service.
try following
[ServiceContract]
interface IUploaderService
{
[OperationContract(IsOneWay = true)]
[WebInvoke(Method = "POST", UriTemplate = "/UploadFile?fileName={fileName}")]
[WebContentType("application/octet-stream")]
void UploadFile(string fileName, Stream fileContents);
}
If it doesn't work I would also try
[OperationContract]
this way if something happens on service you will have feedback on client side.

Categories