Domanda

Ambiente: C #, .Net 3.5, SQL Server 2005

Ho un metodo che funziona in un progetto stand-alone C # applicazione console. Si crea un XmlElement dai dati nel database e utilizza un metodo privato per inviarlo a un servizio Web sulla nostra rete locale. Quando viene eseguito da VS in questo progetto di test, viene eseguito in <5 secondi.

Ho copiato la classe in un progetto CLR, costruito e installato in SQL Server (CON PERMISSION_SET = EXTERNAL_ACCESS). L'unica differenza è lo SqlContext.Pipe.Send () chiama che ho aggiunto per il debug.

Sono test che utilizzando un comando EXECUTE una stored procedure (nel CLR) dalla finestra di uno SSMS query. E non ritorna mai. Quando mi fermo l'esecuzione della chiamata dopo un minuto, l'ultima cosa che appare è "Calling GetResponse () utilizzando http: //servername:53694/odata.svc/Customers/ ". Tutte le idee sul perché il () chiamata GetResponse non restituisce quando si esegue in SQL Server?

private static string SendPost(XElement entry, SqlString url, SqlString entityName)
{
    // Send the HTTP request
    string serviceURL = url.ToString() + entityName.ToString() + "/";
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(serviceURL);
    request.Method = "POST";
    request.Accept = "application/atom+xml,application/xml";
    request.ContentType = "application/atom+xml";
    request.Timeout = 20000;
    request.Proxy = null;

    using (var writer = XmlWriter.Create(request.GetRequestStream()))
    {
        entry.WriteTo(writer);
    }

    try
    {
        SqlContext.Pipe.Send("Calling GetResponse() using " + request.RequestUri);
        WebResponse response = request.GetResponse();
        SqlContext.Pipe.Send("Back from GetResponse()");

        /*
        string feedData = string.Empty;

        Stream stream = response.GetResponseStream();
        using (StreamReader streamReader = new StreamReader(stream))
        {
            feedData = streamReader.ReadToEnd();
        }
        */

        HttpStatusCode StatusCode = ((HttpWebResponse)response).StatusCode;
        response.Close();

        if (StatusCode == HttpStatusCode.Created /* 201 */ )
        {
            return "Created @ Location= " + response.Headers["Location"];
        }

        return "Creation failed; StatusCode=" + StatusCode.ToString();
    }
    catch (WebException ex)
    {
        return ex.Message.ToString();
    }
    finally
    {
        if (request != null)
            request.Abort();

    }
}
È stato utile?

Soluzione

Il problema si è rivelato essere la creazione del contenuto richiesta del XML. L'originale:

using (var writer = XmlWriter.Create(request.GetRequestStream()))
{
    entry.WriteTo(writer);
}

La sostituzione di lavoro:

    using (Stream requestStream = request.GetRequestStream())
    {
        using (var writer = XmlWriter.Create(requestStream))
        {
            entry.WriteTo(writer);
        }
    }

Altri suggerimenti

È necessario smaltire il WebResponse. In caso contrario, dopo un paio di telefonate va a timeout.

Si cerca di guai fare questo in CLR. E tu dici che si sta chiamando questo da un grilletto? Appartiene nello strato applicativo.

Roba come questo è il motivo per cui quando la funzionalità CLR è uscito, gli amministratori di database sono stati molto preoccupati per come sarebbe essere oggetto di abuso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top