How does one debug a WCF Data Service? - asp.net

I have a WCF Data Service hosted in an Asp.Net website. here is my web.config services section :
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<services>
<service name="DataServiceHost"
behaviorConfiguration="DataServiceBehavior">
<endpoint name="DataServiceHost"
address=""
binding="webHttpBinding"
contract="System.Data.Services.IRequestHandler" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="DataServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
And I have config.UseVerboseErrors = true; in my InitializeService method.
I hit F5 I go into debug mode, and browse to my service, getting an error, though it doesn't break in VS. I'm at a loss.
the error btw : The server encountered an error processing the request. See server logs for more details.
I've looked for logs... I have ELMAH setup for the site, nothing in there. So I'm not sure what service logs it's talking about.
Any help would be greatly appreciated.

You can enable error logging like this:
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging" switchValue="Warning, ActivityTracing">
<listeners>
<add type="System.Diagnostics.DefaultTraceListener" name="Default">
<filter type="" />
</add>
<add name="ServiceModelMessageLoggingListener">
<filter type="" />
</add>
</listeners>
</source>
</sources>
<sharedListeners>
<add initializeData="c:\TEMP\web_messages.svclog"
type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
name="ServiceModelMessageLoggingListener" traceOutputOptions="Timestamp">
<filter type="" />
</add>
</sharedListeners>
</system.diagnostics>
Se more info here: http://msdn.microsoft.com/en-us/library/ms730064.aspx
Output file can be viewed in notedpad or in the "Service Trace Viewer" - see http://msdn.microsoft.com/en-us/library/aa751795.aspx
If you host in IIS you can use remote debugging: http://www.codeproject.com/KB/aspnet/IISRemoteDebugging.aspx

Additionally, you can subscribe to the sendingrequest event of your objectcontext: http://msdn.microsoft.com/en-us/library/system.data.services.client.dataservicecontext.sendingrequest.aspx.
Then, set a breakpoint in the event handler and inspect the request.

Related

Unable to Add Assembly reference in WCF Service Application in IIS 7.5

I've been trying to add a reference to an assembly named CAPI_PInvoke.dll (64 bit) in my wcf application. The dll is placed in my bin folder but when i access my service through https://localhost:port It gives following error
The IIS has permission to read/execute contents of the entire project directroy.
here's my web.config file
<?xml version="1.0"?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0"/>
</startup>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
</appSettings>
<system.web>
<compilation targetFramework="4.5"/>
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding
maxReceivedMessageSize="2147483647"
>
<readerQuotas/>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
I've studied several articles but unable to resolve the issue, Can anyone suggest a solution to this problem?

ajax request giving access denied while calling wcf service

I have created an amazon EC2 instance and hosted my .net web application on port 80 and WCF service on port 1212 port.
Locally on the remote session I am able to browse both application and service and able to make ajax request calls.
Only when I try doing same functionality over the internet(not on same remote session) which makes ajax call to wcf service on port 1212 ``gives access denied error. I have added $.support.cors = true; while making request.
Web application web.config:
<configuration>
<system.web>
<connectionStrings>
<add name="ApplicationServices"
connectionString="Server=somedbinstance.asdkfjlksd.us-west-2.rds.amazonaws.com;Initial Catalog=xed; user id=user ;password=pwd"
providerName="System.Data.SqlClient" />
</connectionStrings>
</system.web>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="webEndpoint">
<webHttp defaultBodyStyle="Wrapped"
defaultOutgoingResponseFormat="Xml" helpEnabled="true" />
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="webHttpBinding" />
</webHttpBinding>
</bindings>
<client>
<endpoint name="BasicHttpBinding_ICustomerRequestService"
address="http://10.90.12.121:1212/myservice.svc"
binding="webHttpBinding" bindingConfiguration="webHttpBinding"
behaviorConfiguration="webEndpoint"
contract="CustomerRequestService.ICustomerRequestService" />
</client>
<serviceHostingEnvironment
aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<defaultDocument>
<files>
<add value="index.aspx" />
</files>
</defaultDocument>
</system.webServer>
</configuration>
WCF Service web.config:
<system.serviceModel>
<services>
<service name="iHandyService.CustomerRequestService">
<endpoint
address=""
behaviorConfiguration="restfulBehavior"
binding="webHttpBinding" bindingConfiguration=""
contract="Interfac.ICustomerRequestService" />
<host>
<baseAddresses>
<add baseAddress="http://10.90.12.121:1212/myservice.svc" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="restfulBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true">
</serviceHostingEnvironment>
</system.serviceModel>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>
</httpProtocol>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
Ajax call:
error function gives access denied error.
Please guide me on this error and how to resolve it.
You need to add this port to AWS console->EC2-->Security group-->Inbound rules-->Port. This link will be helpful. You need to select security group corresponding to your instance, and this is also visible in instances link.
LINK1 , LINK2
Also make sure, you have added this port to windows firewall inbound rule. - http://technet.microsoft.com/en-us/library/cc947789(v=ws.10).aspx
Note: You might need to configure WCF service to be CORS ready, follow this link - WCF REST Service Template 40(CS) Cross domain error, i have answered there how to make it CORS enabled.

Cannot access Elmah error log when using wcf

I've been trying to use ELMAH with WCF and I have added the "normal" ErrorHandler and ServiceErrorBehavior to a service. These work, I can see that when there is an exception the code in these runs and logs an error to ELMAH. So it should be fine but when I try to access the error log page elmah.axd I get HTTP 404 and WCF gives me the "Endpoint not found page".
Which means that the Elmah.ErrorLogPageFactory was not used on that url. So what it comes down to is my web.config (I think). I just can't get this right, here are the relevant parts of my web.config:
My service endpoints are setup like so:
<system.serviceModel>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true"
automaticFormatSelectionEnabled="true" />
</webHttpEndpoint>
</standardEndpoints>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
<services>
<service name="SaraService.SaraService"
behaviorConfiguration="SaraSvcBehaviour" >
<endpoint name="SaraService"
address=""
binding="webHttpBinding" bindingConfiguration="webHttpBindingWithJsonP"
behaviorConfiguration="RestEndPointBehaviour"
contract="SaraService.ISaraService" />
<endpoint
address="soap"
behaviorConfiguration="SoapEndPoinstBehaviour"
binding="basicHttpBinding"
contract="SaraService.ISaraService" />
<endpoint
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="SaraSvcBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="RestEndPointBehaviour">
<webHttp />
</behavior>
<behavior name="SoapEndPoinstBehaviour">
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="webHttpBindingWithJsonP"
crossDomainScriptAccessEnabled="true">
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
So there are endpoints in / and /soap urls.
And my ELMAH config is like this:
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<httpModules>
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" />
<add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" />
</httpModules>
</system.web>
</location>
<system.webServer>
<handlers>
<add name="ELMAH" verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" preCondition="integratedMode" />
</handlers>
</system.webServer>
And I'm also running AutofacServiceHostFactory in the root url. Here is my global.asax.cs for the relevant parts:
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
var builder = new ContainerBuilder();
builder.RegisterType<SaraService>();
builder.RegisterType<MarkkinadataAccess.MarkkinadataEntities>().InstancePerLifetimeScope();
builder.RegisterType<GenerisDbConnectionSettings>().As<IGenerisDbConnectionSetting>().SingleInstance();
builder.RegisterType<GenerisApplication>().As<IGenerisApplication>().PropertiesAutowired().InstancePerLifetimeScope();
builder.RegisterType<CrmProductsQuery>().As<ICrmProductsQuery>();
builder.RegisterType <ProductsByNameQuery>().As<IProductsByNameQuery>();
builder.RegisterType<ProductMWQueryByName>().As<IProductMWQueryByName>();
builder.RegisterType<ProductMWQueryById>().As<IProductMWQueryById>();
AutofacHostFactory.Container = builder.Build();
RouteTable.Routes.Add(new ServiceRoute("", new AutofacServiceHostFactory(), typeof(SaraService)));
}
}
So my guess is that either running the service endpoint in root or the AutofacServiceHostFactory somehow prevents me accessing ELMAH log page in /elmah.axd url.
But I just don't understand why or how.
In any case, any help would be much appreciated.
Ok, I got this now (partially at least). The culprit is this line in my global.asax:
RouteTable.Routes.Add(new ServiceRoute("", new AutofacServiceHostFactory(), typeof(SaraService)));
So this will make the service endpoint to root which is what I wanted.
Also I just wanted a route (any route other than root) to access the ELMAH error log page. Which of course means that there has to be a route with a handler that runs the Elmah.ErrorLogPageFactory.
Now this should be simple but when I add my service to root url then it seems that I cannot access any route with a handler (axd) no matter what.
This just seems odd to me because I can create a file for example in www/index.html and that will be served just fine without touching the web.config at all. But in case of a "generated" route like elmah.axd or www/elmah.axd the service that I added in the root url will always get executed. Giving me the "no endpoint" page which is WCF pipelines HTTP 404.
In any case, if I put my service to some url other than root I can access ELMAH error log.
And yes, I did try ignoring elmah.axd url but it just gave me normal 404 error.
So I guess I'll just have to put my service to some place other than root unless somebody can come up with a better answer to do this.

"An error occurred while getting provider information from the database" while deploying Code First

I'm getting the following error while deploying my ASP.NET MVC 4 application (Code First) to IIS:
"An error occurred while getting provider information from the database.
This can be caused by Entity Framework using an incorrect connection string. Check the inner exceptions for details and ensure that the connection string is correct."
I've been looking around for answers, but none of the situations matches mine:
I got 2 projects
BackEnd (DataAccess with Code First + WCF services)
FrontEnd MVC 4 application (only service references to WCF services)
On my local IIS + SQL Server 2008 it works fine. Even if I change connectionstring to production database everything works as espected.
The problem occurs when deploying the BackEnd + FrontEnd to IIS.
The only connection string that accesses db is located in my BackEnd application:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="fromMail" value="xxx#gmail.com" />
</appSettings>
<connectionStrings>
<add name="TTCWestelDbContext" connectionString="Data Source=192.168.2.14\SQLSERVER2008;Initial Catalog=TTCWestel001;Persist Security Info=True;User ID=XXX;Password=XXX" providerName="System.Data.SqlClient" />
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<httpRuntime maxRequestLength="102400" executionTimeout="3600" />
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="64" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true" />
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483646" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<directoryBrowse enabled="true" />
</system.webServer>
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing"
propagateActivity="true">
<listeners>
<add name="traceListener"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData= "c:\Temp\WCFTracesTTCWestel.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
</configuration>
Any help appreciated!!
Thanks
Micclo

ASP.NET Membership Provider authentication not working authenticating WCF Service

I have a SqlMembershipProvider store with Roles enabled. This is configured and has the user "devtest" in the roles "xxUser" and "xxAdmin".
I also have a WCF service, which I want to authenticate and authorize against. My problem is that:
the authorisation is not
happening, code just executes
despite the policy attribute
I don't get any identity or security
context so do not know who is
calling the service
I need:
to know which user is calling the
method
some degree of rejecting
users if permissions don't match up
(ideally this should be performed
within the
RoleProvider/MembershipProvider/WCF
but can do it myself if I have to)
SSL in transport
I have my service contract set up thus:
[ServiceContract]
public interface ISupportService
{
[OperationContract]
[PrincipalPermission(SecurityAction.Demand, Role = "ThisRoleDoesNotExist")]
List<BaseInterestRate> GetAllBaseInterestRates();
}
the code is simple enough:
public class SupportService : ISupportService
{
public List<BaseInterestRate> GetAllBaseInterestRates()
{
OperationContext operationContext = OperationContext.Current;
ServiceSecurityContext serviceSecurityContext = ServiceSecurityContext.Current; // is always null
using (xxxEntities entities = new xxxEntities())
{
return new List<BaseInterestRate>(entities.BaseInterestRates);
}
}}
My service configuration is thus:
-->
<behaviors>
<serviceBehaviors>
<behavior name="SupportServiceBehavior">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="AspNetSqlRoleProvider" />
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="MembershipProvider"
membershipProviderName="SqlMembershipProvider" />
</serviceCredentials>
</behavior>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
Having already configured the MembershipProvider:
<membership defaultProvider="SqlMembershipProvider" >
<providers>
<clear/>
<add name="SqlMembershipProvider"
connectionStringName="SqlMembershipProvider"
applicationName="xxx"
type="System.Web.Security.SqlMembershipProvider" />
</providers>
</membership>
<roleManager enabled="true">
<providers>
<clear />
<add connectionStringName="SqlMembershipProvider" applicationName="xxx"
name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" />
<add applicationName="xxx" name="AspNetWindowsTokenRoleProvider"
type="System.Web.Security.WindowsTokenRoleProvider" />
</providers>
</roleManager>
I have followed the instructions at these pages to the letter:
How to: Use the SQL Server Role Provider with Windows Authentication in WCF Calling from Windows Forms (MSDN)
How to: Create and Install Temporary Client Certificates in WCF During Development (MSDN)
How to: Use wsHttpBinding with Username Authentication and TransportWithMessageCredentials in WCF Calling from Windows Forms (MSDN)
Also quite useful found via SO: Use Asp.Net Membership provider with a WCF .svc service (Alkampfer's Place)
I would at lest expect an issue with certificates/transport/etc. to fail with exceptions, but I can debug right in and over the WCF call. I have no security context/ user context available to me and when I use a user not in the two mentioned roles (which I do in the code example above), I don't get "kicked out".
My client app is currently a Web App, but will ultimately also serve a Windows Forms app and Test suite. I'm currently using the ASP.NET WebDev server and am running .NET 4.0.
Am I missing something?
I'm a little new to WCF Rest services, but during my own testing I ran into a similar problem to this. I came across this video, which helped a bit (even if it wasn't quite what I was trying to do):
http://channel9.msdn.com/blogs/rojacobs/endpointtv-securing-restful-services-with-aspnet-membership
Essentially the problem was that under the asp.net configuration I had to disable anonymous access in order for it to use the MembershipProvider authentication:
system.web>
<authorization>
<deny users="?" />
</authorization>
...
I don't think you can set the principal permission on the interface.
I bet if you move it onto the service implementation method it will work
or at least start breaking for a different reason (I am currently stuck at that point - I get access denied exceptions - hopefully you dont!)
(I first tried to put them on the contract interface also)
this is the correct configuration for wcf service self-hosted with SSL:
<?xml version="1.0"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
<connectionStrings>
<add name="mySqlConnection" connectionString="Data Source=.\SQLEXPRESS2012;Integrated Security=SSPI;Initial Catalog=aspnetdb;"/>
</connectionStrings>
<system.web>
<compilation debug="true"/>
<!-- Configure the Sql Membership Provider -->
<membership defaultProvider="MySqlMembershipProvider" userIsOnlineTimeWindow="15">
<providers>
<clear/>
<add name="MySqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="mySqlConnection" applicationName="UsersManagementNavigationApplication" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" passwordFormat="Hashed"/>
</providers>
</membership>
<!-- Configure the Sql Role Provider -->
<roleManager enabled="true" defaultProvider="MySqlRoleProvider">
<providers>
<clear/>
<add name="MySqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="mySqlConnection" applicationName="UsersManagementNavigationApplication"/>
</providers>
</roleManager>
</system.web>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webBinding">
<security mode="Transport">
<transport clientCredentialType="Basic"/>
</security>
</binding>
</webHttpBinding>
<basicHttpBinding>
<binding name="basicBindingConfiguration">
<security mode="Transport">
<transport clientCredentialType="Basic"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="webEndpointBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="webServiceBehavior">
<serviceMetadata httpsGetEnabled="true"/>
<serviceThrottling/>
<serviceDebug/>
</behavior>
<behavior name="myServiceBehavior">
<!-- Configure role based authorization to use the Role Provider -->
<serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="MySqlRoleProvider">
</serviceAuthorization>
<serviceCredentials>
<!-- Configure user name authentication to use the Membership Provider -->
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WcfServiceHTTPSSelfHosted.MyCustomValidator, WcfServiceHTTPSSelfHosted" />
</serviceCredentials>
<!-- To avoid disclosing metadata information, set the value below to false before deployment -->
<serviceMetadata httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="myServiceBehavior" name="WcfServiceHTTPSSelfHosted.WcfServiceHTTPSSelfHosted">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicBindingConfiguration" contract="WcfServiceHTTPSSelfHosted.IWcfServiceHTTPSSelfHosted"/>
<endpoint address="web" behaviorConfiguration="webEndpointBehavior" binding="webHttpBinding" bindingConfiguration="webBinding" contract="WcfServiceHTTPSSelfHosted.IWcfServiceHTTPSSelfHosted"/>
<endpoint address="mex" binding="mexHttpsBinding" bindingConfiguration="" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="https://localhost:50001/WcfServiceHTTPSSelfHosted/"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
if you want more info take a look this:
http://www.albertoschiassi.it/Home/tabid/55/EntryId/94/Use-ASP-NET-SqlMemberShipProvider-in-WCF-self-hosted-service.aspx
and
http://www.albertoschiassi.it/Home/tabid/55/EntryId/95/Use-ASP-NET-SqlMemberShipProvider-in-WCF-self-hosted-service-with-SSL.aspx

Resources