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

标签 c#

我有以下 Controller :

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

        }

    }

但我有以下 2 个看似简单的错误:

Severity Code Description Project File Line Suppression State Error CS1520 Method must have a return type InnovationInABoxWebApi H:\InnovationInABoxWebApi\InnovationInABoxWebApi\Controllers\SetupController.cs 24 Active

Severity Code Description Project File Line Suppression State Error CS4033 The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'. InnovationInABoxWebApi H:\InnovationInABoxWebApi\InnovationInABoxWebApi\Controllers\SetupController.cs 39 Active

但是我不确定如何解决这个问题,因为操作可能需要一些时间才能完成,它确实需要 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;
        }

    }
}

最佳答案

您在返回类型 Task 之后用 async 词定义方法,async 必须在 Task 之前.

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

关于c# - 'await' 运算符只能在 async > 方法中使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51103323/

相关文章:

c# - TryGetValue 给出不正确的结果

c# - 我想使用 C# 将控制台中的文本水平和垂直居中

c# - Net Core app.UseMiddleware<T>() 和 app.Use(context, next) 之间的区别

c# - MVC 模型评估为无效,因为缺少一些已发布的数据

c# - 创建用户和地址 (1-Many) 以及订单和地址 (1-1) 之间的关系

javascript - MVC - 我的表单没有传递我的选择下拉列表的选定选项

c# - NHibernate SchemaExport.Execute 不创建表

c# - 必须声明标量变量 "@dom"

c# - 是否存在字段优于自动属性的情况

c# - 如何在属性更改时触发 DataTemplateSelector?