开发者

"Not Found" error when attempting to save to SQL Server via WCF in Silverlight 3

I'm attempting to save some data to a SQL Server 2008 database using Silverlight 3 on the .NET 3.5 framework.

Here's the skinny on what's going on here.

When the app starts up, it calls WCF to download a List object containing rows from the DB, so that all the available data is on the client side, preventing the need for repeated client-server database calls. It downloads the data just fine, and gives feedback of successful data download.

The user types information into textboxes. When the user is ready, they click "Save", which calls WCF to save this data, in an encrypted character string probably not more than 2 KB in size, along with some integer and short string fields.

When they click Save, it's throwing the following exception:

The remote server returned an error: NotFound.

I cannot figure out for the life of me what's going on. Data is not being saved.

Thing's I've tried:

  • Adding a to the binding in web.config (that actually caused the first WCF call to fail with the same error)
  • Adding a crossdomainpolicy.xml file with the content from this question
  • Increasing the size of "maxReceivedMessageSize" and "maxBufferSize"
  • Setting "includeExceptionDetailInFaults" to "True" (it didn't give any more useful data)

I'm at my wit's end and need this done in a couple days. If the solution were a snake I'm sure it would bite...here's the contents of my files:

Web.config

<?xml version="1.0"?>
  <configuration>
    <appSettings/>
    <connectionStrings>
       <add name="AFF_DataConnectionString" 
           connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\AFF_Data.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True"/>
    </connectionStrings>
    <system.web>
        <compilation debug="true" targetFramework="4.0">
            <assemblies>
                <add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
            </assemblies>
        </compilation>
        <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/>
    </system.web>
    <system.serviceModel>
       <behaviors>
          <serviceBehaviors>
             <behavior name="DataWCFBehavior"&g开发者_运维百科t;
                <serviceMetadata httpGetEnabled="true"/>
                <serviceDebug includeExceptionDetailInFaults="true"/>
                <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
             </behavior>
          </serviceBehaviors>
       </behaviors>
       <services>
          <service behaviorConfiguration="DataWCFBehavior" name="DataWCF">
              <endpoint address="" binding="basicHttpBinding" contract="IDataWCF">
                  <identity>
                      <dns value="localhost:4493"/>
                  </identity>
              </endpoint>
              <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
          </service>
       </services>
</system.serviceModel>
</configuration>

DataWCF.cs (the function in question)

void IDataWCF.SaveFile(int theUserId, int theCustId, int theDairyCat, string theFilename, string theData, string theFeedId, string theFileType)
{
    using (var db = new DataClassesDataContext())
    {
        var theFile = new AFF_DairyFile
                      {
                          userID = theUserId,
                          custID = theCustId,
                          dairyCat = theDairyCat,
                          filename = theFilename,
                          data = theData,
                          feedID = Convert.ToInt32(theFeedId),
                          fileType = theFileType
                      };
        db.AFF_DairyFiles.InsertOnSubmit(theFile);
        db.SubmitChanges();
    }
}

IDataWCF.cs

[ServiceContract]
public interface IDataWCF {

[OperationContract]
string GetFeed(String feedID);

[OperationContract]
List<Attribute> getNutrients();

[OperationContract]
List<Attribute> getNutrients2(string nutrientID);

[OperationContract]
List<Feed> getFeeds();

[OperationContract]
void SaveFile(int userId, int custId, int dairyCat, string filename, string data, string feedId, string fileType);
}
[DataContract]
public class Attribute
{
[DataMember]
public decimal specCorrectVal = 0m;

[DataMember]
public decimal specVal = 0m;

[DataMember]
public string specID = "";

[DataMember]
public string feedID = "";

}
[DataContract]
public class Feed
{
[DataMember]
public string feedID;

[DataMember]
public string feedName;
}

ServiceReferences.ClientConfig

<configuration>
   <system.serviceModel>
      <bindings>
         <basicHttpBinding>
             <binding name="BasicHttpBinding_IDataWCF" maxBufferSize="2147483647"
                      maxReceivedMessageSize="2147483647">
                <security mode="None" />
             </binding>
         </basicHttpBinding>
      </bindings>
      <client>
          <endpoint address="http://localhost:4493/DairyCalcApp.Web/DataWCF.svc"
                    binding="basicHttpBinding" 
                    bindingConfiguration="BasicHttpBinding_IDataWCF"
                    contract="DataWCF.IDataWCF" name="BasicHttpBinding_IDataWCF" />
      </client>
   </system.serviceModel>
</configuration>

Code that calls WCF and fails

 private void SaveButton_Click(object sender, RoutedEventArgs e)
 {
        var theUserId = 0; // Real user ID here
        var theCustId = 0; // Real Customer ID here
        var theDairyCat = 1;
        var theFilename = FileNameTextBox.Text;
        var theData = AssembleData();
        var theFeedId = "";
        var theFileType = "Ration";
        var proxy = new DairyCalcApp.DataWCF.DataWCFClient();
        try
        {
            proxy.SaveFileCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(proxy_SaveFileCompleted);
            proxy.SaveFileAsync(theUserId,theCustId,theDairyCat,theFilename,theData,theFeedId,theFileType);
        }
        catch (Exception ex)
        {
            FileStatusLabel.Text = ex.InnerException.Message;
        }
    }

    void proxy_SaveFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
    {
        FileStatusLabel.Text = "File Saved!";
        LastEditDate.Text = DateTime.Now.ToShortTimeString();
    }


The short answer I can give you is to debug your wcf service.

Start the wcf service in debug mode and put a breakpoint on the method being called. Start your Silverlight client and call the save method (press the button, etc.) The WCF service breakpoint should be hit and your can find out what is going on on the back end.

The message:

The remote server returned an error: NotFound.

is the generic error that comes back from the WCF service. Silverlight error (fault) handling out of the box is not very good. But if you put a breakpoint on your WCF service you should be able to find out the exception that is occuring on the back end and fix the code.

After that, I would implement the proper Silverlight fault handling so that errors get sent from the WCF service to the SL client in some fashion and you don't get this generic message with any unhandled exception that occurs on the WCF service.

This code here could definately throw an exception if the database wasn't available, the data couldn't be inserted, constraint violations, etc.:

using (var db = new DataClassesDataContext())    
{        
var theFile = new AFF_DairyFile                      
{                          
userID = theUserId,                          
custID = theCustId,                          
dairyCat = theDairyCat,                          
filename = theFilename,                          
data = theData,                          
feedID = Convert.ToInt32(theFeedId),                          
fileType = theFileType                      
};        

db.AFF_DairyFiles.InsertOnSubmit(theFile);        
db.SubmitChanges();    

}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜