简体   繁体   中英

Display custom error message in web service for InfoPath client

I have a custom web service that submits the record to the database,

The JF_ID value that gets submitted to the table references to the JF_ID value of the main/source table. So if a user tries to submit for non-existant JF_ID, sql exception is caught saying 'referential integrity violation etc...

Here's what my web service looks like:

[WebService(Namespace = "http://microsoft.com/webservices/")]
class POReqEntryForm : WebService 
{
    [WebMethod(Description = "Submits data to [Req_entry].")]
    public void AddRecordPOReqIdEntry(int JF_ID, int ReqId, string PONum, string POLineNum, float POAmount, string Submitter, string DateSubmitted)
    {

        string connectionString =
          ConfigurationManager.ConnectionStrings["REQdb"].ConnectionString;

        using (SqlConnection conn = new SqlConnection(connectionString))
        {
            SqlCommand cmd = new SqlCommand();
            cmd.CommandType = System.Data.CommandType.Text;


            cmd.CommandText = "INSERT INTO [REQdb].[dbo].[Req_entry] "
                + "(JF_ID, Req_id, Po_num, Po_line_num, po_amount, Submitter, Date_Submitted ) "
                + "VALUES (@JF_ID, @ReqId, @PONum, @POLineNum, @POAmount, @Submitter, @DateSubmitted)";

            cmd.Parameters.AddWithValue("JF_ID", JF_ID);
            cmd.Parameters.AddWithValue("ReqId", ReqId);
            cmd.Parameters.AddWithValue("PONum", PONum);
            cmd.Parameters.AddWithValue("POLineNum", POLineNum);
            cmd.Parameters.AddWithValue("POAmount", POAmount);
            cmd.Parameters.AddWithValue("Submitter", Submitter);
            cmd.Parameters.AddWithValue("DateSubmitted", DateSubmitted);

            cmd.Connection = conn;

            try
            {
                conn.Open();
                cmd.ExecuteNonQuery();

            }

            catch
            {
                // Handle the error using your own preferred error-handling method
            }
            finally
            {
                conn.Close();
            }
        }


    }

}

There could be a number of fault data entries by a user. For eg, user inputs string instead of integer value, If he tries to submit the entry for the non-existing JF_ID, it violates referential integrity.

The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Req_Entry_JF_ID". The conflict occurred in database "REQdb", table "dbo.Main_Form", column 'JF_ID'.

How do I make sure that such type of SQL exception when caught, a user friendly custom error message(Such as the entered ID doesn't exist.Data insertion failed!) is passed from my web service. In the end, I would like to pass this friendly error message to InfoPath client.

Thanks a lot.

What you want to do is called "Raising a Soap Exception". You can read more about it here . Use the following code:

    /// <summary>
    /// Creates a custom SoapException to submit the client detailed information about the thrown errors
    /// </summary>
    /// <param name="uri">the name of the called method</param>
    /// <param name="webServiceNamespace">iShare_Services</param>
    /// <param name="errorMessage">the thrown error message</param>
    /// <param name="errorSource">the method which caused the error</param>
    /// <param name="code">Server or Client error?</param>
    /// throw RaiseException("MyMethod", "Service", ee.Message,
    /// ee.TargetSite.Name, FaultCode.Client);
    /// <returns></returns>
    public SoapException RaiseException(string uri, string webServiceNamespace,
        string errorMessage, string errorSource, FaultCode code)
    {
        XmlQualifiedName faultCodeLocation = null;
        //Identify the location of the FaultCode
        switch (code)
        {
            case FaultCode.Client:
                faultCodeLocation = SoapException.ClientFaultCode;
                break;
            case FaultCode.Server:
                faultCodeLocation = SoapException.ServerFaultCode;
                break;
        }

        XmlDocument xmlDoc = new XmlDocument();
        //Create the Detail node
        XmlNode rootNode = xmlDoc.CreateNode(XmlNodeType.Element, SoapException.DetailElementName.Name, SoapException.DetailElementName.Namespace);
        //Build specific details for the SoapException

        //Add first child of detail XML element.
        XmlNode errorNode = xmlDoc.CreateNode(XmlNodeType.Element, "Error", webServiceNamespace);

        //Create and set the value for the ErrorMessage node
        XmlNode errorMessageNode = xmlDoc.CreateNode(XmlNodeType.Element, "ErrorMessage", webServiceNamespace);

        errorMessageNode.InnerText = errorMessage;

        //Create and set the value for the ErrorSource node
        XmlNode errorSourceNode = xmlDoc.CreateNode(XmlNodeType.Element, "ErrorSource", webServiceNamespace);

        errorSourceNode.InnerText = errorSource;

        //Append the Error child element nodes to the root detail node.
        errorNode.AppendChild(errorMessageNode);
        errorNode.AppendChild(errorSourceNode);

        //Append the Detail node to the root node
        rootNode.AppendChild(errorNode);

        //Construct the exception
        SoapException soapEx = new SoapException(errorMessage, faultCodeLocation, uri, rootNode);

        //Raise the exception  back to the caller
        return soapEx;
    }

and call it in your catch as followed:

        catch (Exception e)
        {
            var userFriendlyMessage = "this is a user friendly exception!";
            throw RaiseException("MyMethod", this.GetType().Namespace, userFriendlyMessage, e.Source, FaultCode.Client);
        }

In InfoPath, you simply add the WebService Reference (Retrieve and NOT Submit) and bind the Message to a Field you want.

You could also extend the RaiseException code, that it sends the ex.Message AND the user friendly message back to the client (InfoPath). You might want to create an "Admin View" that allows you the see the actual Exception.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM