I'm fairly new to .NET and c# and I'm working on a POC where I've run into an issue when a controller throws the error
System.InvalidOperation Exception {"Unable to resolve controller: TenantController"}
The Inner exception details are
No default Instance is registered and cannot be automatically determined for type 'GICS.Web.Managers.Interfaces.ITenantManager'
There is no configuration specified for GICS.Web.Managers.Interfaces.ITenantManager
1.) new TenantController(Default of ITenantManager, Default of IRemedyService)
2.) GICS.Web.Controllers.Api.TenantController
3.) Instance of GICS.Web.Controllers.Api.TenantController
4.) Container.GetInstance(GICS.Web.Controllers.Api.TenantController)
The TenantController looks as follows:
using System.Web.Mvc;
using GICS.Web.Controllers.Api.Abstracts;
using GICS.Web.Managers.Interfaces;
using GICS.Web.Services.Interfaces;
using System.Collections.Generic;
using GICS.Web.ViewModels.Tenant;
using GICS.Web.Models.Tenant;
namespace GICS.Web.Controllers.Api
{
[RoutePrefix("api/tenant")]
public class TenantController : BaseApiController
{
private readonly ITenantManager _tenantsManager;
private readonly IRemedyService _remedyService;
private string token;
public TenantController(ITenantManager tenantsManager, IRemedyService remedyService)
{
_tenantsManager = tenantsManager;
_remedyService = remedyService;
token = null;
}
[HttpGet, Route("{groupId}/{userName}")]
public JsonResult getTenants(string groupId, string UserName)
{
getToken(UserName);
JsonResult result = Json(null);
if (token != null)
{
var tenants = _tenantsManager.GetTenants(token, groupId);
List<TenantViewModel> tenantViewModelList = new List<TenantViewModel>();
foreach (Values x in tenants)
{
TenantViewModel model = new TenantViewModel(x, groupId);
tenantViewModelList.Add(model);
}
result = Json(tenantViewModelList);
}
return result;
}
}
The TenantManager interface is as follows:
using System.Collections.Generic;
using GICS.Web.Models.Tenant;
namespace GICS.Web.Managers.Interfaces
{
public interface ITenantManager
{
IEnumerable<Values> GetTenants(string token, string groupId);
}
}
And the Manager implementation is:
using GICS.Web.Managers.Abstracts;
using GICS.Web.Managers.Interfaces;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Configuration;
using System.Net;
using GICS.Web.Models.Tenant;
namespace GICS.Web.Managers
{
public class TentantManager : ManagerBase, ITenantManager
{
public IEnumerable<Models.Tenant.Values> GetTenants(string token, string groupId)
{
Tenant restEntries = null;
List<Models.Tenant.Values> tenantList = new List<Models.Tenant.Values>();
using (WebClient client = new WebClient())
{
client.Headers[HttpRequestHeader.Authorization] = token;
var baseURL = ConfigurationManager.AppSettings["RemedyBaseUrl"];
var apiPath = ConfigurationManager.AppSettings["RemedyAPIPath"];
string getURL = baseURL + apiPath + "ESN%3AAST%3ALogSysComp%5FASTPeople" + "?q=?q=%27PeopleGroup%20Form%20Entry%20ID%27%20%3D%20%22" + groupId + "%22&fields=values(Name)";
string getResponse = client.DownloadString(getURL);
restEntries = JsonConvert.DeserializeObject<Tenant>(getResponse);
foreach (Models.Tenant.Entry x in restEntries.entries)
{
tenantList.Add(x.values);
}
}
return tenantList;
}
}
}
I have other controllers in the project that follow the same approach and all are working except for this one. Anyone spot where I am going wrong here?
Thanks in advance.
Related
I am trying to get data from a IT ticketing system through API in SSIS using Script Component, very new to this:
I am just starting with 1 field called Supplier, for that i have so far written below scripts:
Script Component
Created a class called ResultAPI:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SC_b15eeeff0e3544d3a882578b3eb9bbba
{
public class ResultAPI
{
public string Supplier { get; set; }
}
}
Another class called GenericResponse:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SC_b15eeeff0e3544d3a882578b3eb9bbba
{
public class GenericResponse
{
public ResultAPI[] ListData { get; set; }
}
public class ResultGen
{
public GenericResponse Result { get; set; }
}
}
Main:
public override void CreateNewOutputRows()
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://***************");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
var cred = Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", "username", "pwd")));
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", cred);
string APIUrl = string.Format("https://**************");
var response = client.GetAsync(APIUrl).Result;
if (response.IsSuccessStatusCode)
{
var result = response.Content.ReadAsStringAsync().Result;
var serializer = new JavaScriptSerializer();
var data = serializer.Deserialize<ResultAPI>(result);
APIResultsBuffer.AddRow();
//APIResultsBuffer.SupplierType = data.SupplierType;
APIResultsBuffer.Supplier = data.Supplier;
//APIResultsBuffer.nextpage = data.nextpage;
//APIResultsBuffer.previouspage = data.previouspage;
//APIResultsBuffer.recordcount = data.recordcount;
//APIResultsBuffer.HREF = data.HREF;
}
}
}
When I execute the package, i get the attached error:
Error
Not sure exactly where this error is.
Hoping to download this file in SQL Server table
I need to use another company's API to query data using POST requests.
The API works (= I receive all the data with no errors) when I query it from the swagger website using the UI, but when I do it from my C# program I get a 500 Internal Server Error.
Where should I be looking for the problem ? Is there a way to get a more detailed error message ?
Edit (added code) :
using System;
using System.Data.Entity;
using System.Data.Entity.Core.Mapping;
using System.Data.Entity.Core.Metadata.Edm;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Infrastructure.Interception;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Runtime.Serialization;
using System.Text;
namespace credex_distribution_offers_to_interfaces
{
class Program
{
private const string jsonMediaType = "application/json";
static void Main()
{
FetchJSONAndInsertToDB();
}
private static bool FetchJSONAndInsertToDB()
{
var baseServiceUrl = new Uri("a valid url");
Root rootObject;
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(jsonMediaType));
try
{
string token = FetchToken(httpClient, baseServiceUrl);
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(token);
}
catch (Exception e)
{
return false;
}
try
{
rootObject = FetchDistributionLookupOffers(httpClient, baseServiceUrl, 29612, 29613, 29614, 29617, 29621);
}
catch (Exception e)
{
return false;
}
}
// database related stuff...
// ...
return true;
}
[DataContract]
public class MortgageForDistributionLookupInputDto
{
public int[] OfferNumbers { get; set; }
}
private static Root FetchDistributionLookupOffers(HttpClient aHttpClient, Uri aBaseServiceUrl, params int[] aOfferNumbers)
{
var input = new MortgageForDistributionLookupInputDto()
{
OfferNumbers = aOfferNumbers
};
var lookup = aHttpClient.PostAsync(new Uri(aBaseServiceUrl, "v1/MortgageDetails/InvestorLookupOffers"), PayloadFor(input)).Result;
if (lookup.StatusCode != HttpStatusCode.OK)
{
throw new Exception("Fetching investor lookup offers failed with HTTP status code '" + lookup.StatusCode + "' : " + lookup.ReasonPhrase + "}");
}
var obj = ValueFor<Root>(lookup.Content);
return obj;
}
private static HttpContent PayloadFor<T>(T aObject)
{
return new StringContent(aObject.SerializeJson(), Encoding.UTF8, jsonMediaType);
}
private static T ValueFor<T>(HttpContent aHttpContent)
{
//var content = aHttpContent.ReadAsStringAsync();
return aHttpContent.ReadAsStreamAsync().Result.DeSerializeJson<T>();
}
private static string FetchToken(HttpClient aHttpClient, Uri aBaseServiceUrl)
{
var login = new LoginRequest()
{
UserName = "some user name",
Password = "some password"
};
var authResult = aHttpClient.PostAsync(new Uri(aBaseServiceUrl, "api/Login"), PayloadFor(login)).Result;
if (authResult.StatusCode != HttpStatusCode.OK)
{
throw new Exception("Fetching authentication token failed. Reason : " + authResult.StatusCode + " -> " + authResult.ReasonPhrase);
}
return authResult.Content.ReadAsStringAsync().Result.Trim('"');
}
}
}
I am trying to retrieve records in my index ActionResult but keep getting a "The name 'connectionString' does not exist in the current context" error. Please see below code:
using Microsoft.Xrm.Tooling.Connector;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TestMVCApp.DAL;
using TestMVCApp.Models;
namespace TestMVCApp.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
var objDAL = new DAL_InvoicesEntity();
List<InvoicesModel> invInfo = objDAL.RetriveRecords(connectionString);
ViewBag.invInfo = invInfo;
return View();
}
}
}
DAL class file:
using System;
using System.Collections.Generic;
using Microsoft.Xrm.Sdk;
using TestMVCApp.Models;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Tooling.Connector;
using System.Linq;
namespace TestMVCApp.DAL
{
public class DAL_InvoicesEntity
{
public List<InvoicesModel> RetriveRecords(string connectionString)
{
var svc = new CrmServiceClient(connectionString);
var query = new QueryExpression()
{
EntityName = "new_invoices",
ColumnSet = new ColumnSet("new_invoicesid", "ttt_customer", "ttt_invoiceid", "ttt_paymentreceived", "ttt_commission", "ttt_adminfee", "ttt_discountamount"),
TopCount = 10
};
var invoices = svc.RetrieveMultiple(query).Entities.ToList();
var invoiceModels = invoices.Select(i =>
new InvoicesModel
{
InvoiceID = i.GetAttributeValue<Guid>("new_invoicesid"),
ClientName = i.GetAttributeValue<EntityReference>("ttt_customer"),
InvoiceNumber = i.GetAttributeValue<string>("ttt_invoiceid"),
AdminFee = i.GetAttributeValue<decimal>("ttt_adminfee"),
Discount = i.GetAttributeValue<decimal>("ttt_discountamount"),
PaymentReceived = i.GetAttributeValue<decimal>("ttt_paymentreceived")
})
.ToList();
return invoiceModels;
}
}
}
Please assist if you can
You should define connectionString variable before using it.
public class HomeController : Controller
{
private const connectionString = "YourConnectionString";
public ActionResult Index()
{
var objDAL = new DAL_InvoicesEntity();
List<InvoicesModel> invInfo = objDAL.RetriveRecords(connectionString);
ViewBag.invInfo = invInfo;
return View();
}
}
I am trying to post a message on the #general channel and this worked when was doing it through a console app but Now I am using MVC and the message doesn't seem to get posted. Also, earlier I was using the webhook URL and now I am using the access token that I have.
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
namespace SlackClient.Controllers
{
public class SlackClient
{
private readonly Uri _uri;
private readonly Encoding _encoding = new UTF8Encoding();
public SlackClient(string urlWithAccessToken)
{
_uri = new Uri(urlWithAccessToken);
}
//Post a message using simple strings
public void PostMessage(string text, string username = null, string channel = null)
{
Payload payload = new Payload()
{
Channel = channel,
Username = username,
Text = text
};
PostMessage(payload);
}
//Post a message using a Payload object
public void PostMessage(Payload payload)
{
string payloadJson = JsonConvert.SerializeObject(payload);
using (WebClient client = new WebClient())
{
NameValueCollection data = new NameValueCollection();
data["payload"] = payloadJson;
var response = client.UploadValues(_uri, "POST", data);
//The response text is usually "ok"
string responseText = _encoding.GetString(response);
}
}
}
//This class serializes into the Json payload required by Slack Incoming WebHooks
public class Payload
{
[JsonProperty("channel")]
public string Channel { get; set; }
[JsonProperty("username")]
public string Username { get; set; }
[JsonProperty("text")]
public string Text { get; set; }
}
}
And the other class is SlackClientTest.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace SlackClient.Controllers
{
public class SlackClientTest
{
void TestPostMessage()
{
string urlWithAccessToken = "https://srishti2604.slack.com/services/hooks/incoming-webhook?token=my-tokenHere.";
SlackClient client = new SlackClient(urlWithAccessToken);
client.PostMessage(username: "Mr. Torgue",
text: "THIS IS A TEST MESSAGE! SQUEEDLYBAMBLYFEEDLYMEEDLYMOWWWWWWWW!",
channel: "#general");
}
}
}
Could someone tell me what might me wrong?
My console app looks like this
SlackClient.cs
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace SlackProject1
{
public class SlackCient
{
private readonly Uri _webhookUrl;
private readonly HttpClient _httpClient = new HttpClient();
public SlackCient(Uri webhookUrl)
{
_webhookUrl = webhookUrl;
}
public async Task<HttpResponseMessage> SendMessageAsync(string message,
string channel = null, string username = null)
{
var payload = new
{
text = message,
channel,
username,
};
var serializedPayload = JsonConvert.SerializeObject(payload);
var response = await _httpClient.PostAsync(_webhookUrl,
new StringContent(serializedPayload, Encoding.UTF8, "application/json"));
return response;
}
}
}
And the Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SlackProject1
{
class Program
{
static void Main(string[] args)
{
Task.WaitAll(IntegrateWithSlackAsync());
}
private static async Task IntegrateWithSlackAsync()
{
var webhookUrl = new Uri("https://hooks.slack.com/services/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");
var slackClient = new SlackCient(webhookUrl);
while (true)
{
Console.Write("Type a message: ");
var message = Console.ReadLine();
var response = await slackClient.SendMessageAsync(message);
var isValid = response.IsSuccessStatusCode ? "valid" : "invalid";
Console.WriteLine($"Received {isValid} response.");
}
}
}
}
I want to be able to login to my identity database with user name and password and retreive a JWT. Then I want to use the JWT to access data securely from my API.
I found out that the SDK code generated by VS2017 uses an old version of autorest, so I have switched to using Azure Autorest
The api and the SDK are both ASP.NET Core 2.0
To generate the SDK I use
AutoRest -mynamespace mytrack.Client -CodeGenerator CSharp -Modeler
Swagger -Input swagger.json -PackageName mytrack.client -AddCredentials true
The versions show as
AutoRest code generation utility [version: 2.0.4262; node: v8.11.2]
I have written my test as
using System;
using System.Threading.Tasks;
using Microsoft.Rest;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json.Linq;
using swagger; // my name space from the autorest command, not to be confused with swagger itself.
using swagger.Models;
namespace CoreClientTest
{
[TestClass]
public class MyTests
{
[TestMethod]
public void TestMethod1()
{
try
{
GetMyJob().Wait();
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
private static async Task GetMyJob()
{
var tokenRequest = new TokenRequest
{
Username = "myusername",
Password = "mypassword"
};
var credentials = new TokenCredentials("bearer token");
var uri = new Uri("https://localhost:44348", UriKind.Absolute);
var tokenClient = new Track3API(uri, credentials);
var tokenResponse = await tokenClient.ApiRequestTokenPostWithHttpMessagesAsync(tokenRequest);
var tokenContent = await tokenResponse.Response.Content.ReadAsStringAsync();
var tokenString = JObject.Parse(tokenContent).GetValue("token").ToString();
var creds2 = new TokenCredentials(tokenString);
var client2 = new Track3API(uri, creds2);
var result = await client2.ApiJobsByIdGetWithHttpMessagesAsync(1);
var response = result.Response;
Console.WriteLine(response.ToString());
}
}
}
I can see that the result has OK and I can see the token in it.
I cant see the return job
The method in the api has
[Produces("application/json")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Route("api/jobs")]
public class JobController : Controller
{
/// <summary>
/// Returns Job Header for Id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("{id}", Name = "Get")]
public IActionResult Get(int id)
{
var header1 = new JobHeader
{
JobNumber = "1234",
Id = id,
CustomerPurchaseOrderNumber = "fred"
};
return Ok(header1);
}
}
You should apply the DataContract attribute over the class so that when RestClient consumes the service reference, it also generate the types.
Read it here.
You should also attach DatamMember attribute on Property. See below example
[DataContract]
class Person
{
[DataMember]
public string Name {get; set; }
[DataMember]
public int Id {get; set; }
public Person(string name, int id)
{
this.Name = name;
this.Id = id;
}
}
When Rest Client consume the service, it will generate the classes at client side for those classes which are attributed with DataContract.
Finally it is working.
I found a tip at Andrei Dzimchuk's blog on setting up the token
using System;
using System.Threading.Tasks;
using Microsoft.Rest;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using swagger;
using swagger.Models;
namespace CoreClientTest
{
[TestClass]
public class MyTests
{
[TestMethod]
public void TestMethod1()
{
try
{
GetMyJob().Wait();
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
private static async Task<JobHeader> GetMyJob()
{
var tokenRequest = new TokenRequest
{
Username = "myusername",
Password = "mypassword"
};
var credentials = new TokenCredentials("bearer token");
var uri = new Uri("https://localhost:44348", UriKind.Absolute);
var tokenClient = new Track3API(uri, credentials);
var tokenResponse = await tokenClient.ApiRequestTokenPostWithHttpMessagesAsync(tokenRequest);
var tokenContent = await tokenResponse.Response.Content.ReadAsStringAsync();
var tokenString = JObject.Parse(tokenContent).GetValue("token").ToString();
var creds2 = new TokenCredentials(tokenString);
var client2 = new Track3API(uri, creds2);
var result = await client2.ApiJobsByIdGetWithHttpMessagesAsync(1);
string resultContent = await result.Response.Content.ReadAsStringAsync();
var job = JsonConvert.DeserializeObject<JobHeader>(resultContent);
Console.WriteLine(job.JobNumber);
return job;
}
}
}