Angular 2替换Silverlight对接现有WCF服务遇适配问题咨询
Alright, let's tackle this problem head-on. You're looking to swap out your Silverlight frontend for Angular 2 while keeping your existing WCF backend (using basicHttpBinding)—and the main hurdle is getting Angular to talk to WCF since Angular leans on REST-style endpoints (typically webHttpBinding). The good news is you don't need to rewrite your WCF service at all; we can just extend it to support Angular's needs.
webHttpBinding Endpoint to Your WCF Service The key here is to add a new REST-friendly endpoint alongside your existing basicHttpBinding one. This way, Silverlight can keep using the old endpoint, and Angular uses the new one—no changes to your service's business logic required.
Step 1: Update Your WCF web.config
Modify your service configuration to include the new endpoint and enable JSON formatting by default:
<system.serviceModel> <services> <service name="YourServiceNamespace.YourExistingService"> <!-- Keep this for your Silverlight app --> <endpoint address="" binding="basicHttpBinding" contract="YourServiceNamespace.IYourExistingService"/> <!-- Add this REST endpoint for Angular --> <endpoint address="rest" binding="webHttpBinding" contract="YourServiceNamespace.IYourExistingService" behaviorConfiguration="webHttpBehavior"/> </service> </services> <behaviors> <endpointBehaviors> <behavior name="webHttpBehavior"> <!-- Set JSON as the default response format --> <webHttp defaultOutgoingResponseFormat="Json"/> </behavior> </endpointBehaviors> </behaviors> </system.serviceModel>
Step 2: Update Your Service Contract
Add [WebGet] or [WebInvoke] attributes to your service interface methods so WCF knows how to expose them as REST endpoints. You can reuse your existing method implementations—no need to duplicate code:
[ServiceContract] public interface IYourExistingService { // Original operation for Silverlight [OperationContract] string GetCustomerDetails(int customerId); // Add this attribute to enable REST access for the same method [OperationContract] [WebGet(UriTemplate = "GetCustomerDetails/{customerId}", ResponseFormat = WebMessageFormat.Json)] string GetCustomerDetails(int customerId); }
For POST operations, use [WebInvoke(Method = "POST", UriTemplate = "CreateCustomer", RequestFormat = WebMessageFormat.Json)] instead.
Now let's wire up Angular to talk to the new REST endpoint. We'll use Angular's HttpClient for this.
Step 1: Create an Angular Service
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class WcfCustomerService { // Point to your WCF service's REST endpoint private wcfRestUrl = 'http://your-wcf-service-domain/rest'; constructor(private http: HttpClient) { } getCustomerDetails(customerId: number): Observable<string> { return this.http.get<string>(`${this.wcfRestUrl}/GetCustomerDetails/${customerId}`); } }
Step 2: Use the Service in an Angular Component
import { Component, OnInit } from '@angular/core'; import { WcfCustomerService } from './wcf-customer.service'; @Component({ selector: 'app-customer-details', template: `<div *ngIf="customerData">Customer Info: {{ customerData }}</div>` }) export class CustomerDetailsComponent implements OnInit { customerData: string; constructor(private customerService: WcfCustomerService) { } ngOnInit(): void { this.customerService.getCustomerDetails(123).subscribe(data => { this.customerData = data; }); } }
Here are the most frequent roadblocks you might hit, and how to fix them:
CORS Errors: If your Angular app is hosted on a different domain than your WCF service, you'll get CORS blocked errors. Add a custom message inspector to your WCF service to inject CORS headers:
public class CorsMessageInspector : IDispatchMessageInspector { public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) { return null; } public void BeforeSendReply(ref Message reply, object correlationState) { var httpResponse = reply.Properties["httpResponse"] as HttpResponseMessageProperty; if (httpResponse != null) { httpResponse.Headers.Add("Access-Control-Allow-Origin", "*"); httpResponse.Headers.Add("Access-Control-Allow-Methods", "GET, POST, OPTIONS"); httpResponse.Headers.Add("Access-Control-Allow-Headers", "Content-Type"); } } }Then register this inspector in your WCF behavior configuration.
JSON Parsing Failures: Double-check that your WCF endpoint is set to return JSON (we did this in the
webHttpBehaviorconfig). If you're getting XML instead, Angular will throw parsing errors.UriTemplate Mismatches: Make sure the
UriTemplatein your WCF contract matches exactly the path you're using in Angular. For example, if your template isGetCustomerDetails/{customerId}, your Angular request should be.../GetCustomerDetails/123, not.../GetCustomerDetails?customerId=123.
内容的提问来源于stack exchange,提问作者Anil Prajapati

