C# 有没有一种方法可以调用从quickbooks检索公司信息的API

C# 有没有一种方法可以调用从quickbooks检索公司信息的API,c#,C#,我是mvc新手,尝试从Quickbooks调用Api以获取公司信息沙箱,我遵循intuit.com中的说明:创建应用程序、生成客户端id、客户端机密并在web.config中使用它们。我还生成了OAuth2,在使用用户名和密码登录后,我能够在我的项目中看到“连接到Quickbooks”对话框,现在我正试图调用Api,所以首先我创建了OAuth2RequestValidator类的dobject,但出现了一个错误:“对象引用未设置为对象的实例”a我正在使用声明进行身份验证,我认为claimsPri

我是mvc新手,尝试从Quickbooks调用Api以获取公司信息沙箱,我遵循intuit.com中的说明:创建应用程序、生成客户端id、客户端机密并在web.config中使用它们。我还生成了OAuth2,在使用用户名和密码登录后,我能够在我的项目中看到“连接到Quickbooks”对话框,现在我正试图调用Api,所以首先我创建了OAuth2RequestValidator类的dobject,但出现了一个错误:“对象引用未设置为对象的实例”a我正在使用声明进行身份验证,我认为claimsPrincipal无法从ClaimsEntity读取声明,我被困在这里,我正在尝试使用intuit.com中的示例代码

这是获取身份验证和调用api的控制器

public class AppController : Controller
{
    public static string clientid = ConfigurationManager.AppSettings["clientid"];
    public static string clientsecret = ConfigurationManager.AppSettings["clientsecret"];
    public static string redirectUrl = ConfigurationManager.AppSettings["redirectUrl"];
    public static string environment = ConfigurationManager.AppSettings["appEnvironment"];

    public static OAuth2Client auth2Client = new OAuth2Client(clientid, clientsecret, redirectUrl, environment);

    /// <summary>
    /// Use the Index page of App controller to get all endpoints from discovery url
    /// </summary>
    public ActionResult Index()
    {
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
        Session.Clear();
        Session.Abandon();
        Request.GetOwinContext().Authentication.SignOut("Cookies");
        return View();
    }

    /// <summary>
    /// Start Auth flow
    /// </summary>
    public ActionResult InitiateAuth(string submitButton)
    {
        switch (submitButton)
        {
            case "Connect to QuickBooks":
                List<OidcScopes> scopes = new List<OidcScopes>();
                scopes.Add(OidcScopes.Accounting);
                string authorizeUrl = auth2Client.GetAuthorizationURL(scopes);
                return Redirect(authorizeUrl);
            default:
                return (View());
        }
    }

    /// <summary>
    /// QBO API Request
    /// </summary>
    public ActionResult ApiCallService()
    {
        if (Session["realmId"] != null)
        {
            string realmId = Session["realmId"].ToString();
            try
            {
                var principal = User as ClaimsPrincipal;
                OAuth2RequestValidator oauthValidator = new OAuth2RequestValidator(principal.FindFirst("access_token").Value);

                // Create a ServiceContext with Auth tokens and realmId
                ServiceContext serviceContext = new ServiceContext(realmId, IntuitServicesType.QBO, oauthValidator);
                serviceContext.IppConfiguration.MinorVersion.Qbo = "23";

                // Create a QuickBooks QueryService using ServiceContext
                QueryService<CompanyInfo> querySvc = new QueryService<CompanyInfo>(serviceContext);
                CompanyInfo companyInfo = querySvc.ExecuteIdsQuery("SELECT * FROM CompanyInfo").FirstOrDefault();

                string output = "Company Name: " + companyInfo.CompanyName + " Company Address: " + companyInfo.CompanyAddr.Line1 + ", " + companyInfo.CompanyAddr.City + ", " + companyInfo.CompanyAddr.Country + " " + companyInfo.CompanyAddr.PostalCode;
                return View("ApiCallService", (object)("QBO API call Successful!! Response: " + output));
            }
            catch (Exception ex)
            {
                return View("ApiCallService", (object)("QBO API call Failed!" + " Error message: " + ex.Message));
            }
        }
        else
            return View("ApiCallService", (object)"QBO API call Failed!");
    }

    /// <summary>
    /// Use the Index page of App controller to get all endpoints from discovery url
    /// </summary>
    public ActionResult Error()
    {
        return View("Error");
    }

    /// <summary>
    /// Action that takes redirection from Callback URL
    /// </summary>
    public ActionResult Tokens()
    {
        return View("Tokens");
    }
这个控制器创建了访问令牌和刷新令牌

public class CallbackController : Controller
{
    /// <summary>
    /// Code and realmid/company id recieved on Index page after redirect is complete from Authorization url
    /// </summary>
    public async Task<ActionResult> Index()
    {
        //Sync the state info and update if it is not the same
        var state = Request.QueryString["state"];
        if (state.Equals(AppController.auth2Client.CSRFToken, StringComparison.Ordinal))
        {
            ViewBag.State = state + " (valid)";
        }
        else
        {
            ViewBag.State = state + " (invalid)";
        }

        string code = Request.QueryString["code"] ?? "none";
        string realmId = Request.QueryString["realmId"] ?? "none";
        await GetAuthTokensAsync(code, realmId);

        ViewBag.Error = Request.QueryString["error"] ?? "none";

        return RedirectToAction("Tokens", "App");
    }

    /// <summary>
    /// Exchange Auth code with Auth Access and Refresh tokens and add them to Claim list
    /// </summary>
    private async Task GetAuthTokensAsync(string code, string realmId)
    {
        if (realmId != null)
        {
            Session["realmId"] = realmId;
        }

        Request.GetOwinContext().Authentication.SignOut("TempState");
        var tokenResponse = await AppController.auth2Client.GetBearerTokenAsync(code);

        var claims = new List<Claim>();

        if (Session["realmId"] != null)
        {
            claims.Add(new Claim("realmId", Session["realmId"].ToString()));
        }

        if (!string.IsNullOrWhiteSpace(tokenResponse.AccessToken))
        {
            claims.Add(new Claim("access_token", tokenResponse.AccessToken));
            claims.Add(new Claim("access_token_expires_at", (DateTime.Now.AddSeconds(tokenResponse.AccessTokenExpiresIn)).ToString()));
        }

        if (!string.IsNullOrWhiteSpace(tokenResponse.RefreshToken))
        {
            claims.Add(new Claim("refresh_token", tokenResponse.RefreshToken));
            claims.Add(new Claim("refresh_token_expires_at", (DateTime.Now.AddSeconds(tokenResponse.RefreshTokenExpiresIn)).ToString()));
        }

        var id = new ClaimsIdentity(claims, "Cookies");
        Request.GetOwinContext().Authentication.SignIn(id);

    }
}
注意:这是用户在身份验证完成后重定向的控制器

这就是我试图调用api时发生的错误 对象引用未设置为对象的实例。 描述:执行当前web请求期间发生未处理的异常。请查看堆栈跟踪以了解有关错误的更多信息以及错误在代码中的起源

异常详细信息:System.NullReferenceException:对象引用不存在 设置为对象的实例

源错误:

第66行:/{67行:var 委托人=用户作为索赔人;第68行: OAuth2RequestValidator oauthValidator=新 OAuth2RequestValidatorprincipal.FindFirstaccess_token.Value; 第69行:第70行://使用 身份验证令牌和realmId


刚刚遇到这个问题并找到了一个解决方案,也许可以为其他人节省一些时间

IntuitAPI文档假定您正在使用Cookie身份验证

将此添加到Startup.cs,然后尝试一下

       app.UseCookieAuthentication(new CookieAuthenticationOptions
       {
            AuthenticationType = "Cookies"
       });

       app.UseCookieAuthentication(new CookieAuthenticationOptions
       {
           AuthenticationType = "TempState",
           AuthenticationMode = AuthenticationMode.Passive
       });