REST API:创建部署抛出错误BadRequest

时间:2012-07-24 08:44:42

标签: rest azure

我们正在尝试访问下面所述的Create Deployment方法 http://msdn.microsoft.com/en-us/library/windowsazure/ee460813 我们已在Blob中上传了Package并浏览了配置文件。我们已经检查过尝试手动上传Azure门户中的包和配置文件,并且工作正常。 下面是我们为创建部署编写的代码,其中“AzureEcoystemCloudService”是我们要部署包的云服务名称。

    byte[] bytes = new byte[fupldConfig.PostedFile.ContentLength + 1];
        fupldConfig.PostedFile.InputStream.Read(bytes, 0, bytes.Length);
        string a = Encoding.UTF8.GetString(bytes, 0, bytes.Length);
        string base64ConfigurationFile = a.ToBase64();
        X509Certificate2 certificate = CertificateUtility.GetStoreCertificate  
        (ConfigurationManager.AppSettings["thumbprint"].ToString());


        HostedService.CreateNewDeployment(certificate, ConfigurationManager.AppSettings   
        ["SubscriptionId"].ToString(), "2012-03-01", "AzureEcoystemCloudService", 
        Infosys.AzureEcosystem.Entities.Enums.DeploymentSlot.staging,
        "AzureEcoystemDeployment", "http://shubhendustorage.blob.core.windows.net/shubhendu
        storage/Infosys.AzureEcoystem.Web.cspkg", "AzureEcoystemDeployment", 
        base64ConfigurationFile, true, false);   



    /// <summary>
    /// 
    /// </summary>
    /// <param name="certificate"></param>
    /// <param name="subscriptionId"></param>
    /// <param name="version"></param>
    /// <param name="serviceName"></param>
    /// <param name="deploymentSlot"></param>
    /// <param name="name"></param>
    /// <param name="packageUrl"></param>
    /// <param name="label"></param>
    /// <param name="base64Configuration"></param>
    /// <param name="startDeployment"></param>
    /// <param name="treatWarningsAsError"></param>
    public static void CreateNewDeployment(X509Certificate2 certificate, string 
    subscriptionId,string version, string serviceName, 
   Infosys.AzureEcosystem.Entities.Enums.DeploymentSlot deploymentSlot, string name, 
   string packageUrl, string label, string base64Configuration,
        bool startDeployment, bool treatWarningsAsError)
    {
        Uri uri = new Uri(String.Format(Constants.CreateDeploymentUrlTemplate, 
        subscriptionId, serviceName, deploymentSlot.ToString()));
        XNamespace wa = Constants.xmlNamespace;
        XDocument requestBody = new XDocument();

        String base64ConfigurationFile = base64Configuration; 
        String base64Label = label.ToBase64();
        XElement xName = new XElement(wa + "Name", name); 
        XElement xPackageUrl = new XElement(wa + "PackageUrl", packageUrl);
        XElement xLabel = new XElement(wa + "Label", base64Label);
        XElement xConfiguration = new XElement(wa + "Configuration", 
        base64ConfigurationFile);
        XElement xStartDeployment = new XElement(wa + "StartDeployment", 
        startDeployment.ToString().ToLower());
        XElement xTreatWarningsAsError = new XElement(wa + "TreatWarningsAsError", 
        treatWarningsAsError.ToString().ToLower()); 
        XElement createDeployment = new XElement(wa + "CreateDeployment"); 

        createDeployment.Add(xName); 
        createDeployment.Add(xPackageUrl);
        createDeployment.Add(xLabel); 
        createDeployment.Add(xConfiguration); 
        createDeployment.Add(xStartDeployment); 
        createDeployment.Add(xTreatWarningsAsError);
        requestBody.Add(createDeployment);
        requestBody.Declaration = new XDeclaration("1.0", "UTF-8", "no"); 
        XDocument responseBody;
        RestApiUtility.InvokeRequest(
            uri, Infosys.AzureEcosystem.Entities.Enums.RequestMethod.POST.ToString(), 
        HttpStatusCode.Accepted, requestBody, certificate, version, out responseBody);
    }
    /// <summary>
    /// A helper function to invoke a Service Management REST API operation.
    /// Throws an ApplicationException on unexpected status code results.
    /// </summary>
    /// <param name="uri">The URI of the operation to invoke using a web request.</param>
    /// <param name="method">The method of the web request, GET, PUT, POST, or 
    DELETE.</param>
    /// <param name="expectedCode">The expected status code.</param>
    /// <param name="requestBody">The XML body to send with the web request. Use null to   
    send no request body.</param>
    /// <param name="responseBody">The XML body returned by the request, if any.</param>
    /// <returns>The requestId returned by the operation.</returns>
    public static string InvokeRequest(
        Uri uri,
        string method,
        HttpStatusCode expectedCode,
        XDocument requestBody,
        X509Certificate2 certificate,
        string version,
        out XDocument responseBody)
    {
        responseBody = null;
        string requestId = String.Empty;
        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
        request.Method = method;
        request.Headers.Add("x-ms-Version", version);
        request.ClientCertificates.Add(certificate);
        request.ContentType = "application/xml";
        if (requestBody != null)
        {
            using (Stream requestStream = request.GetRequestStream())
            {
                using (StreamWriter streamWriter = new StreamWriter(
                    requestStream, System.Text.UTF8Encoding.UTF8))
                {
                    requestBody.Save(streamWriter, SaveOptions.DisableFormatting);
                }
            }
        }
        HttpWebResponse response;
        HttpStatusCode statusCode = HttpStatusCode.Unused;
        try
        {
            response = (HttpWebResponse)request.GetResponse();
        }
        catch (WebException ex)
        {
            // GetResponse throws a WebException for 4XX and 5XX status codes
            response = (HttpWebResponse)ex.Response;
        }
        try
        {
            statusCode = response.StatusCode;
            if (response.ContentLength > 0)
            {
                using (XmlReader reader = XmlReader.Create(response.GetResponseStream()))
                {
                    responseBody = XDocument.Load(reader);
                }
            }
            if (response.Headers != null)
            {
                requestId = response.Headers["x-ms-request-id"];
            }
        }
        finally
        {
            response.Close();
        }
        if (!statusCode.Equals(expectedCode))
        {
            throw new ApplicationException(string.Format(
                "Call to {0} returned an error:{1}Status Code: {2} ({3}):{1}{4}",
                uri.ToString(),
                Environment.NewLine,
                (int)statusCode,
                statusCode,
                responseBody.ToString(SaveOptions.OmitDuplicateNamespaces)));
        }
        return requestId;
    }




  But every time we are getting the below error from the line

  response = (HttpWebResponse)request.GetResponse();

    <Error xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
      <Code>BadRequest</Code>
      <Message>The specified configuration settings for Settings are invalid. Verify that the service configuration file is a valid XML file, and that role instance counts are specified as positive integers.</Message>

</Error>

谢谢, Shubhendu

2 个答案:

答案 0 :(得分:4)

我对azure rest API的请求有问题。我发现WebException的读取响应是非常宝贵的。

try
{
    //Call Azure REST API
}
catch(WebException ex)
{
    var err = new StreamReader(ex.Response.GetResponseStream()).ReadToEnd();

    Console.WriteLine(err);

    throw;
}

这应该为您提供有关请求的潜在问题的充分信息。

答案 1 :(得分:0)

从Azure SDK 2.2开始,它最终导致文档错误,您不需要对配置字符串进行base64编码。因此,不要将所有byte []转换为base64,只需传入UFT8字符串。