Отображение пользовательского сообщения об ошибке в веб-службе для клиента InfoPath

У меня есть пользовательский веб-сервис, который отправляет запись в базу данных,

Значение JF_ID, которое отправляется в таблицу, ссылается на значение JF_ID основной/исходной таблицы. Поэтому, если пользователь пытается отправить несуществующий JF_ID, исключение sql перехватывается, говоря: «нарушение ссылочной целостности и т. д.».

Вот как выглядит мой веб-сервис:

[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();
            }
        }


    }

}

Пользователь может ввести несколько данных об ошибках. Например, пользователь вводит строку вместо целочисленного значения. Если он попытается отправить запись для несуществующего JF_ID, это нарушит ссылочную целостность.

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'.

Как мне убедиться, что при обнаружении такого типа исключения SQL из моей веб-службы передается удобное пользовательское сообщение об ошибке (например, введенный идентификатор не существует. Ошибка вставки данных!) В конце концов, я хотел бы передать это понятное сообщение об ошибке клиенту InfoPath.

Большое спасибо.


person Nemo    schedule 06.11.2012    source источник


Ответы (1)


То, что вы хотите сделать, называется «Поднятие исключения мыла». Подробнее об этом можно прочитать здесь. Используйте следующий код:

    /// <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;
    }

и вызовите его в своем улове следующим образом:

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

В InfoPath вы просто добавляете ссылку на веб-службу (получать, а НЕ отправлять) и привязываете сообщение к нужному полю.

Вы также можете расширить код RaiseException, чтобы он отправлял ex.Message И удобное для пользователя сообщение обратно клиенту (InfoPath). Возможно, вы захотите создать «представление администратора», которое позволит вам увидеть фактическое исключение.

person int32    schedule 23.11.2012