I am new to json and web api.
I created a service called AdminService which has a get method. Kindly see below the get method:
[Route("{iUserId:long}/{iSegmentId:long}/GetUserSegmentItemBySegmentIdAndUserId")]
public IEnumerable<spADGetUserSegmentItemBySegmentIdAndUserId> GetUserSegmentItemBySegmentIdAndUserId(long iUserId, long iSegmentId)
{
using (ADMINEntities context = new ADMINEntities())
{
var usibsu = context.spADGetUserSegmentItemBySegmentIdAndUserId(iUserId, iSegmentId);
if (usibsu != null) return usibsu.ToList();
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
}
}
The service is working correctly.
Now, I have another service called TestService in which i want to call the get method i created in the adminservice.
Below is my code:
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
using Newtonsoft.Json;
using NPAService.Models;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
namespace NPAService.Controllers
{
public class HomeController : Controller
{
private string ServiceURLBase = ConfigurationManager.AppSettings["AdminUrl"];
public ActionResult Index()
{
return View();
}
private void MoveImageFiles()
{
DirectoryInfo dirInfo = new DirectoryInfo(Server.MapPath("~/Reports/"));
List<String> FileNames = new List<string>();
for (int i = 0; i < dirInfo.GetFiles().Length; i++)
{
FileNames.Add(dirInfo.GetFiles()[i].FullName);
}
for (int i = 0; i < FileNames.Count; i++)
{
FileInfo fileInfo = new FileInfo(FileNames[i]);
//Delete file if it is older than five minutes
if (DateTime.Now.Subtract(fileInfo.CreationTime).TotalMinutes > 1.0)
{
System.IO.File.Delete(fileInfo.FullName);
//if the file exists at the destination folder, delete it as well
if (System.IO.File.Exists(Server.MapPath("~/Home/images/") + fileInfo.Name))
{
System.IO.File.Delete(Server.MapPath("~/Home/images/") + fileInfo.Name);
}
}
else //Copy file to where it can get displayed on the report if it is less than 5 minute old
{
if (!System.IO.File.Exists(Server.MapPath("~/Home/images/") + fileInfo.Name))
{
System.IO.File.Copy(fileInfo.FullName, Server.MapPath("~/Home/images/") + fileInfo.Name);
}
}
}
}
public string GetUserDataSegment(long iUserId, long iSegmentId)
{
string ListString = string.Empty;
var userdata = new UserData();
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(ServiceURLBase);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = client.GetAsync(iUserId + "/" + iSegmentId + "/GetUserSegmentItemBySegmentIdAndUserId").Result;
if (response.IsSuccessStatusCode)
{
var data = response.Content.ReadAsStringAsync();
var product = JsonConvert.DeserializeObject<UserData>(data);
//foreach (var str in data)
//{
//ListString = str.MyList;
//if (iSegmentId == 1) //'Depot'
//{
// ListString = ("iRegionId IN (" + str.MyList + ")");
//}
//else if (iSegmentId == 2) //'BDC'
//{
//}
//else if (iSegmentId == 3) //'LPGMC'
//{
//}
//else if (iSegmentId == 4) //'Region'
//{
// ListString = ListString + (" and iRegionId IN (" + str.MyList + ")");
//}
//else if (iSegmentId == 5) //'OMC'
//{
// ListString = ListString + (" and iOMCId IN (" + str.MyList + ")");
// ListString = "";
//}
//else if (iSegmentId == 6) //'Zone'
//{
//}
//}
}
}
return ListString;
}
[System.Web.Mvc.HttpGet]
public ActionResult OutletReportListing(long lngCompanyId, string strszITSfromPersol,
string strsQuery1, string strsQuery2, string strsQuery3, string strsQuery4,
string strPicHeight, string strPicWeight, string strCompany, long iUserId, string type)
{
string Username = Convert.ToString(ConfigurationManager.AppSettings["username"]);
string Password = Convert.ToString(ConfigurationManager.AppSettings["password"]);
string Servername = Convert.ToString(ConfigurationManager.AppSettings["DSN"]);
string Databasename = Convert.ToString(ConfigurationManager.AppSettings["databasename"]);
//GetUserDataSegment(iUserId, 5).Wait();
//var myObjList = JSON.Deserialize<List<GetUserDataSegment>>(iUserId, 5);
//var objResponse1 =
// JsonConvert.DeserializeObject<List<UserData>>(iUserId, 5);
string strOMC = GetUserDataSegment(iUserId,5);
string strRegion = GetUserDataSegment(iUserId, 4);
ReportDocument reportdocument = new ReportDocument();
reportdocument.Load(Server.MapPath("~/Reports/rptNPAOutletListing.rpt"));
reportdocument.SetDatabaseLogon(Username, Password, Servername, Databasename);
reportdocument.SetParameterValue("#iCompanyId", lngCompanyId);
reportdocument.SetParameterValue("#szITSfromPersol", strszITSfromPersol);
reportdocument.SetParameterValue("#szQuery1", strsQuery1);
reportdocument.SetParameterValue("#szQuery2", strsQuery2);
reportdocument.SetParameterValue("#szQuery3", strOMC); //strOMC
reportdocument.SetParameterValue("#szQuery4", strRegion); //strRegion
reportdocument.SetParameterValue("#szPicHeight", strPicHeight);
reportdocument.SetParameterValue("#szPicWeight", strPicWeight);
reportdocument.SetParameterValue("#szCompany", strCompany);
ExportFormatType formtType = ExportFormatType.HTML40;
string ExportName = "NPAReport.html";
string ExportMimeType = "text/html";
if (type.Trim().ToLower().Equals("view"))
{
formtType = ExportFormatType.HTML40;
ExportName = "NPAReport.html";
ExportMimeType = "text/html";
}
else if (type.Trim().ToLower().Equals("pdf"))
{
formtType = ExportFormatType.PortableDocFormat;
ExportName = "NPAReport.pdf";
ExportMimeType = "application/pdf";
}
else if (type.Trim().ToLower().Equals("doc"))
{
formtType = ExportFormatType.WordForWindows;
ExportName = "NPAReport.doc";
ExportMimeType = "application/msword";
}
else if (type.Trim().ToLower().Equals("rtf"))
{
formtType = ExportFormatType.RichText;
ExportName = "NPAReport.rtf";
ExportMimeType = "application/rtf";
}
else if (type.Trim().ToLower().Equals("xls"))
{
formtType = ExportFormatType.Excel;
ExportName = "NPAReport.xls";
ExportMimeType = "application/vnd.ms-excel";
}
reportdocument.ExportToDisk(formtType, Server.MapPath("~/Reports/" + ExportName));
MoveImageFiles();
return File(Server.MapPath("~/Reports/" + ExportName), ExportMimeType);
}
}
}
As you can see, i want to generate a report file in my api project. But the first error i am getting is:
cannot convert from 'System.Threading.Tasks.Task' to 'string'
I have done a lot of research but none does not seem to work.
Any help or explanation would be appreciated. Thank you.
response.Content.ReadAsStringAsync();
Async calls return Task<T> . When you want to read the string you call .Result property and you get the string. There is also a way to make async call synchronous. When you call an async method, your method gets out of execution and your method's caller continues execution. When async call completes, then your method continues its execution right after async method. Also since you call async method from GetUserDataSegment method, it also needs to be labeled as async.
Related
I have a C# code that connects to a set of APIs and retrieves and displays specific data. Initially, the code was written in a way that heavily depended on Internet Explorer (the user had to be logged in to their account only through IE; otherwise, the application couldn't make a connection to the API). Since the IE expired, the code could no longer connect to the API, so I replaced the cookies with edge cookies. I receive no errors; however, the code is not giving the desire outcome. When I debugged, it looks like the exception of "Error:_edgeKey is null" is being thrown. How can I fix this?
I have created a folder named Controllers which includes StaticStrings.cs, WebAPI.cs, WebNav.cs.
StaticStrings.cs includes the set of APIs
WebAPI.cs includes the following code:
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using WeeklyScheduleModels;
using Newtonsoft.Json;
using System.Net.Http;
using System.Threading.Tasks;
namespace WeeklySchedule.Contollers
{
class WebAPI
{
public string GetNorderTimeExpensebyNo(string norderNo)
{
return "OK";
}
public string GetNorderDbIDfromNo(string norderNo)
{
return "";
}
public async Task<double> GetBookedHours(string subOrderNo)
//public double GetBookedHours(string subOrderNo)
{
using (var edgeCookie = new EdgeCookie())
{
var cookies = edgeCookie.GetCookies(new Uri(StaticStrings.UrlNCert), false);
var cookieString = new StringBuilder();
foreach (var cookie in cookies)
{
cookieString.Append(cookie.Name + "=" + cookie.Value + "; ");
}
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Cookie", cookieString.ToString());
string uri = "";
double totalHours = 0.0;
uri = StaticStrings.NOrderTimeExpenseAPI + subOrderNo;
var response = await client.GetStringAsync(uri);
NCertTimeExpenseMain ntem = JsonConvert.DeserializeObject<NCertTimeExpenseMain>(response);
foreach (OracleHour oh in ntem.oracleHours)
{
totalHours += oh.hours;
}
return totalHours;
}
}
//To get the status of the project from Ncert
public async Task<string> GetOrderStatus(string subOrderNo)
{
using (var edgeCookie = new EdgeCookie())
{
var cookies = edgeCookie.GetCookies(new Uri(StaticStrings.UrlNCert), false);
var cookieString = new StringBuilder();
foreach (var cookie in cookies)
{
cookieString.Append(cookie.Name + "=" + cookie.Value + "; ");
}
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Cookie", cookieString.ToString());
string uri = "";
uri = StaticStrings.OrderStatusAPI + subOrderNo + '?';
var response = await client.GetStringAsync(uri);
RootObject status = JsonConvert.DeserializeObject<RootObject>(response);
string currentstatusofproject = status.statusDescription;
return currentstatusofproject;
}
}
public CustomerList GetCustomerListFromPartialName(string partialName)
{
using (var edgeCookie = new EdgeCookie())
{
var cookies = edgeCookie.GetCookies(new Uri(StaticStrings.UrlNCert), false);
var cookieString = new StringBuilder();
foreach (var cookie in cookies)
{
cookieString.Append(cookie.Name + "=" + cookie.Value + "; ");
}
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Cookie", cookieString.ToString());
string searchStr = StaticStrings.CustomerSearchAPI + partialName + "&%24format=json&%24top=30&%24filter=status%20eq%20%27Active%27&%24count=true";
var response = client.GetStringAsync(searchStr).Result;
CustomerList cl = JsonConvert.DeserializeObject<CustomerList>(response);
return cl;
}
}
public List<FrameAgreement> GetAgreementsFromCustomerId(string customerId)
{
using (var edgeCookie = new EdgeCookie())
{
var cookies = edgeCookie.GetCookies(new Uri(StaticStrings.UrlNCert), false);
var cookieString = new StringBuilder();
foreach (var cookie in cookies)
{
cookieString.Append(cookie.Name + "=" + cookie.Value + "; ");
}
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Cookie", cookieString.ToString());
string searchStr = StaticStrings.CustomerAgreementAPI + customerId;
var response = client.GetStringAsync(searchStr).Result;
List<FrameAgreement> FAList = JsonConvert.DeserializeObject<List<FrameAgreement>>(response);
return FAList;
}
}
public List<Address> GetAddressFromCustomerId(string customerId)
{
using (var edgeCookie = new EdgeCookie())
{
var cookies = edgeCookie.GetCookies(new Uri(StaticStrings.UrlNCert), false);
var cookieString = new StringBuilder();
foreach (var cookie in cookies)
{
cookieString.Append(cookie.Name + "=" + cookie.Value + "; ");
}
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Cookie", cookieString.ToString());
string searchStr = StaticStrings.CustomerAddressAPI + customerId + "/survey-address/all";
var response = client.GetStringAsync(searchStr).Result;
List<Address> AddressList = JsonConvert.DeserializeObject<List<Address>>(response);
return AddressList;
}
}
}
}
WebNav.cs Includes the following code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data;
namespace WeeklySchedule.Contollers
{
public class EdgeCookie : IDisposable
{
private Microsoft.Win32.RegistryKey _edgeKey = null;
public EdgeCookie()
{
_edgeKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(#"Software\Microsoft\Windows\CurrentVersion\AppContainer\Storage\microsoft.microsoftedge_8wekyb3d8bbwe\MicrosoftEdge\Main", false);
}
public List<Cookie> GetCookies(Uri uri, bool v)
{
var cookies = new List<Cookie>();
try
{
if (_edgeKey == null)
{
throw new Exception("Error: _edgeKey is null");
}
var sqliteFile = System.IO.Path.Combine(_edgeKey.GetValue("DataPath").ToString(), "Cookies");
using (var conn = new System.Data.SQLite.SQLiteConnection("Data Source=" + sqliteFile + ";Version=3;"))
{
conn.Open();
using (var cmd = new System.Data.SQLite.SQLiteCommand("select host_key, name, encrypted_value, path, expires_utc, secure, httponly from cookies where host_key like '%" + uri.Host + "%'", conn))
{
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var cookie = new Cookie(
reader.GetString(1),
reader.GetString(2),
reader.GetString(3),
reader.GetString(0));
cookie.Expires = DateTime.FromFileTimeUtc(long.Parse(reader.GetString(4)));
cookie.Secure = reader.GetBoolean(5);
cookie.HttpOnly = reader.GetBoolean(6);
cookies.Add(cookie);
}
}
}
}
}
catch
{
throw new Exception("Error reading cookies from Microsoft Edge");
}
return cookies;
}
public void Dispose()
{
if (_edgeKey != null)
{
_edgeKey.Dispose();
_edgeKey = null;
}
}
}
}
researched on this topic and tried to implement different solutions, but I can't solved it.
I have a function plotmyChartAsync() that is getting values from google trends.
Using this function in Console Application works fine and I get my desiriable results.
But when I try to perform this function with a button from a windows form, it always failing. With this " HttpResponseMessage secondResponse = await clientUsed.GetAsync(secondRequestStr);" I always get 429 failure from the API. It means I am sending to many request. How could I avoid this?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Globalization;
using System.Threading;
namespace GoogleTrendsAnalysis
{
public partial class Form1 : Form
{
private SemaphoreSlim _mutex = new SemaphoreSlim(1);
public Form1()
{
InitializeComponent();
}
public async Task plotmyChartAsync()
{
await _mutex.WaitAsync();
try
{
const string searchKeyWord = "bmw";
const string firstTimePeriodString = "2021-01-10T00";
const string secondTimePeriodString = "+2021-01-15T00";
const string httprequestStr = "https://trends.google.de/trends/api/explore?hl=de&tz=-60&req=%7B%22comparisonItem%22:%5B%7B%22keyword%22:%22" + searchKeyWord + "%22,%22geo%22:%22DE%22,%22time%22:%22" + firstTimePeriodString + secondTimePeriodString + "%22%7D%5D,%22category%22:0,%22property%22:%22%22%7D&tz=-60";
CookieContainer cookies = new CookieContainer();
HttpClientHandler handler = new HttpClientHandler();
handler.CookieContainer = cookies;
HttpClient client = new HttpClient(handler);
HttpResponseMessage response = await client.GetAsync(httprequestStr, HttpCompletionOption.ResponseHeadersRead);
Uri uri = new Uri(httprequestStr);
Console.WriteLine(cookies.GetCookies(uri));
IEnumerable<Cookie> responseCookies = cookies.GetCookies(uri).Cast<Cookie>();
Console.WriteLine(responseCookies.First());
string cookieused = responseCookies.First().Name + "=" + responseCookies.First().Value;
client.CancelPendingRequests();
client.Dispose();
handler.Dispose();
using (var clientUsed = new HttpClient())
{
clientUsed.BaseAddress = new Uri("https://trends.google.de/trends/api/");
clientUsed.DefaultRequestHeaders.Add("cookie", cookieused);
Console.WriteLine(clientUsed.DefaultRequestHeaders);
HttpResponseMessage responseUsed = await clientUsed.GetAsync(httprequestStr);
responseUsed.EnsureSuccessStatusCode();
Console.WriteLine(responseUsed);
if (responseUsed.IsSuccessStatusCode)
{
string result = responseUsed.Content.ReadAsStringAsync().Result;
result = result.Substring(4, result.Length - 4);
Console.WriteLine("Result: " + result);
dynamic data = JObject.Parse(result);
Console.WriteLine("TOKEN: " + data.widgets[0]["token"]);
string myToken = data.widgets[0]["token"];
string secondRequestStr = "https://trends.google.de/trends/api/widgetdata/multiline?hl=de&tz=-60&req=%7B%22time%22:%22" + firstTimePeriodString + "%5C%5C:00%5C%5C:00" + secondTimePeriodString + "%5C%5C:00%5C%5C:00%22,%22resolution%22:%22HOUR%22,%22locale%22:%22de%22,%22comparisonItem%22:%5B%7B%22geo%22:%7B%22country%22:%22DE%22%7D,%22complexKeywordsRestriction%22:%7B%22keyword%22:%5B%7B%22type%22:%22BROAD%22,%22value%22:%22" + searchKeyWord + "%22%7D%5D%7D%7D%5D,%22requestOptions%22:%7B%22property%22:%22%22,%22backend%22:%22CM%22,%22category%22:0%7D%7D&token=" + myToken + "&tz=-60";
HttpResponseMessage secondResponse = await clientUsed.GetAsync(secondRequestStr);
secondResponse.EnsureSuccessStatusCode();
string secondResult = secondResponse.Content.ReadAsStringAsync().Result;
List<DateTime> dateTimes = new List<DateTime>();
List<double> values = new List<double>();
secondResult = secondResult.Substring(5, secondResult.Length - 5);
dynamic secondData = JObject.Parse(secondResult);
foreach (var t in secondData)
{
foreach (var x in t)
{
foreach (var s in x.timelineData)
{
bool ifhasDataStr = s.hasData[0];
if (ifhasDataStr == true)
{
string formattedValueStr = s.formattedValue[0];
string formattedTimeStr = s.formattedTime;
double myValue = Convert.ToDouble(formattedValueStr);
formattedTimeStr = formattedTimeStr.Replace(" um ", " ");
DateTime dt = DateTime.ParseExact(formattedTimeStr, "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture);
dateTimes.Add(dt);
values.Add(myValue);
Console.WriteLine("Die ZEIT: " + formattedTimeStr + " / DER WERT: " + myValue);
}
}
}
}
double numberOfPeriods = dateTimes.Count;
double[] valuesArr = values.ToArray();
double[] xs = new double[valuesArr.Length];
for (int i = 0; i < valuesArr.Length; i++)
{
xs[i] = dateTimes[i].ToOADate();
}
formsPlot1.Reset();
formsPlot1.plt.PlotScatter(xs, valuesArr);
formsPlot1.plt.Ticks(dateTimeX: true);
formsPlot1.Render();
}
}
}
finally
{
_mutex.Release();
}
}
protected async void button1_Click(object sender, EventArgs e)
{
await plotmyChartAsync();
}
}
}
After researching it I found that the problem was the cookie...
Here are the Adjustment that need to be done to the code above...
var baseAddress = new Uri("https://trends.google.de/trends/api/");
using (var firstHandler = new HttpClientHandler() { UseCookies = false })
using (var clientUsed = new HttpClient(firstHandler) { BaseAddress = baseAddress })
{
clientUsed.BaseAddress = baseAddress;
clientUsed.DefaultRequestHeaders.Accept.Clear();
//clientUsed.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//clientUsed.DefaultRequestHeaders.Add("cookie", cookieused);
var firstRequest = new HttpRequestMessage(HttpMethod.Get, httprequestStr);
firstRequest.Headers.Add("cookie", cookieused);
Console.WriteLine(httprequestStr);
HttpResponseMessage responseUsed = await clientUsed.SendAsync(firstRequest);
Console.WriteLine(responseUsed);
string result = responseUsed.Content.ReadAsStringAsync().Result;
Console.WriteLine(result);
I have content of video and object being created an pass into a http client web api. When ever I pass the image to the client it works find it gets to the post method, but when it comes to the video the client has trouble posting the video. I checked the video size length to make sure it meets the content length and it well under the specific ranges. The error that I receive is that the object has been disposed. If you look at the code the object is never disposed.
Here's the code on the app
public async Task<bool> AddToQueueAsync(Incident i, ContentPage page, MediaFile file)
{
HttpResponseMessage result = null;
Uri webserviceURL = i.IncidentType == IncidentType.Trooper ? trooperURL : gspURL;
var fileStream = File.Open(file.Path, FileMode.Open);
try
{
using (var client = new HttpClient())
{
using (fileStream)
{
using (var stream = new StreamContent(fileStream))
{
using (var content = new MultipartFormDataContent("----MyBoundary"))
{
if(i.MediaType == "Video")
{
content.Add(stream,"file", Guid.NewGuid().ToString() + ".mp4");
}
else
{
content.Add(stream, "file", Guid.NewGuid().ToString() + ".png");
}
content.Add(new StringContent(JsonConvert.SerializeObject(i)), "metadata");
result = await client.PostAsync(webserviceURL, content);
}
}
}
}
Here is the code on the web api:
[HttpPost]
public IHttpActionResult StarGSPDATA() {
try {
if(!Request.Content.IsMimeMultipartContent()) {
Request.CreateResponse(HttpStatusCode.UnsupportedMediaType);
}
starGSPDATAinfo suspicousInfo;
string homeDir = AppDomain.CurrentDomain.BaseDirectory;
string dir = $"{homeDir}/uploads/";
Directory.CreateDirectory(dir);
var file = HttpContext.Current.Request.Files.Count > 0 ?
HttpContext.Current.Request.Files[0] : null;
if(HttpContext.Current.Request.Form.Count > 0) {
suspicousInfo = MetaDataFromRequest(HttpContext.Current.Request.Form);
} else {
suspicousInfo = new starGSPDATAinfo();
}
if(file != null && file.ContentLength > 0) {
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(dir, fileName);
suspicousInfo.MediaFilePath = fileName;
try {
file.SaveAs(path);
} catch(Exception e) {
Console.WriteLine($"not saving: {e.ToString()}");
}
} else {
throw new HttpResponseException(
new HttpResponseMessage(
HttpStatusCode.NoContent));
}
CleanData(suspicousInfo);
db.starGSPDATAinfoes.Add(suspicousInfo);
db.SaveChanges();
return Created("http://localhost:50641/api/StarGSPDATA/", JsonConvert.SerializeObject(suspicousInfo));
} catch(Exception e) {
return InternalServerError(e);
}
}
It works for an image but not for a video Please help thank you!
Here is a picture of the error
I have the following 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);
}
}
But I have the following 2 error which seems simple:
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
However I am not sure how to fix this, as the operation can take some time to complete, it really needs to be asybnc
and the setupmanager
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;
}
}
}
You are defining the method with async word after the return type Task, async must be before Task.
public async Task SetupPartnerPackAsync(SetupInformation info)
{
.
.
.
I am using the code listed below for a c# visual studio project to interface with the DocuSign API. As soon as the code gets to
LoginInformation loginInfo = authApi.Login();
I am getting error message:
404 - File or directory not found.
The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable
Does anyone know why?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Newtonsoft.Json;
using DocuSign.eSign.Api;
using DocuSign.eSign.Model;
using DocuSign.eSign.Client;
namespace CoreRecipes
{
class Program
{
private string INTEGRATOR_KEY = "[key]";
static void Main(string[] args)
{
Program recipes = new Program();
recipes.listDocumentsAndDownloadTest();
Console.Read();
}
public void listDocumentsAndDownloadTest()
{
string username = "[username]";
string password = "[password]";
string envelopeId = "envelopid";
//configureApiClient("www.docusign.net/restapi");
//http"s://demo.docusign.net/restapi"
configureApiClient("https://demo.docusign.net/restpi");
string accountId = loginApi(username, password);
EnvelopesApi envelopesApi = new EnvelopesApi();
EnvelopeDocumentsResult docsList = envelopesApi.ListDocuments(accountId, envelopeId);
Console.WriteLine("EnvelopeDocumentsResult:\n{0}", JsonConvert.SerializeObject(docsList));
int docCount = docsList.EnvelopeDocuments.Count;
string filePath = null;
FileStream fs = null;
for (int i = 0; i < docCount; i++)
{
MemoryStream docStream = (MemoryStream)envelopesApi.GetDocument(accountId, envelopeId, docsList.EnvelopeDocuments[i].DocumentId);
filePath = Path.GetTempPath() + Path.GetRandomFileName() + ".pdf";
fs = new FileStream(filePath, FileMode.Create);
docStream.Seek(0, SeekOrigin.Begin);
docStream.CopyTo(fs);
fs.Close();
Console.WriteLine("Envelope Document {0} has been downloaded to: {1}", i, filePath);
}
}
public void configureApiClient(string basePath)
{
ApiClient apiClient = new ApiClient(basePath);
Configuration.Default.ApiClient = apiClient;
}
public string loginApi(string usr, string pwd)
{
ApiClient apiClient = Configuration.Default.ApiClient;
string authHeader = "{\"Username\":\"" + usr + "\", \"Password\":\"" + pwd + "\", \"IntegratorKey\":\"" + INTEGRATOR_KEY + "\"}";
Configuration.Default.AddDefaultHeader("X-DocuSign-Authentication", authHeader);
string accountId = null;
AuthenticationApi authApi = new AuthenticationApi();
LoginInformation loginInfo = authApi.Login();
foreach (LoginAccount loginAcct in loginInfo.LoginAccounts)
{
if (loginAcct.IsDefault == "true")
{
accountId = loginAcct.AccountId;
break;
}
}
if (accountId == null)
{
accountId = loginInfo.LoginAccounts[0].AccountId;
}
return accountId;
}
}
}
The issue is with this list:
configureApiClient("https://demo.docusign.net/restpi")
There is a typo in it - as identified by going to https://demo.docusign.net/restpi and seeing that it returned a 404.
I suggest changing it to:
configureApiClient("https://demo.docusign.net/restapi")