WCF web service binding configuration not being applied - wcf

I have a WCF web service called "Palladium" that is created as a project in a VS2008 solution.
I have an ASP.Net Web Application that hosts this service on a page called, "Palladium.svc".
When I post form data to the web service my service receives that data and can do stuff with it.
Now I'm posting images to the service and the post size exceeds WCF's default maxReceivedMessageSize property. To get around this, I've added a binding configuration to the end point on the ASP.Net Web Application's web.config file.
My problem is that the binding configuration doesn't appear to be applying.
The service is being posted to from an iPhone app, and when the post size is under 65k the service works fine. As soon as the post size exceeds this I get a 400 (Bad Request) error.
For testing purposes I created a test.aspx file in my ASP.Net Web Application which posts some forms values and an image to the web service. Again, when the post size is under the default 65k size the service works fine. Over 65k and I get served a 400 error.
The test page posts to a URL matching the following URITemplate /job-photo/{photoId}/{palladiumId}/{jobId}
If someone could help me debug this problem, it would be much appreciated.
Markup for Test Page:
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" action="http://localhost/cds/resources/services/palladium.svc/job-photo/1/235DE168-5D1C-46A4-89F2-FD17C6B9F415/567" method="post" enctype="multipart/form-data">
<div>
<input type="text" name="user" value="joe bloggs" />
<input type="file" name="photo" />
<input type="submit" name="btnsubmit" value="submit" />
</div>
</form>
</body>
</html>
Service information from web.config:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="large_message_binding" maxBufferPoolSize="5242880" maxReceivedMessageSize="5242880">
<readerQuotas maxStringContentLength="5242880" maxArrayLength="5242880" maxBytesPerRead="5242880" />
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="CDS.UI.Resources.Services.PalladiumBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="CDS.UI.Resources.Services.PalladiumBehavior"
name="CDS.UI.Resources.Services.Palladium">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="large_message_binding" contract="CDS.PalladiumService.IPalladium">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
Markup from Palladium.svc
<%# ServiceHost Language="C#" Debug="true" Service="CDS.PalladiumService.Palladium" Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>

My understanding was that
Service="CDS.PalladiumService.Palladium"
should be referencing the underlying type.
As should the name attribute from here:
<service behaviorConfiguration="CDS.UI.Resources.Services.PalladiumBehavior"
name="CDS.UI.Resources.Services.Palladium">
If you assign them to the actual type of the underlying service class does it resolve your issue?

Related

Dynamics AX 2012 WCF service error

I'm facing a very strange issue with a custom AX 2012 R3 CU9 AIF WCF service.
My goal is to use my AX wcf service with wsHttpBinding + Basic authentication + TransactionFlow enabled.
This error occurs every time I try to add a service reference for this service in VS \ open a service link in a browser:
Object Server 01: An error has occurred in the services framework. Method: AifMessageInspector::AfterReceiveRequest. Error: System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.Dynamics.Ax.Services.AxServiceOperationContext.InitializeSession()
at Microsoft.Dynamics.Ax.Services.AxServiceOperationContext.InitializeContext()
at Microsoft.Dynamics.Ax.Services.AxServiceOperationContext.Attach(OperationContext owner)
at System.ServiceModel.ExtensionCollection`1.InsertItem(Int32 index, IExtension`1 item)
at System.Collections.Generic.SynchronizedCollection`1.Add(T item)
at Microsoft.Dynamics.Ax.Services.AifMessageInspector.AfterReceiveRequest(Message& request, IClientChannel channel, InstanceContext instanceContext)
IIS:
Enabled only Anonymous and Basic authentication
Created self-signed certificate and added it to Server certificates on the host, "Trusted Root Certification Authorities" and "Enterprise Trust" folders
Enabled https binding on this web-site with this certificate
Checked "Require SSL" option on the web-site
AX:
HTTP inbound port
Use 'Configure AOS' instead of 'Configure' option
Use wsHttpBinding with Transport security and
TransportClientCredentialType = Basic
Web config (aos.config) that AX generates:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.diagnostics />
<system.serviceModel>
<diagnostics>
<messageLogging logEntireMessage="true" logKnownPii="true" logMalformedMessages="true"
logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
<endToEndTracing propagateActivity="true" activityTracing="true"
messageFlowTracing="true" />
</diagnostics>
<bindings>
<wsHttpBinding>
<binding name="wsHttpBindingTransportBasic" transactionFlow="true">
<security mode="Transport">
<transport clientCredentialType="Basic" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="DefaultServiceGroupBehavior">
<serviceMetadata httpGetEnabled="false" httpGetUrl="http://ax2012r2a/MicrosoftDynamicsAXAif60/WCFService/xppservice.svc"
httpsGetEnabled="true" httpsGetUrl="https://ax2012r2a/MicrosoftDynamicsAXAif60/WCFService/xppservice.svc" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceThrottling maxConcurrentCalls="200" maxConcurrentSessions="200"
maxConcurrentInstances="200" />
<useRequestHeadersForMetadataAddress />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="DefaultServiceGroupBehavior"
name="Microsoft.Dynamics.Ax.Services.WCFService">
<endpoint address="https://ax2012r2a/MicrosoftDynamicsAXAif60/WCFService/xppservice.svc"
binding="wsHttpBinding" bindingConfiguration="wsHttpBindingTransportBasic"
name="DefaultServiceGroupEndPoint" contract="Microsoft.Dynamics.Ax.Services.ServiceGroup" />
</service>
</services>
<client>
<endpoint address="https://ax2012r2a/MicrosoftDynamicsAXAif60/WCFService/xppservice.svc"
binding="wsHttpBinding" bindingConfiguration="wsHttpBindingTransportBasic"
contract="*" name="DefaultServiceGroupEndPoint" />
</client>
</system.serviceModel>
</configuration>
What could be happening?
Any help would be highly appreciated.
Thank you.

WCF username authentication not working

I'm new to WCF service. I wanted to create a WCF service with basichttpbinding to create a custom authentication mechanism before giving access to my WCF service. I have used
security mode = Transport and clientcredentialtype = basic. I have written a custom validator function for validating my username and password.
validator function
namespace CustomValidator
{
public class MyCustomValidator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
// This isn't secure, though!
if ((userName != "check") || (password != "check"))
{
throw new SecurityTokenException("Validation Failed!");
}
}
}
}
This is my service config file
< ?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<identity impersonate="false" />
</system.web>
<system.serviceModel>
<diagnostics>
<endToEndTracing activityTracing="true" messageFlowTracing="true" propagateActivity="true"></endToEndTracing>
</diagnostics>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpEndpointBinding">
<security mode="Transport">
<transport clientCredentialType="Basic" />
<!-- <message clientCredentialType="UserName" />-->
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="ServiceBehavior" name="Service">
<endpoint address="" binding="basicHttpBinding" name="BasicHttpEndpoint" bindingConfiguration="BasicHttpEndpointBinding" contract="IService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="false" />
<!-- 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" />
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="CustomValidator.MyCustomValidator, App_Code" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<security>
<authentication>
<basicAuthentication enabled="true" />
<anonymousAuthentication enabled="false" />
<windowsAuthentication enabled="false" />
</authentication>
</security>
</system.webServer>
</configuration>
So the problem here is that whenever I run my service, I get a login dialog were I enter username and password(my validator expects both username and password to be same), I'm not getting my service details page, which used to come up in normal case (without authentication mechanism). I don't know what I'm missing, I do feel like its all in configurations which matters in my case but still I can't find out the mistake.
Have Created and Shared a Demo Project for Username Password Authentication.Its Working Fine.
Pls Check
https://onedrive.live.com/redir?resid=3FE322C74D6AA4D1%21169
You can use SelfCert,given inside,to Create a Certificate with name TrustedPeople , Store Location LocalMachine

Scalabilty issues with Restful WCF

Hi I have built a simple WCF application I am using to query data back and forth from Mobile app.
Everything else works Fine But When I try to Upload large binary video upload it gives me weird error, I am successfully able to upload binary streams upto 3-4 MB but larger than that
I get one of the following error randomly
1.
<html>
<BODY>
<FONT face="Helvetica">
<big><strong></strong></big><BR>
</FONT>
<blockquote>
<TABLE border=0 cellPadding=1 width="80%">
<TR><TD>
<FONT face="Helvetica">
<big>Network Error (tcp_error)</big>
<BR>
<BR>
</FONT>
</TD></TR>
<TR><TD>
<FONT face="Helvetica">
A communication error occurred: ""
</FONT>
</TD></TR>
<TR><TD>
<FONT face="Helvetica">
The Web Server may be down, too busy, or experiencing other problems preventing it from responding to requests. You may wish to try again at a later time.
</FONT>
</TD></TR>
<TR><TD>
<FONT face="Helvetica" SIZE=2>
<BR>
For assistance, contact your network support team.
</FONT>
</TD></TR>
</TABLE>
</blockquote>
</FONT>
</BODY>
</html>
2.
<html>
<body>
<div id="header"><h1>Server Error</h1></div>
<div id="content">
<div class="content-container"><fieldset>
<h2>404 - File or directory not found.</h2>
<h3>The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable.</h3>
</fieldset></div>
</div>
</body>
</html>
Here is my Web.Config
<?xml version="1.0"?>
<configuration>
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="2147483648" />
</requestFiltering>
</security>
</system.webServer>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
<bindings>
<webHttpBinding>
<binding transferMode="Streamed" maxBufferSize="5242880" maxReceivedMessageSize="2147483647" openTimeout="05:25:00" closeTimeout="00:25:00" sendTimeout="00:25:00" receiveTimeout="0:25:00"
name="webBinding"
/>
</webHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="RestBehavior" name="EyePlots.Videos">
<endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" bindingConfiguration="webBinding"
contract="EyePlots.IVideos" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="RestBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceThrottling maxConcurrentCalls="100"
maxConcurrentInstances="100" maxConcurrentSessions="100" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Could it be issue with the scalability of the system? I can post my code snippets if you guys want? Thanks!
I think 4 megs is an IIS throttle.
Have you set (IIS7+)
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="2147483648" />
</requestFiltering>
</security>
</system.webServer>
Here's a post listing out some more throttles to try opening up. WCF problem with uploading large file, hosted in IIS

WCF self-hosted service SSL/transport security/Basic authentication doesn't ask for credentials

I've created a self-hosted WCF service with HTTPS/SSL, transport security and Basic authentication. For some reason, when I run the service in the browser it never asks for credentials. What's wrong?
Service configuration:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="WsHttpTest.GreetingServiceBehavior">
<serviceMetadata httpsGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="TransportSecurity">
<security mode="Transport">
<transport clientCredentialType="Basic"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="WsHttpTest.GreetingServiceBehavior" name="WsHttpTest.GreetingService">
<host>
<baseAddresses>
<add baseAddress="https://localhost:8555/WsHttpTest/Greeting" />
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="TransportSecurity" contract="WsHttpTest.IGreetingService" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
</configuration>
HTTP config:
C:\>httpcfg query ssl
IP : 0.0.0.0:8555
Hash : 14ae237add3c49 a5091367487563cf6f6a8f586
Guid : {9416496a-6d3e-4680-a9d1-03defd97d7d6}
CertStoreName : MY
CertCheckMode : 0
RevocationFreshnessTime : 0
UrlRetrievalTimeout : 0
SslCtlIdentifier :
SslCtlStoreName :
Flags : 0
------------------------------------------------------------------------------
C:\>httpcfg query urlacl
URL : https://localhost:8555/WsHttpTest/Greeting/
ACL : D:(A;;GX;;;WD)
------------------------------------------------------------------------------
The configuration of wsHttpBinding is used only if you communicate with the endpoint = you create the proxy and call operation exposed on service contract. When opening the service's help page you don't communicate with the endpoint.
ServiceMetadataBehavior also offers two additional properties HttpsHelpPageBinding and HttpsHelpPageBindingConfiguration. Perhaps if you play with these properties and configure some custom binding (must be custom because it requires MessageVersion.None) for them you will be able to force help page to require authentication as well but I have never tried it.
I would start with something like:
<bindings>
<cutstomBinding>
<binding name="helpPage">
<textMessageEncoding messageVersion="None" />
<httpsTransport authenticationScheme="Basic" />
</binding>
</customBinding>
</bindings>

Problem with downloading many files from WCF

I have problem with WCF service. When I am downloading 2 files everything works fine ( less than 1 minute), but when I'm trying downloading more than 3 files there is going something bad . I'm waiting and waiting and nothing :/ Every file has about 1 MB.
Dictionary<FileIdentifier, Stream> data = new Dictionary<FileIdentifier, Stream>();
foreach (string path in paths)
{
using (var client = new ServiceClient())
{
var stream = client.GetFile(path);
data[fileIdentifier] = stream;
}
}
Method at WCF Service:
public Stream GetFile(string path)
{
FileStream fs = new FileStream(stream, FileMode.Open);
fs.Close();
return fs;
}
config of WCF service:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<client />
<bindings>
<basicHttpBinding>
<binding name="basicHttpBindingConfiguration" closeTimeout="00:10:00"
openTimeout="00:15:00" receiveTimeout="00:15:00" sendTimeout="00:15:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="2097152000" maxBufferPoolSize="524288000" maxReceivedMessageSize="2097152000"
messageEncoding="Text" textEncoding="utf-8" transferMode="Streamed"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="524288000"
maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="FileServer.Service" behaviorConfiguration="FileServer.Service1Behavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8731/Design_Time_Addresses/Server.FileServer/Service/" />
</baseAddresses>
</host>
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address="" contract="FileServer.IService" binding="basicHttpBinding" bindingConfiguration="basicHttpBindingConfiguration">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<!-- Metadata Endpoints -->
<!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
<!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="FileServer.Service1Behavior">
<!-- 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" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.web>
<compilation debug="true" />
<httpRuntime maxRequestLength="2097151" executionTimeout="1000" />
<customErrors mode="RemoteOnly" />
</system.web>
<system.webServer>
<directoryBrowse enabled="false" />
</system.webServer>
</configuration>
You should not close the stream on the service side.
Here is how you would do:
Open stream on service
Return stream to client
Read the stream on the client
Close the stream on the client
WCF will take care of closing the service stream for you
Instead of returning a stream, read the stream into a byte array and then return the byte array.