有没有一种方法可以调用API从快速手册中检索公司信息

时间:2019-04-05 18:58:11

标签: c#

我是mvc的新手,试图从Quickbooks调用Api以获取公司信息(沙盒),因此我按照intuit.com上的说明进行操作:创建应用程序,生成客户端ID,客户端密码并在web.config中使用。我也生成了OAuth2,使用用户名和密码登录后,在项目中可以看到“连接到Quickbooks”对话框,现在我正试图调用Api,因此首先我创建了OAuth2RequestValidator类的dobject,但错误提示为“未将对象引用设置为对象实例,因为我正在使用声明进行身份验证,我认为ClaimsPrincipal无法读取ClaimsIdentity的声明,并且被卡在此处,我试图使用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时发生的错误 bject引用未设置为对象的实例。 说明:执行当前Web请求期间发生未处理的异常。请查看堆栈跟踪,以获取有关错误及其在代码中起源的更多信息。

  

异常详细信息:System.NullReferenceException:没有对象引用   设置为对象的实例。

源错误:

  

第66行:// {第67行:var   主体=用户作为ClaimsPrincipal;第68行:
  OAuth2RequestValidator oauthValidator =新   OAuth2RequestValidator(principal.FindFirst(“ access_token”)。Value);   第69行:第70行://使用以下命令创建ServiceContext   身份验证令牌和realmId

1 个答案:

答案 0 :(得分:1)

刚遇到这个问题,找到了解决办法,也许能帮别人省点时间。

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

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

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

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