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.