Self referencing loop detected for property in Web Application - c#

I am trying to port a mobile service app to a web application. To do so I created a new web application and copied the relevant code from the working mobile service to the new web application that I created (using the mobile app template.
I have the following code in my Startup method in the new application:
public partial class Startup
{
public static void ConfigureMobileApp(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
new MobileAppConfiguration()
.UseDefaultConfiguration()
.ApplyTo(config);
// Use Entity Framework Code First to create database tables based on your DbContext
Database.SetInitializer(new MobileServiceInitializer());
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize;
config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
app.UseWebApi(config);
MobileAppSettingsDictionary settings = config.GetMobileAppSettingsProvider().GetMobileAppSettings();
}
}
The config.Formatters were copied from the original application which returns the entity and its children to the json output of the api controller.
In the new application I had to add the [MobileAppController] to my api controllers. I get the following error from the controller in the web application app: Self referencing loop detected for property Teams
(The model has Teams --> Players and players has a teamid)
Based on this detailed question:
Self referencing loop detected - Getting back data from WebApi to the browser
The above code should work as it does in my mobile service app. The web service app appears to ignore the config.Formatters value as I have tried every value in the above question but I still get the same error.
If I place the [JSON Ignore] attribute before the Child list, then I do not get the error, but also do not get the children back in the json. How can I get this web application to accept the formatting values?

hank you for your useful comments. Thank you #dbc for pointing me to this question. I spent 3 days looking and didn't find it. So apparently I was correct that the mobile app is ignoring the json formatters. You let me to this post [json net error]. Adding the attribute [JsonObject(IsReference = true)] before the DTOs solved the problem with minimum code. [json net error]:stackoverflow.com/questions/7397207/… – Haim Katz Jul 24 at 13:41  

Related

ASP.NET MVC application : could not localize MessageFormat in ApplicationUserManager.RegisterTwoFactorProvider in IdentityConfig.cs

In a standard ASP.NET MVC (5.2.7) application with Identity (2.2.1) I'm trying to localize the message sent during the two factor authentication.
I have both PhoneNumberTokenProvider and EmailTokenProvider.
There is also a project with *.resx files containing the text messages in different languages.
In the application the current language is set based on custom language cookie.
And in every controller or view if I use Resources.<<message_name>> I get the text of the specific message for the CurrentCulture (Resources is the class name for the text resources project).
Now in IdentityConfig.cs I have:
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
...
// Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
// You can write your own provider and plug it in here.
manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser>
{
MessageFormat = Resources.MESSAGE_PHONE
});
This ApplicationUserManager.Create method is called on every request and so the RegisterTwoFactorProvider. The problem is that the Resources.MESSAGE_PHONE return always the message corresponding to the server locale - it does not change when another language is set on the page.
The context parameter has the right language cookie.
So the question would be why in IdentityConfig\ApplicationManager.Create method Resource.MESSAGE_PHONE does not return the message in the proper language (as in every controller or view). The project is relatively big and maybe there is some setting for the controllers and view, which I overlook ...
How could one solve this problem?
Thanks in advance!
The answer is quite easy if you know where to look.
In my case the CurrentCulture is set in the global.asax.cs file in Application_AcquireRequestState and it is triggered after the ApplicationUserManager.Create method from the IdentityConfig.cs so in the ApplicationUserManager.Create the CurrentThread has only the default culture.
A solution would be to move the code setting the culture of the CurrentThread into the Application_BeginRequest method in the global.asax.cs which gets triggered before the ApplicationUserManager.Create method in the IdentityConfig.cs.
Full info here

Could not load settings in AuthorizeService in .net core 3 + angular application

I've been trying to set up a .net core 3 angular application with default identity authentication using the below command:
dotnet new angular -o -au Individual
I was able to build and run the application succesfully but with set of error messages as below:
Uncaught (in promise): Error: Could not load settings for 'pos_app'
Error: Could not load settings for 'pos_app'
at AuthorizeService. (authorize.service.ts:179)
when I go into the AuthorizeService to check the error, it breaks on the below line:
const response = await fetch(ApplicationPaths.ApiAuthorizationClientConfigurationUrl);
if (!response.ok) {
throw new Error(`Could not load settings for '${ApplicationName}'`);
}
I also get some error messages as below:
GET http://localhost:50059/_configuration/pos_app 404 (Not Found)
And when I hit the default Register button, i get the below error message:
Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'Identity/Account/Register'
Error: Cannot match any routes. URL Segment: 'Identity/Account/Register'
I wonder what Im missing, since I didnt change anything and the default application should work.
Please help.
I am using Mac if that makes a difference
Well. Let recheck your controller. There is a controller named OidcConfigurationController. That serves to return the configuration for front end. I got this error once i tried to refactor my code and delete that controller.
You can create new angular project with identity to get that controller code and add to your current project
public class OidcConfigurationController : Controller
{
private readonly ILogger<OidcConfigurationController> logger;
public OidcConfigurationController(IClientRequestParametersProvider clientRequestParametersProvider, ILogger<OidcConfigurationController> _logger)
{
ClientRequestParametersProvider = clientRequestParametersProvider;
logger = _logger;
}
public IClientRequestParametersProvider ClientRequestParametersProvider { get; }
[HttpGet("_configuration/{clientId}")]
public IActionResult GetClientRequestParameters([FromRoute]string clientId)
{
var parameters = ClientRequestParametersProvider.GetClientParameters(HttpContext, clientId);
return Ok(parameters);
}
}
I ran into this issue, I am new to angular so I didn't realise this immidietly.
But I had the exact same issue, the issue lies in that if you start your application with the command:
ng-serve
The backend doesn't start, just start the backend normaly and everything should work fine.
This exception occurred for me when added a filter for controllers in a blazor hosted project, specifically on Startup.cs:
services.AddControllers(config =>
{
config.Filters.Add(new AuthorizeFilter(Shared.Policies.MyPolicy()));
});
The accepted answer inspired me to fix by adding [AllowAnonymous] at OidcConfigurationController
[AllowAnonymous]
public class OidcConfigurationController : Controller

SignalR 404 error when trying to negotiate

So I am very new to SignalR, in fact I've only been using it for a couple of days now. Anyway, I am getting the error below when my application first starts up:
The code for the application in question is located in two projects, a Web API and a Single Page Application (SPA). The first one has my backend code (C#) and the second one my client-side code (AngularJS). I think the problem might be due to the fact that the projects in question run on different ports. The Web API, where my SignalR hub lives, is on port 60161 and the SPA is on 60813. My hub is declared like so:
public class ReportHub : Hub
{
public void SendReportProgress(IList<ReportProgress> reportProgress)
{
this.Clients.All.broadcastReportProgress(reportProgress);
}
public override Task OnConnected()
{
this.Clients.All.newConnection();
return base.OnConnected();
}
}
and then in my Startup.cs file for my Web API I initialize SignalR like this:
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
config.Services.Replace(typeof(IHttpControllerActivator), new NinjectFactory());
config.MessageHandlers.Add(new MessageHandler());
//set up OAuth and Cors
this.ConfigureOAuth(app);
config.EnableCors();
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
// Setting up SignalR
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
map.RunSignalR(new HubConfiguration { EnableJSONP = true });
});
//set up json formatters
FormatterConfig.RegisterFormatters(config.Formatters);
WebApiConfig.Register(config);
app.UseWebApi(config);
}
For my client-side code I use an Angular SignalR API called angular-signalr-hub (Angular-signalr-hub). The client-side follows:
angular
.module("mainApp")
.factory("reportHubService", ["$rootScope", "Hub", reportHubService]);
/// The factory function
function reportHubService($rootScope, Hub) {
var vm = this;
vm.reportName = "None";
// Setting up the SignalR hub
var hub = new Hub("reportHub", {
listeners: {
'newConnection': function(id) {
vm.reportName = "SignalR connected!";
$rootScope.$apply();
},
'broadcastReportProgress': function (reportProgress) {
vm.reportName = reportProgress.reportName;
$rootScope.$apply();
}
},
errorHandler: function(error) {
},
hubDisconnected: function () {
if (hub.connection.lastError) {
hub.connection.start();
}
},
transport: 'webSockets',
logging: true
//rootPath: 'http://localhost:60161/signalr'
});
I did some googling yesterday and one of the suggestions I came upon was to set the SignalR URL to the one of my Web API, which I did (the commented out line above). When I uncomment the line in question, that does seem to do something because if I now go to http://localhost:60161/signalr/hubs in my browser, it does show me the dynamically generated proxy file:
and when I run my application I no longer get the error above, but now it doesn't seem to connect. It gets to the negotiate line and it stops there:
I think it should look like this (this is from a SignalR tutorial I found):
In addition, none of my listeners (declared in my Angular code above) get called, so something is still now working quite right. There should be more lines in the log to the effect that connection was successfully established, etc. What could be the problem here?
UPDATE: upon further debugging i found out the problem is most likely being caused by the ProtocolVersion property being different between the client and the result here:
Because of that it seems it just exists and fails to establish connection.
I figured out what the problem was. My SignalR dependencies were out of date and because of that my client and server versions differed. All I had to do was update (via NuGet Package Manager) all SignalR dependencies to the latest version and now it works.
As a side note, SignalR was not very good at telling me what was wrong. In fact, no error message was displayed, unless of course there was some additional logging somewhere that had to be found or turned on, in addition to the logging I already had (turned on). Either way, it's either not logging certain errors or it makes it difficult to figure out how to turn on all logging. I had to go and debug the JQuery SignalR api to figure out what the problem was, which was a time consuming endeavour.

using ControllerContext.RequestContext in a web api controller

I am try to integrate SagePayMvc.dll into a ASP.NET Web API project which requires ControllerContext.RequestContext to be passed in order to form the Notification Url.
Currently I am experiencing some difficulties in achieving this, I need to pass the ControllerContext.RequestContext from this web api controller:
public class PaymentStartController : ApiController
{
private PaymentRepository paymentRepository = new PaymentRepository();
private SagePayHelper sagePayHelper = new SagePayHelper();
public Order MakePaymentInitial(Payment payment)
{
Order order = new Order();
order = sagePayHelper.MakePayment(payment, context);
paymentRepository.InsertVendorTXCode(order.VendorTxCode);
paymentRepository.InsertInitialPaymentDetails(order, payment);
return order;
}
}
I have tried to add a public ControllerContext controllerContext = new ControllerContext() below the SagePayHelper instantiation and then subsequently added var context = controllerContext.RequestContext, the problem with this none of the methods inside RequestContext are instantiated either so when SagePayMvc arrives at the point of building the Notification Url which is done inside an IUrlResolver interface an error is thrown.
Is there a way of mocking up ControllerContext.RequestContext, I have previously used RhinoMocks or would it be more prudent to revert to the way I previously implemented SagePayMvc down in the forms project (the forms project is an MVC 4 application that serializes and sends the form data to the web api).
Any advise would be much appreciated.
ASP.NET Web API uses completely different runtime components from ASP.NET MVC for representing the context and request/response messages. It looks like the API you are using is heavily tied to ASP.NET MVC, which makes it really hard to reuse in ASP.NET Web API unless you initialize the ASP.NET MVC content doing manual mappings. I think it would be easier for you to just use ASP.NET MVC for invoking that method expecting the MVC context.

No controller is found by Web API although controller exists

I created one solution with two projects: one is a class library with a Self Host Web API (created with the help of http://www.asp.net/web-api/overview/hosting-aspnet-web-api/self-host-a-web-api), the second is a windows service created with TopShelf. The purpose of this solution is to have a status report on the service with the use of Web API.
Everything works fine, but when I recreate my solution within a target solution the whole application does not work properly. The Windows Service seems to be working, but when I type localhost:8080/Test which is suppose to view OK (and it does in the separate test solution mentioned at the beginning) it throws an error (viewed as an xml):
Message: No HTTP resource was found that matches the request URI 'http://localhost:8080/Test'.
MessageDetail: No type was found that matches the controller named 'Report'.
There is a ReportController (inheriting from ApiController) in the project that contains the SelfHost but somehow it's "visible". I took a guess (a stupid guess, I believe) and moved it to the windows service project but it's also not working.
Can someone tell me what is the problem I'm facing? Why does it not see the controller if it has in a simple solution?
EDIT:
My routing looks like this:
var config = new HttpSelfHostConfiguration(String.Format("http://localhost:{0}", port));
config.Routes.MapHttpRoute("API Default", "{action}", new { controller = defaultControllerName });
where
defaultControllerName = "Report";
I am ashamed to admit it, but the reason why it didn't work lay in the controller class not having an access modifier. Making it public fixed the bug.
the Class and method must be public
public class PrintController: ApiController
{
//[HttpGet, Route("api/Print/Getp")]
public string Get()
{
var ob = new List<string>();
foreach (var item in File.ReadLines(#"c:\PrintService\pr.txt"))
{
string i = item;
ob.Add(i);
}
var json1 = JsonConvert.SerializeObject(ob);
return "ok";
}
}
and my route config is this:
_config.Routes.MapHttpRoute("DefaultHttpRoute", "api/{controller}");

Categories

Resources