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)
{
.
.
.
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;
}
}
}
}
I'm attempting to initiate a call with the Microsoft Graph SDK Create call API using the code sample below. The attempt fails with a Not Found exception.
I have registered the bot application, added the API call permissions and I am able to receive incoming calls from Teams.
It's not clear from the Microsoft documentation whether Teams users can be called directly or whether they have to be allocated a VoIP number. Has anyone been able to use the Graph SDK to call a Teams User? Is there some special configuration a User needs to have in order to be able to receive a call?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Microsoft.Graph.Communications.Common.Telemetry;
using Microsoft.Extensions.Logging;
using Microsoft.Graph;
using Microsoft.Graph.Communications.Calls;
using Microsoft.Graph.Communications.Calls.Media;
using Microsoft.Graph.Communications.Client;
using Microsoft.Skype.Bots.Media;
namespace sipbotcaller
{
class Program
{
private static string APP_NAME = "";
private static string APP_ID = "";
private static string APP_SECRET = "";
private static string TENANT_ID = "";
private static string CALLBACK_URI = "";
private static string CERTIFICATE_THUMBPRINT = "";
private static int MEDIA_PORT = 10000;
private static string PUBLIC_IP = "";
private static string HOSTNAME = "";
static async Task Main(string[] args)
{
Console.WriteLine("Teams Call Console:");
GraphLogger graphLogger = new GraphLogger(APP_NAME);
graphLogger.DiagnosticLevel = System.Diagnostics.TraceLevel.Verbose;
ILogger logger = new ConsoleLogger(graphLogger);
AuthenticationProvider authProvider = new AuthenticationProvider(
APP_NAME,
APP_ID,
APP_SECRET,
TENANT_ID,
graphLogger);
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
var users = await graphClient.Users.Request().GetAsync();
foreach (var user in users)
{
Console.WriteLine($"user Id: {user.Id}.");
Console.WriteLine($"user Display Name: {user.DisplayName}.");
}
var mediaPlatformSettings = new MediaPlatformSettings()
{
MediaPlatformInstanceSettings = new MediaPlatformInstanceSettings()
{
CertificateThumbprint = CERTIFICATE_THUMBPRINT,
InstanceInternalPort = MEDIA_PORT,
InstancePublicIPAddress = IPAddress.Parse(PUBLIC_IP),
InstancePublicPort = MEDIA_PORT,
ServiceFqdn = HOSTNAME,
},
ApplicationId = APP_ID,
};
var builder = new Microsoft.Graph.Communications.Client.CommunicationsClientBuilder(
APP_NAME,
APP_ID,
graphLogger);
builder
.SetAuthenticationProvider(authProvider)
.SetNotificationUrl(new Uri(CALLBACK_URI))
.SetMediaPlatformSettings(mediaPlatformSettings)
.SetServiceBaseUrl(new Uri(CALLBACK_URI));
var client = builder.Build();
AudioSocketSettings audioSockSettings = new AudioSocketSettings {
CallId = Guid.NewGuid().ToString(),
SupportedAudioFormat = AudioFormat.Pcm16K,
StreamDirections = StreamDirection.Sendrecv
};
AudioSocket audioSock = new AudioSocket(audioSockSettings);
var mediaConfig = MediaPlatform.CreateMediaConfiguration(audioSock);
Console.WriteLine($"media config: {mediaConfig}");
Console.WriteLine($"Attempting to call {users.First().DisplayName}.");
var call = new Call
{
CallbackUri = CALLBACK_URI,
TenantId = TENANT_ID,
Targets = new List<InvitationParticipantInfo>()
{
new InvitationParticipantInfo
{
Identity = new IdentitySet
{
User = new Identity
{
DisplayName = users.First().DisplayName,
Id = users.First().Id
},
}
}
},
RequestedModalities = new List<Modality>()
{
Modality.Audio
},
MediaConfig = new AppHostedMediaConfig()
{
Blob = mediaConfig.ToString(Newtonsoft.Json.Formatting.None)
},
};
var callResult = await client.Calls().AddAsync(call);
Console.WriteLine($"Call result {callResult.Id}.");
Console.WriteLine("Finished.");
Console.WriteLine("Press any key to exit...");
Console.ReadLine();
}
}
}
Result:
<snip>
StatefulCall: Verbose
StatefulCall: Info
StatefulCall: Verbose
StatefulCall: Info
StatefulCall: Info
StatefulCall: Error {
"error": {
"code": "itemNotFound",
"message": "Unexpected exception returned from the service.\r\nStatus Code: NotFound"
}
}
StatefulCall: 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")
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.
The objective is, by using WCF, connect to a Web service that requires UserNameToken ws-security as specified by the standard "oasis-200401-wss-soap-message-security-1.0".
Full specification can be find here http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0.pdf
There are few examples of how to create the token and none worked for me.
When i posted this i had already found the answer but since it was not easy, i let here the solution i found and hope it can be improved. So i will just jump to the answer.
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens;
using System.Security.Cryptography;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Security;
using System.ServiceModel.Channels;
using System.Text;
using System.Threading.Tasks;
namespace WSClient
{
//Create this custom credentials class to implement UserNameToken autentication
public class CustomCredentials : ClientCredentials
{
public CustomCredentials()
{ }
protected CustomCredentials(CustomCredentials cc)
: base(cc)
{ }
public override System.IdentityModel.Selectors.SecurityTokenManager CreateSecurityTokenManager()
{
return new CustomSecurityTokenManager(this);
}
protected override ClientCredentials CloneCore()
{
return new CustomCredentials(this);
}
}
public class CustomSecurityTokenManager : ClientCredentialsSecurityTokenManager
{
public CustomSecurityTokenManager(CustomCredentials cred)
: base(cred)
{ }
public override System.IdentityModel.Selectors.SecurityTokenSerializer CreateSecurityTokenSerializer(System.IdentityModel.Selectors.SecurityTokenVersion version)
{
return new CustomTokenSerializer(System.ServiceModel.Security.SecurityVersion.WSSecurity10);
}
}
public class CustomTokenSerializer : WSSecurityTokenSerializer
{
public CustomTokenSerializer(SecurityVersion sv)
: base(sv)
{ }
protected override void WriteTokenCore(System.Xml.XmlWriter writer,
System.IdentityModel.Tokens.SecurityToken token)
{
UserNameSecurityToken userToken = token as UserNameSecurityToken;
string tokennamespace = "o";
DateTime created = DateTime.UtcNow;
string createdStr = created.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
string phrase = Guid.NewGuid().ToString();
var nonce = Convert.ToBase64String(Encoding.UTF8.GetBytes(phrase));
SHA1CryptoServiceProvider sha1Hasher = new SHA1CryptoServiceProvider();
//Password_Digest = Base64 ( SHA-1 ( nonce + created + password ) )
string Password_Digest = Convert.ToBase64String(sha1Hasher.ComputeHash(Encoding.UTF8.GetBytes(phrase + createdStr + userToken.Password))); // pxLqPLCXU1EiUS+NnpRuCw==
var stringToWrite = string.Format(
"<{0}:UsernameToken u:Id=\"" + token.Id +
"\" xmlns:u=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">" +
"<{0}:Username>" + userToken.UserName + "</{0}:Username>" +
"<{0}:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest\">" +
Password_Digest + "</{0}:Password>" +
"<{0}:Nonce EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\">" +
nonce + "</{0}:Nonce>" +
"<u:Created>" + createdStr + "</u:Created></{0}:UsernameToken>", tokennamespace);
writer.WriteRaw(stringToWrite);
}
}
class Program
{
static void Main(string[] args)
{
try
{
//for invalid ssl server certificate
System.Net.ServicePointManager.ServerCertificateValidationCallback +=
(se, cert, chain, sslerror) =>
{
return true;
};
CustomBinding binding = new CustomBinding();
var security = TransportSecurityBindingElement.CreateUserNameOverTransportBindingElement();
security.IncludeTimestamp = true;
security.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic256;
security.MessageSecurityVersion = MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
security.EnableUnsecuredResponse = true;
var encoding = new TextMessageEncodingBindingElement();
encoding.MessageVersion = MessageVersion.Soap11;
var transport = new HttpsTransportBindingElement();
transport.MaxReceivedMessageSize = 2000000;
binding.Elements.Add(security);
binding.Elements.Add(encoding);
binding.Elements.Add(transport);
WSClient.Proxy.TargetWS client = new Proxy.TargetWS(binding,
new EndpointAddress(Properties.Settings.Default.Url));
//change credential for the custom credentials instance
client.ChannelFactory.Endpoint.Behaviors.Remove<System.ServiceModel.Description.ClientCredentials>();
client.ChannelFactory.Endpoint.Behaviors.Add(new CustomCredentials());
client.ClientCredentials.UserName.UserName = Properties.Settings.Default.username;
client.ClientCredentials.UserName.Password = Properties.Settings.Default.password;
Proxy.Message message = new WSClient.Proxy.Message();
message.id = "whatever";
client.foo(message);
System.Console.Write("Success");
}
catch (Exception ex)
{
System.Console.Write(ex.Message);
}
}
}
}
a bit extensive!
Essentially, it is need to serialize the token according to Oasys specifications. To do this it is need to derivate ClientCredentials, ClientCredentialsSecurityTokenManager and WSSecurityTokenSerializer in the way presented.
About the binding, not sure if works for all or if variations are allowed by the specification.