wcfwcfserviceclient

WCF Service with ASP.Net


I am new to WCF.

I wrote the following service below, which runs fine. I then configured IIS, and ran the service via the browser http://localhost/WCF_Entity_SVC/ProductService.svc, which runs fine. I created a ASP.Net webpage and added a service refrence using the url. When I run the ASP page, I recieve an internal error. Any help is appreciated.

public class ProductService : IProductService
    {
        public Product GetProduct(int id)
        {
            NorthwindEntities context = new NorthwindEntities();
            var productEntity = (from p
                                 in context.ProductEntities
                                 where p.ProductID == id
                                 select p).FirstOrDefault();
            if (productEntity != null)
                return TranslateProductEntityToProduct(productEntity);
            else
                throw new Exception("Invalid product id");
        }
        private Product TranslateProductEntityToProduct(
              ProductEntity productEntity)
        {
            Product product = new Product();
            product.ProductID = productEntity.ProductID;
            product.ProductName = productEntity.ProductName;
            product.QuantityPerUnit = productEntity.QuantityPerUnit;
            product.UnitPrice = (decimal)productEntity.UnitPrice;
            product.Discontinued = productEntity.Discontinued;
            return product;
        }
    }

ASP code

 public partial class _Default : System.Web.UI.Page
    {
        myService.ProductServiceClient objService = new ProductServiceClient();

        protected void Page_Load(object sender, EventArgs e)
        {
           var results = objService.GetProduct(45);   //debug shows internal error
           dgResult.DataSource = results;
           dgResult.DataBind();

        }
    }

Adding Debuging to the webconfig shows the below error:

The underlying provider failed on Open. 

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

        Exception Details: System.ServiceModel.FaultException`1[[System.ServiceModel.ExceptionDetail, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]: The underlying provider failed on Open.

        Source Error: 


        Line 159:        
        Line 160:        public ASPWFC.myService.Product GetProduct(int id) {
        Line 161:            return base.Channel.GetProduct(id);
        Line 162:        }
        Line 163:    }

    Source File: D:\My Documents\Visual Studio 2010\Projects\wcf\WCF_Entity\ASPWFC\Service References\myService\Reference.cs    Line: 161 

    Stack Trace: 


    [FaultException`1: The underlying provider failed on Open.]
       System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +9464367
       System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) +345
       ASPWFC.myService.IProductService.GetProduct(Int32 id) +0
       ASPWFC.myService.ProductServiceClient.GetProduct(Int32 id) in D:\My Documents\Visual Studio 2010\Projects\wcf\WCF_Entity\ASPWFC\Service References\myService\Reference.cs:161
       ASPWFC._Default.Page_Load(Object sender, EventArgs e) in D:\My Documents\Visual Studio 2010\Projects\wcf\WCF_Entity\ASPWFC\Default.aspx.cs:23
       System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +37
       System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +95
       System.Web.UI.Control.OnLoad(EventArgs e) +145
       System.Web.UI.Control.LoadRecursive() +134
       System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3412

For debugging purposes, I add a funcction called Getparams(int id) to the service all the function does is return the id. I called the Getparams functions in ASp page, and got back the argument passsed. I think that means that the param in the GetProduct function is being passed to the service and somewhere in the link to entity query, is the error.

What I don't understand is why when I run the service directly, there is no error. The database gives me a result

I did some more debuging, and I found the reason for the open error is:

sqlError: Login failed for IIS AppPool\ASP.Net4

how do I go about fixing this, my sqlserver runs via windows authentication.

I found a script in msdn that fixes the security issue, and the code is know working

CREATE LOGIN [IIS APPPOOL\ASP.NET v4.0] 
  FROM WINDOWS WITH DEFAULT_DATABASE=[Northwind], 
  DEFAULT_LANGUAGE=[us_english]
GO
CREATE USER [NWUser] 
  FOR LOGIN [IIS APPPOOL\ASP.NET v4.0]
GO
EXEC sp_addrolemember 'db_datareader', 'NWUser'
GO

Solution

  • When debugging WCF services it really helps to enable tracing. This lets you diagnose vague messages ("500 Internal Server Error" doesn't really give much away) without too much kerfuffle.

    Go here: http://msdn.microsoft.com/en-us/library/ms732023.aspx to see the detail. In brief, add

    <system.diagnostics>
        <trace autoflush="true" />
        <sources>
                <source name="System.ServiceModel" 
                        switchValue="Information, ActivityTracing"
                        propagateActivity="true">
                <listeners>
                   <add name="sdt" 
                       type="System.Diagnostics.XmlWriterTraceListener" 
                       initializeData= "c:\temp\wcfserver.log" />
                </listeners>
             </source>
        </sources>
    </system.diagnostics>
    

    to your client, your server, or both; adjust the log filename in initializeData as appropriate.

    Run your program, and you should see a log file or two. Open them with the Service Trace Viewer (part of the Windows SDK, installed with later versions of Windows) and you should see the exception highlighted in red.

    The exceptions raised by WCF, in particular the inner exceptions, are usually very explicit, so this is definitely worth the effort.

    (This also works for System.Runtime.Serialization which has saved my bacon a couple of times recently.)