Cannot access Elmah error log when using wcf - asp.net

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.

Related

WCF Web Deploy HTTP Error 404 - Not Found

I have created a REST WCF web service in vb.net and published it to 1&1 Host Server using Web Deploy. When trying to call one of the services, I keep receiving:
HTTP Error 404 - Not Found.
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
I have looked at the wwwroot directory and I can find the .svc files and web.config, so I can't figure out why it can not find it. The call I am making is: http://localhost/Service1.svc/GetTimesheetDetails/1/1/11256/2017-8-9
<OperationContract()>
<WebInvoke(Method:="GET", ResponseFormat:=WebMessageFormat.Json, BodyStyle:=WebMessageBodyStyle.Wrapped, UriTemplate:="GetTimesheetDetails/{userid}/{organisationid}/{jobid}/{sdate}")>
Function GetTimesheetDetails(ByVal userid As String, ByVal organisationid As String, ByVal jobid As String, ByVal sdate As String) As List(Of JobEngineerTime)
I have tested these calls running them on Visual Studio and it works fine, unfortunately I am unable to get it to run through the 1&1 server.
This is my web.config:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<!--Disabled custom errors to allow display of detailed errors.-->
<!--<customErrors mode="Off"/>-->
<customErrors mode="RemoteOnly" defaultRedirect="~/Errors/500.htm">
<error statusCode="404" redirect="~/Errors/404.htm"/>
</customErrors>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="webBehaviour">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="metadataBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="metadataBehavior" name="WCFTimesheetWebService.Service1">
<endpoint address="" behaviorConfiguration="webBehaviour"
binding="webHttpBinding" contract="WCFTimesheetWebService.IService1" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
<service behaviorConfiguration="metadataBehavior" name="WCFTimesheetWebService.Service2">
<endpoint address="" behaviorConfiguration="webBehaviour"
binding="webHttpBinding" contract="WCFTimesheetWebService.IService2" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
<service behaviorConfiguration="metadataBehavior" name="WCFTimesheetWebService.Service3">
<endpoint address="" behaviorConfiguration="webBehaviour"
binding="webHttpBinding" contract="WCFTimesheetWebService.IService3" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<!-- Allowing Cross-Origin Resource Sharing (CORS) - The httpProtocol settings allow web services to be called from external domains using JavaScript-->
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type, Accept" />
</customHeaders>
</httpProtocol>
<modules runAllManagedModulesForAllRequests="true"/>
<httpErrors errorMode="Detailed" />
<validation validateIntegratedModeConfiguration="false"/>
<!--
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>
A couple of mappings were missing in IIS "Handler Mappings". To sort out the problem, all I had to do was click on "Revert to Parent" inside "Handler Mappings" which restored the missing mappings and it started working.

WCF Service wsHttpBinding

I'm getting error while creating wcf service using wsHtpBinding help page is getting error and services also not working
Help Page Error:
The resource cannot be found. Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
http://localhost:80/Service1.svc/help
My old working wsHttpbinding project web.config but it's not working now:
web.config
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" executionTimeout="3600" maxRequestLength="10000000"/>
<customErrors mode="Off" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceTypeBehaviors">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding >
<binding name="MyBasicwsHttpBinding">
<security mode="None">
<transport clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="MyServiceTypeBehaviors" name="WcfService1.Service1">
<endpoint address="mex" binding="wsHttpBinding" bindingConfiguration="MyBasicwsHttpBinding" name="WcfService1.Service1" contract="WcfService1.IService1"/>
</service>
</services>
<serviceHostingEnvironment minFreeMemoryPercentageToActivateService="0" aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
In my case, I found out that a Microsoft IIS filtering module Url Scan 3.1 was installed on IIS/website, which have it's own limit to reject incoming requests based on content size and return "404 Not found page".
It's limit can be updated in %windir%\System32\inetsrv\urlscan\UrlScan.ini file by setting MaxAllowedContentLength to the required value.
For eg. following will allow upto 300 mb requests
MaxAllowedContentLength=314572800

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.

Error 302 returned while using WCF for Forms Authentication and Accessing Authentication_JSON_AppService.axd

I have a client and application which are set up to use the ClientFormAuthenticationMembershipProvider for authentication. On the client side, when the application boots up the system prompts for a username and password. The server is set up to accept this, and a Web Application is supposed to permit the application to work. We are in the midst of setting up a new environment, and something is not working on the server side (if we point the client at another server, it works fine). We've painstakingly gone over every detail we can think of, and the result is the same: The call to ValidateUser() throws an exception. I have downloaded a network sniffer, and under the hood I can see that a 302 message is being returned when I try to call Authentication_JSON_AppService.axd. On the server side, ProcMon registers attempts to read the Authentication_JSON_AppService.axd file from within the wwwroot/../Authentication_JSON_AppService.axd, which obviously does not exist.
Client Side Configuration:
From our FormMain.cs (which attempts to call the provider)
if (!System.Web.Security.Membership.ValidateUser(null, null))
System.Windows.Forms.Application.Exit();
else
{
DoStartUp();
....
}
From Our FormLogin.cs (which prompts for UserName and Pass) Note: class inherits
IClientFormsAuthenticationCredentialsProvider
public System.Web.ClientServices.Providers.ClientFormsAuthenticationCredentials GetCredentials()
{
if (this.ShowDialog() == DialogResult.OK)
{
return new ClientFormsAuthenticationCredentials(
textEditUsername.Text, textEditPassword.Text,
false);
}
else
{
return null;
}
}
From the app.config:
<membership defaultProvider="ClientAuthenticationMembershipProvider">
<providers>
<clear />
<add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="http://SERVERNAME/APPNAME/Authentication_JSON_AppService.axd" credentialsProvider="APPNAME.Windows.FormLogin, APPNAME.Windows" savePasswordHashLocally="False" />
</providers>
</membership>
On the server side:
IIS has been configured for this application for anonymous authentication and forms authentication. (we're running IIS 7.5, .NET 4.0, Windows Server 2008 R2). We have the WCF Activation and HTTP Activation features installed on the server. The ApplicationPool is set to v4.0 Framework, 32-bit Applications not enabled, Integrated PipelineMode, most other values set to default.
The web.config file:
<system.web.extensions>
<scripting>
<webServices>
<authenticationService enabled="true" />
<roleService enabled="true" />
</webServices>
</scripting>
</system.web.extensions>
<authentication mode="Forms">
<forms name=".MDPSApp" loginUrl="~/Connect/Login.aspx" slidingExpiration="true" timeout="600000">
</forms>
</authentication>
<authorization>
<deny users="?" />
</authorization>
<membership defaultProvider="XYZ">
<providers>
<add name="XYZ" type="APPNAME.Web.Providers.MembershipProvider, APPNAME.Web" />
</providers>
</membership>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="DisableAutoCookieManagement" maxReceivedMessageSize="2147483647" allowCookies="false">
<readerQuotas maxDepth="64" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None" />
</binding>
</wsHttpBinding>
<behaviors>
<serviceBehaviors>
<behavior name="APPNAME.Application.Web.Services.AgenceMaster.ServiceAgenceMasterBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceAuthorization principalPermissionMode="None">
</serviceAuthorization>
</behavior>
<behavior name="APPNAME.Application.Web.Services.Agence.ServiceAgenceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="APPNAME.Application.Web.Services.AgenceMaster.ServiceAgenceMasterBehavior" name="APPNAME.Application.Web.Services.AgenceMaster.ServiceAgenceMaster">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="DisableAutoCookieManagement" contract="APPNAME.Services.AgenceMaster.IServiceAgenceMaster">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
<service behaviorConfiguration="APPNAME.Application.Web.Services.Agence.ServiceAgenceBehavior" name="APPNAME.Application.Web.Services.Agence.ServiceAgence">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="DisableAutoCookieManagement" contract="APPNAME.Services.Agence.IServiceAgence">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
The APPNAME.Web.Providers.MembershipProvider class extends System.Web.Security.MembershipProvider and overrides ValidateUser(string username, string password) with custom code. This class is not getting instantiated or called during the scenario.
Something isn't configured properly on the server side, or else the server would know how to resolve the Authentication_JSON_AppService.axd call properly (and it seems to me like it's not). Any thoughts or help are appreciated!
This was driving me bonkers. In FireFox - if I entered the URL for my *.aspx page that invoked my WCF REST call - everything worked fine. If I then did a shift-reload - I would get a 302 which redirected me to a non-existent forms login page.
In Safari and Chrome - no shift-reloaded needed. It would fail with the 302 on the first load.
I found the basic answer in the Alex on ASP.NET blog
Short answer: change the web.config to remove forms authentication:
<modules runAllManagedModulesForAllRequests="true">
<remove name="FormsAuthentication" />
</modules>

How does one debug a WCF Data Service?

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.

Resources