'await'运算符只能在async>方法中使用

时间:2018-06-29 13:51:11

标签: c#

我有以下控制器:

[Authorize]
    public class SetupController : ApiController
    {
        [HttpPost]
        public Task async SetupPartnerPackAsync(SetupInformation info)
        {
            if (info.SslCertificateGenerate)
            {
                SetupManager.CreateX509Certificate(info);
            }
            else
            {
                SetupManager.LoadX509Certificate(info);
            }

            info.SslCertificateThumbprint = SetupManager.GetX509CertificateThumbprint(info);
            info.AzureAppKeyCredential = SetupManager.GetX509CertificateInformation(info);


            await SetupManager.RegisterAzureADApplication(info);

        }

    }

但是我有以下两个似乎很简单的错误:

  

严重性代码描述项目文件行抑制状态   错误CS1520方法必须返回   键入InnovationInABoxWebApi H:\ InnovationInABoxWebApi \ InnovationInABoxWebApi \ Controllers \ SetupController.cs 24有效

     

严重性代码描述项目文件行抑制状态   错误CS4033'await'运算符只能在异步中使用   方法。考虑使用“异步”修饰符标记此方法,然后   将其返回类型更改为   '任务'。 InnovationInABoxWebApi H:\ InnovationInABoxWebApi \ InnovationInABoxWebApi \ Controllers \ SetupController.cs 39有效

但是我不确定如何解决此问题,因为该操作可能需要一些时间才能完成,所以确实需要asybnc

和设置管理器

using CERTENROLLLib;
using Microsoft.Identity.Client;
using Microsoft.Online.SharePoint.TenantAdministration;
using Microsoft.SharePoint.Client;
using Newtonsoft.Json;
using OfficeDevPnP.Core;
using OfficeDevPnP.Core.Entities;
using OfficeDevPnP.Core.Framework.Provisioning.Model;
using OfficeDevPnP.Core.Framework.Provisioning.ObjectHandlers;
using OfficeDevPnP.Core.Framework.Provisioning.Providers.Xml;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Resources;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Xml.Linq;

namespace InnovationInABoxWebApi.Components
{
    public static class SetupManager
    {


        public static String GetX509CertificateThumbprint(SetupInformation info)
        {
            var certificate = info.AuthenticationCertificate;
            return (certificate.Thumbprint.ToUpper());
        }

        public static String GetX509CertificateInformation(SetupInformation info)
        {
            // var basePath = String.Format(@"{0}..\..\..\..\Scripts\", AppDomain.CurrentDomain.BaseDirectory);

            var certificate = info.AuthenticationCertificate;
            //var certificate = new X509Certificate2();
            //if (info.SslCertificateGenerate)
            //{
            //    certificate.Import($@"{basePath}{info.SslCertificateCommonName}.cer");
            //}
            //else
            //{
            //    certificate = new X509Certificate2(info.SslCertificateFile, info.SslCertificatePassword);
            //}

            var rawCert = certificate.GetRawCertData();
            var base64Cert = System.Convert.ToBase64String(rawCert);
            var rawCertHash = certificate.GetCertHash();
            var base64CertHash = System.Convert.ToBase64String(rawCertHash);
            var KeyId = System.Guid.NewGuid().ToString();

            var keyCredential =
                "{" +
                    "\"customKeyIdentifier\": \"" + base64CertHash + "\"," +
                    "\"keyId\": \"" + KeyId + "\"," +
                    "\"type\": \"AsymmetricX509Cert\"," +
                    "\"usage\": \"Verify\"," +
                    "\"key\":  \"" + base64Cert + "\"" +
                "}";

            return (keyCredential);
        }

        public static void CreateX509Certificate(SetupInformation info)
        {
            var certificate = CreateSelfSignedCertificate(info.SslCertificateCommonName.ToLower(),
                info.SslCertificateStartDate, info.SslCertificateEndDate, info.SslCertificatePassword);

            SaveCertificateFiles(info, certificate);
        }

        public static void LoadX509Certificate(SetupInformation info)
        {
            var certificate = new X509Certificate2(info.SslCertificateFile, info.SslCertificatePassword);
            info.AuthenticationCertificate = certificate;
            info.SslCertificateCommonName = certificate.SubjectName.Name;
        }

        public static void SaveCertificateFiles(SetupInformation info, X509Certificate2 certificate)
        {
            info.AuthenticationCertificate = certificate;
            //var basePath = String.Format(@"{0}..\..\..\..\Scripts\", AppDomain.CurrentDomain.BaseDirectory);

            //info.SslCertificateFile = $@"{basePath}{info.SslCertificateCommonName}.pfx";
            //var pfx = certificate.Export(X509ContentType.Pfx, info.SslCertificatePassword);
            //System.IO.File.WriteAllBytes(info.SslCertificateFile, pfx);

            //var cer = certificate.Export(X509ContentType.Cert);
            //System.IO.File.WriteAllBytes($@"{basePath}{info.SslCertificateCommonName}.cer", cer);
        }

        public static X509Certificate2 CreateSelfSignedCertificate(string subjectName, DateTime startDate, DateTime endDate, String password)
        {
            // Create DistinguishedName for subject and issuer
            var name = new CX500DistinguishedName();
            name.Encode("CN=" + subjectName, X500NameFlags.XCN_CERT_NAME_STR_NONE);

            // Create a new Private Key for the certificate
            CX509PrivateKey privateKey = new CX509PrivateKey();
            privateKey.ProviderName = "Microsoft RSA SChannel Cryptographic Provider";
            privateKey.KeySpec = X509KeySpec.XCN_AT_KEYEXCHANGE;
            privateKey.Length = 2048;
            privateKey.SecurityDescriptor = "D:PAI(A;;0xd01f01ff;;;SY)(A;;0xd01f01ff;;;BA)(A;;0x80120089;;;NS)";
            privateKey.MachineContext = true;
            privateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG;
            privateKey.Create();

            // Define the hashing algorithm
            var serverauthoid = new CObjectId();
            serverauthoid.InitializeFromValue("1.3.6.1.5.5.7.3.1"); // Server Authentication
            var ekuoids = new CObjectIds();
            ekuoids.Add(serverauthoid);
            var ekuext = new CX509ExtensionEnhancedKeyUsage();
            ekuext.InitializeEncode(ekuoids);

            // Create the self signing request
            var cert = new CX509CertificateRequestCertificate();
            cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextMachine, privateKey, String.Empty);
            cert.Subject = name;
            cert.Issuer = cert.Subject;
            cert.NotBefore = startDate;
            cert.NotAfter = endDate;
            cert.X509Extensions.Add((CX509Extension)ekuext);
            cert.Encode();

            // Enroll the certificate
            var enroll = new CX509Enrollment();
            enroll.InitializeFromRequest(cert);
            string certData = enroll.CreateRequest(EncodingType.XCN_CRYPT_STRING_BASE64HEADER);
            enroll.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate,
                certData, EncodingType.XCN_CRYPT_STRING_BASE64HEADER, String.Empty);

            var base64encoded = enroll.CreatePFX(password, PFXExportOptions.PFXExportChainWithRoot);

            // Instantiate the target class with the PKCS#12 data
            return new X509Certificate2(
                System.Convert.FromBase64String(base64encoded), password,
                System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.Exportable);
        }

        public async static Task RegisterAzureADApplication(SetupInformation info)
        {
            // Fix the App URL
            if (!info.AzureWebAppUrl.EndsWith("/"))
            {
                info.AzureWebAppUrl = info.AzureWebAppUrl + "/";
            }

            // Load the App Manifest template
            //Stream stream = typeof(SetupManager)
            //    .Assembly
            //    .GetManifestResourceStream("OfficeDevPnP.PartnerPack.Setup.Resources.azure-ad-app-manifest.json");

            using (StreamReader sr = new StreamReader("Resources\azure-ad-app-manifest.json"))
            {
                // Get the JSON manifest
                var jsonApplication = sr.ReadToEnd();

                var application = JsonConvert.DeserializeObject<AzureAdApplication>(jsonApplication);
                var keyCredential = JsonConvert.DeserializeObject<KeyCredential>(info.AzureAppKeyCredential);

                application.displayName = info.ApplicationName;
                application.homepage = info.AzureWebAppUrl;
                application.identifierUris = new List<String>();
                application.identifierUris.Add(info.ApplicationUniqueUri);
                application.keyCredentials = new List<KeyCredential>();
                application.keyCredentials.Add(keyCredential);
                application.replyUrls = new List<String>();
                application.replyUrls.Add(info.AzureWebAppUrl);

                // Generate the Application Shared Secret
                var startDate = DateTime.Now;
                Byte[] bytes = new Byte[32];
                using (var rand = System.Security.Cryptography.RandomNumberGenerator.Create())
                {
                    rand.GetBytes(bytes);
                }
                info.AzureAppSharedSecret = System.Convert.ToBase64String(bytes);
                application.passwordCredentials = new List<object>();
                application.passwordCredentials.Add(new AzureAdApplicationPasswordCredential
                {
                    CustomKeyIdentifier = null,
                    StartDate = startDate.ToString("o"),
                    EndDate = startDate.AddYears(2).ToString("o"),
                    KeyId = Guid.NewGuid().ToString(),
                    Value = info.AzureAppSharedSecret,
                });

                // Get an Access Token to create the application via Microsoft Graph
                var office365AzureADAccessToken = await AzureManagementUtility.GetAccessTokenSilentAsync(
                    AzureManagementUtility.MicrosoftGraphResourceId,
                    ConfigurationManager.AppSettings["O365:ClientId"]);

                var azureAdApplicationCreated = false;

                // Create the Azure AD Application
                try
                {
                    await CreateAzureADApplication(info, application, office365AzureADAccessToken);
                    azureAdApplicationCreated = true;
                }
                catch (ApplicationException ex)
                {
                    var graphError = JsonConvert.DeserializeObject<GraphError>(((HttpException)ex.InnerException).Message);
                    if (graphError != null && graphError.error.code == "Request_BadRequest" &&
                        graphError.error.message.Contains("identifierUris already exists"))
                    {
                        // We need to remove the existing application

                        // Thus, retrieve it
                        String jsonApplications = await HttpHelper.MakeGetRequestForStringAsync(
                            String.Format("{0}applications?$filter=identifierUris/any(c:c+eq+'{1}')",
                                AzureManagementUtility.MicrosoftGraphBetaBaseUri,
                                HttpUtility.UrlEncode(info.ApplicationUniqueUri)),
                            office365AzureADAccessToken);

                        var applications = JsonConvert.DeserializeObject<AzureAdApplications>(jsonApplications);
                        var applicationToUpdate = applications.Applications.FirstOrDefault();
                        if (applicationToUpdate != null)
                        {
                            // Remove it
                            await HttpHelper.MakeDeleteRequestAsync(
                                String.Format("{0}applications/{1}",
                                    AzureManagementUtility.MicrosoftGraphBetaBaseUri,
                                    applicationToUpdate.Id),
                                office365AzureADAccessToken);

                            // And add it again
                            await CreateAzureADApplication(info, application, office365AzureADAccessToken);

                            azureAdApplicationCreated = true;
                        }
                    }
                }

                if (azureAdApplicationCreated)
                {
                    // TODO: We should upload the logo
                    // property mainLogo: stream of the application via PATCH
                }
            }
        }

        public static async Task CreateAzureADApplication(SetupInformation info, AzureAdApplication application, string office365AzureADAccessToken)
        {
            String jsonResponse = await HttpHelper.MakePostRequestForStringAsync(
                String.Format("{0}applications",
                    AzureManagementUtility.MicrosoftGraphBetaBaseUri),
                application,
                "application/json", office365AzureADAccessToken);

            var azureAdApplication = JsonConvert.DeserializeObject<AzureAdApplication>(jsonResponse);
            info.AzureAppClientId = azureAdApplication.AppId.HasValue ? azureAdApplication.AppId.Value : Guid.Empty;
        }

    }
}

1 个答案:

答案 0 :(得分:6)

您要在返回类型async之后用Task字定义方法,async必须在Task之前。

public async Task SetupPartnerPackAsync(SetupInformation info)
{
.
.
.