I encountered this problem when I studied Silverlight a few days ago. I thought it was very difficult to test the results. I checked a lot of information to solve the problem. Here I wrote the solution to the problem, it is also convenient for other friends to learn from.
The problem is that I created a console application as the host Program of the WCF Service to test the communication with WCF during the Silverlight test.
A Silverlight application and a web program carrying Silverlight are created at the same time.
Solution:
Console program:
1. Add a WCF Service
Name it wcfservice. CS and add the service. The Code is as follows:
Namespace wcfbase
{
// Note: If you change the class name "wcfservice", you must also update the reference to "wcfservice" in APP. config.
Public class wcfservice: iwcfservice
{
Public int dowork (int A, int B)
{
Return A + B;
}
Public int dowork2 (int A, int B)
{
Return A-B;
}
}
}
The system automatically adds the app. config file and related configuration section information.
The content is as follows:
<? XML version = "1.0" encoding = "UTF-8"?>
<Configuration>
<System. servicemodel>
<Servicehostingenvironment aspnetcompatibilityenabled = "true"/>
<Behaviors>
<Servicebehaviors>
<Behavior name = "wcfbase. wcfservicebehavior">
<Servicemetadata httpgetenabled = "true"/>
<Servicedebug includeexceptiondetailinfaults = "false"/>
</Behavior>
</Servicebehaviors>
</Behaviors>
<Services>
<Service behaviorconfiguration = "wcfbase. wcfservicebehavior" name = "wcfbase. wcfservice">
<Endpoint address = "" binding = "basichttpbinding" Contract = "wcfbase. iwcfservice">
<Identity>
<DNS value = "localhost"/>
</Identity>
</Endpoint>
<Endpoint address = "mex" binding = "mexhttpbinding" Contract = "imetadataexchange"/>
<Host>
<Baseaddresses>
<Add baseaddress = "http: /localhost: 9090/wcfservice/"/>
</Baseaddresses>
</Host>
</Service>
</Services>
</System. servicemodel>
</Configuration>
2. Load the WCF Service
Open the main method of the main program entry. The Code is as follows:
Namespace wcfbase
{
Class Program
{
Static void main (string [] ARGs)
{
Servicehost host = new servicehost (typeof (wcfservice ));
Host. open ();
Console. writeline ("I'm here .");
Console. readkey ();
Host. Close ();
}
}
}
So far, the console program is running, and the WCF Service is available.
However, an error occurs when the domain access fails, prompting that the operation is not limited. The following operations are required:
3. Enable WCF to access Domains
A. Add the clientaccesspolicy. xml file to the root directory of the console program.
The content is as follows:
<? XML version = "1.0" encoding = "UTF-8"?>
<Access-Policy>
<Cross-domain-access>
<Policy>
<Allow-from http-request-headers = "*">
<Domain uri = "*"/>
</Allow-from>
<Grant-to>
<Resource Path = "/" include-subpaths = "true"/>
</Grant-to>
</Policy>
</Cross-Domain-access>
</Access-Policy>
B. Add the idomainservice interface (the name can be customized)
First, add system. servicemodel. Web reference.
The Code is as follows:
Using system;
Using system. Collections. Generic;
Using system. LINQ;
Using system. text;
Using system. IO;
Using system. xml;
Using system. servicemodel;
Using system. servicemodel. channels;
Namespace wcfbase
{
/**/
/// <Summary>
/// Cross-origin Access Policy Service Interface
/// Note: If you have updated the icrosdomainservice interface, you must update app. config at the same time.
/// </Summary>
[Servicecontract]
Public interface idomainservice
{
[Operationcontract]
[Webget (uritemplate = "clientaccesspolicy. xml")]
Message providepolicyfile ();
}
}
C. Implement the interface idomainservice
Class: domainservice (customizable)
The Code is as follows:
Namespace wcfbase
{
Public class domainservice: idomainservice
{
# Region idomainservice Member
Public System. servicemodel. channels. Message providepolicyfile ()
{
Filestream = file. Open (@ "clientaccesspolicy. xml", filemode. Open );
// Either specify clientacesspolicy. xml file path properly
// Or put that in/bin folder of the console application
Xmlreader reader = xmlreader. Create (filestream );
System. servicemodel. channels. Message result = message. createmessage (messageversion. None, "", Reader );
Return result;
}
// Crossdomainservicebehavior
# Endregion
}
}
D. Modify the app. config file.
After modification
<? XML version = "1.0" encoding = "UTF-8"?>
<Configuration>
<System. servicemodel>
<Servicehostingenvironment aspnetcompatibilityenabled = "true"/>
<Behaviors>
<Servicebehaviors>
<Behavior name = "wcfbase. wcfservicebehavior">
<Servicemetadata httpgetenabled = "true"/>
<Servicedebug includeexceptiondetailinfaults = "false"/>
</Behavior>
</Servicebehaviors>
<Endpointbehaviors>
<Behavior name = "domainservicebehavior">
<Webhttp/>
</Behavior>
</Endpointbehaviors>
</Behaviors>
<Services>
<Service behaviorconfiguration = "wcfbase. wcfservicebehavior" name = "wcfbase. wcfservice">
<Endpoint address = "" binding = "basichttpbinding" Contract = "wcfbase. iwcfservice">
<Identity>
<DNS value = "localhost"/>
</Identity>
</Endpoint>
<Endpoint address = "mex" binding = "mexhttpbinding" Contract = "imetadataexchange"/>
<Host>
<Baseaddresses>
<Add baseaddress = "http: /localhost: 9090/wcfservice/"/>
</Baseaddresses>
</Host>
</Service>
<Service name = "wcfbase. domainservice">
<Endpoint address = "" behaviorconfiguration = "domainservicebehavior"
Binding = "webhttpbinding" Contract = "wcfbase. idomainservice"/>
<Host>
<Baseaddresses>
<Add baseaddress ="Http: // localhost: 9090/"/>
</Baseaddresses>
</Host>
</Service>
</Services>
</System. servicemodel>
</Configuration>
The gray area is the newly added information. It is not complete yet. Continue...
E. Modify the main method for opening the main program entry in the console
The Code is as follows:
Namespace wcfbase
{
Class Program
{
Static void main (string [] ARGs)
{
Servicehost host = new servicehost (typeof (wcfservice ));
Host. open ();
Servicehost crossdomainservicehost = new servicehost (typeof (domainservice ));
Crossdomainservicehost. open ();
Console. writeline ("I'm here .");
Console. readkey ();
Host. Close ();
}
}
}
Add new code in the gray area
The final program structure is as follows:
By now, the WCF Service can implement domain access.
Note: copy the clientaccesspolicy. xml file to the same directory as wcfbase.exe.
4. Silverlight and WCF communication test
Run the console program wcfbase.exe
:
Add "service reference" to the Silverlight program at http: // localhost: 9090/wcfservice/
The Silverlight code is as follows:
Private void btntest_click (Object sender, routedeventargs E)
{
Servicereference1.wcfserviceclient WCF = new silverlightapp. servicereference1.wcfserviceclient ();
WCF. doworkcompleted + = new eventhandler <silverlightapp. servicereference1.doworkcompletedeventargs> (wcf_doworkcompleted );
WCF. doworkasync (1, 2 );
}
Void wcf_doworkcompleted (Object sender, silverlightapp. servicereference1.doworkcompletedeventargs E)
{
MessageBox. Show (E. Result. tostring ());
}
Test:
It proves that Silverlight can call the dowork method of WCF normally and return the result correctly.
Source code download:
Http://download.csdn.net/source/2014616