How to Inject to EmailMessageService - dependency-injection

I'm having problem with injecting my service. I've a ISettingService. I'm testing registration onmy application and using email confirmation.
So, at the EmailMessageService class which is inherit from IIdentityMessageService
I'm using Unity for Ioc. I'd registered ISettingService at unity config like below
.RegisterType<ISettingService, SettingService>()
I need to inject this interface to EmailMessageService class to access settings.
Here is the EmailMessageService class
public class EmailMessagingService : IIdentityMessageService
{
private ISettingService SettingService { get; set; }
public Task SendAsync(IdentityMessage message)
{
var fromEmailAddress = ConfigurationManager
.AppSettings["IdentityFromEmailAddress"];
var text = message.Body;
var html = message.Body;
// Do whatever you want to the message
using (var msg = new MailMessage())
{
msg.From = new MailAddress(fromEmailAddress);
msg.To.Add(new MailAddress(message.Destination));
msg.Subject = message.Subject;
msg.AlternateViews.Add(
AlternateView.CreateAlternateViewFromString(
text, null, MediaTypeNames.Text.Plain)
);
msg.AlternateViews.Add(
AlternateView.CreateAlternateViewFromString(
html, null, MediaTypeNames.Text.Html)
);
// var smtpClient = new SmtpClient("smtp.whatever.net", Convert.ToInt32(587));
// var credentials = new System.Net.NetworkCredential(Keys.EmailUser, Keys.EMailKey);
// smtpClient.Credentials = credentials;
using (var smtpClient = new SmtpClient())
{
var setting = SettingService.Query().Select().FirstOrDefault();
if (setting != null)
{
if (!string.IsNullOrEmpty(setting.SmtpHost))
{
smtpClient.Host = setting.SmtpHost;
smtpClient.Port = Convert.ToInt32(setting.SmtpPort);
if (setting.IsSmtpSsl)
{
smtpClient.EnableSsl = true;
}
}
}
smtpClient.Send(msg);
}
}
return Task.FromResult(0);
}
}
EmailMessageService class instantiating at Startup.Auth
var manager =
new ApplicationUserManager(
new ApplicationUserStore(context.Get<DataContext>()));
...
manager.EmailService = new EmailMessagingService();
I cant use Constructor injecting be cause of this direct call. So i used setter injection. But im getting error like "Object reference not set to an instance of an object"
var setting = SettingService.Query().Select().FirstOrDefault();
in EmailMessageService.

O.K What exacly happend i dont know but by changing UnityMvcActivator Start method like below its fixed.
public static void Start()
{
var container = ContainerManager.GetConfiguredContainer();
UnityConfig.RegisterTypes(container);
FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First());
FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(container));
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
try
{
//http://stackoverflow.com/questions/699852/how-to-find-all-the-classes-which-implement-a-given-interface
foreach (var assembly in assemblies)
{
var instances = from t in assembly.GetTypes()
where t.GetInterfaces().Contains(typeof(IDependencyRegister))
&& t.GetConstructor(Type.EmptyTypes) != null
select Activator.CreateInstance(t) as IDependencyRegister;
foreach (var instance in instances.OrderBy(x => x.Order))
{
instance.Register(container);
}
}
}
catch (ReflectionTypeLoadException ex)
{
http://stackoverflow.com/questions/1091853/error-message-unable-to-load-one-or-more-of-the-requested-types-retrieve-the-l
System.Text.StringBuilder sb = new System.Text.StringBuilder();
foreach (Exception exSub in ex.LoaderExceptions)
{
sb.AppendLine(exSub.Message);
System.IO.FileNotFoundException exFileNotFound = exSub as System.IO.FileNotFoundException;
if (exFileNotFound != null)
{
if (!string.IsNullOrEmpty(exFileNotFound.FusionLog))
{
sb.AppendLine("Fusion Log:");
sb.AppendLine(exFileNotFound.FusionLog);
}
}
sb.AppendLine();
}
string errorMessage = sb.ToString();
throw new Exception(errorMessage, ex);
//Display or log the error based on your application.
}
// TODO: Uncomment if you want to use PerRequestLifetimeManager
// Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
}

Related

How do I programmatically add records to an Umbraco v8 form?

I'm looking to add records to an Umbraco v8 form. I know I need the form guid. Is this how I'd do it? Something like this?
public void PostFormData()
{
Guid FormGuid = new Guid("8494a8f0-94da-490e-bd61-7e658c226142");
var form = _formService.Get(FormGuid);
//place for field data into fieldDic
var fieldDic = new Dictionary<Guid, RecordField>();
var firstName = form.AllFields.First(f => f.Alias == "firstName");
var firstNameRecord = new RecordField(firstName);
firstNameRecord.Values = new List<object>() { "Mad Max" };
fieldDic.Add(firstName.Id, firstNameRecord);
var record = new Record()
{
Created = DateTime.Now,
Form = form.Id,
RecordFields = fieldDic,
State = FormState.Submitted,
};
record.RecordData = record.GenerateRecordDataAsJson();
_recordStorage.InsertRecord(record, form);
}
Here's how I do it. Note, I'm hard-coding the Record.UmbracoPageId to -1 while you might want to actually pass in the correct page ID.
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Logging;
using Umbraco.Forms.Core.Data.Storage;
using Umbraco.Forms.Core.Models;
using Umbraco.Forms.Core.Persistence.Dtos;
using Umbraco.Forms.Core.Services;
namespace myProject.Services
{
public class FormServiceComposer : IUserComposer
{
public void Compose(Composition composition)
{
composition.Register<IFormService, FormService>(Lifetime.Request);
}
}
public interface IFormService
{
void InsertFormData(Guid formGuid, object formModel, string ipAddress);
}
public class FormService : IFormService
{
private readonly ILogger _logger;
private readonly Umbraco.Forms.Core.Services.IFormService _formService;
private readonly IRecordStorage _recordStorage;
private readonly IRecordFieldStorage _recordFieldStorage;
private readonly IWorkflowService _workflowService;
public FormService(ILogger logger, Umbraco.Forms.Core.Services.IFormService formService, IRecordStorage recordStorage, IRecordFieldStorage recordFieldStorage, IWorkflowService workflowService)
{
_logger = logger;
_formService = formService;
_recordStorage = recordStorage;
_recordFieldStorage = recordFieldStorage;
_workflowService = workflowService;
}
#region IFormService
public void InsertFormData(Guid formGuid, object formModel, string ipAddress)
{
try
{
Form form = _formService.GetForm(formGuid);
Record record = new Record();
foreach (Field field in form.AllFields)
{
string caption = CleanCaption(field.Caption);
if (formModel.GetType().GetProperty(caption) == null) continue;
var propertyValue = formModel.GetType().GetProperty(caption).GetValue(formModel, null);
if (propertyValue != null)
{
List<object> values = ExtractValues(propertyValue);
RecordField recordField = new RecordField
{
Alias = field.Alias,
FieldId = field.Id,
Field = field,
Key = Guid.NewGuid(),
Record = record.Id,
Values = values
};
_recordFieldStorage.InsertRecordField(recordField);
record.RecordFields.Add(recordField.Key, recordField);
}
}
record.Form = formGuid;
record.IP = ipAddress;
record.UmbracoPageId = -1;
record.State = Umbraco.Forms.Core.Enums.FormState.Approved;
record.RecordData = record.GenerateRecordDataAsJson();
_recordStorage.InsertRecord(record, form);
_recordStorage.DisposeIfDisposable();
}
catch (Exception ex)
{
_logger.Error<FormService>(ex, "Failed inserting Umbraco Forms data for {formGuid}");
}
}
#endregion IFormService
#region Private
private string CleanCaption(string caption)
{
Regex rgx = new Regex("[^a-zA-Z0-9 -]");
return rgx.Replace(caption.Trim().Replace(" ", ""), "");
}
private List<object> ExtractValues(object propertyValue)
{
List<object> result = new List<object>();
if (propertyValue is string == false && propertyValue.GetType().GetGenericTypeDefinition() == typeof(List<>))
{
IEnumerable<object> _propertyValue = (IEnumerable<object>)propertyValue;
if (_propertyValue.Any())
{
if (_propertyValue.First().GetType().GetProperties().Count() > 1)
{
JArray _properties = JArray.Parse(JsonConvert.SerializeObject(propertyValue));
foreach (JToken item in _properties)
{
string _value = string.Empty;
foreach (var _property in _propertyValue.First().GetType().GetProperties())
{
string _key = _property.Name;
_value = _value + (_value == "" ? "" : " - ") + item[_key].ToString();
}
result.Add(_value);
}
}
else
{
string _key = _propertyValue.First().GetType().GetProperties().First().Name;
JArray _properties = JArray.Parse(JsonConvert.SerializeObject(propertyValue));
foreach (JToken item in _properties)
{
result.Add(item[_key].ToString());
}
}
}
}
else
{
result.Add(propertyValue);
}
return result;
}
#endregion Private
}
}

Serilog stops logging events

I have created a Serilog sink that talks to a web service which persists log messages to a database. It works most of the time. Even in cases where there is an exception calling the web service it will log to the Selflog file. However, However, periodically it simply stops logging either to our custom web service or to the self log file and after it stops logging it never begins logging anywhere else. This is being executed in a windows service and I have to stop and restart the windows service before it begins logging again. A typical exception that i might get from the web service call is: "Task was cancelled". This would be caused because the webservice does not respond within the configured timeout period. As I said normally it will properly write the events to the selflog file. Only periodically will it just stop logging everywhere. I should also say that the volume of logs being generated is very high.
This is a dnx project and here is a portion of the project.json file:
"dependencies": {
"Newtonsoft.Json": "8.0.2",
"Serilog.Sinks.PeriodicBatching": "2.0.0",
"Serilog": "2.0.0-beta-465",
"Serilog.Extensions.Logging": "1.0.0-rc1-final-10092",
"JA.AppCentral.Logging.Contracts": "0.1.0-alpha1-*",
"FluentAssertions": "4.2.2",
"Microsoft.Extensions.Configuration": "1.0.0-rc1-final",
"Microsoft.AspNet.WebApi.Client": "4.0.30506"
}
I have included relevant portions of the sink class. It inherits from periodic batching sink.
The code used to configure the Selflog follows:
FileStream fs = new FileStream(selfLogFilePath, fileMode, FileAccess.Write);
StreamWriter sw = new StreamWriter(fs);
Serilog.Debugging.SelfLog.Out = TextWriter.Synchronized(sw);
Here is the sink code:enter code here
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Serilog;
using System.Net.Http;
using Serilog.Core;
using Serilog.Events;
using System.Net.Http.Headers;
using System.IO;
using Serilog.Formatting.Json;
using Serilog.Debugging;
using Newtonsoft.Json;
using JA.AppCentral.Logging.Contracts;
using Microsoft.Extensions.Configuration;
using Serilog.Sinks.PeriodicBatching;
using System.Diagnostics;
using System.Threading;
namespace JA.AppCentral.Logging
{
public class AppCentralSink: Serilog.Sinks.PeriodicBatching.PeriodicBatchingSink
{
readonly HttpClient _httpClient;
LoggingLevelSwitch _levelControlSwitch;
const string BulkAddUri = "api/appLogging/bulkAdd";
private Uri _baseUri;
private string _baseUriPath;
readonly long? _eventBodyLimitBytes = 1000000;
static readonly TimeSpan RequiredLevelCheckInterval = TimeSpan.FromSeconds(10);
private TimeSpan _timeout = TimeSpan.FromMinutes(1);
private bool _saveMessageTemplate;
private int eventsCount;
private LoggingRepositoryServiceResponse _logServiceResponse;
private int _totalInsertedRecords;
public event EventHandler<ResponseEventArgs> ResponseReceived = delegate { };
DateTime _nextRequiredLevelCheckUtc = DateTime.Now.Add(RequiredLevelCheckInterval);
private int osId;
private string server;
private string username;
private int threadId;
private string appcode;
/// <summary>
/// Overloaded constructor, to pass AppSettings via IConfiguration , instead of separate parameters
/// </summary>
/// <param name="config"></param>
public AppCentralSink(IConfiguration config)
: base(Convert.ToInt32(GetConfigParams(config)["BatchSizeLimit"]),
TimeSpan.FromSeconds(Convert.ToDouble(GetConfigParams(config)["BatchEmitIntervalSeconds"])))
{
Dictionary<string, string> appSettingDict = GetConfigParams(config);
long tempLongVal;
long? eventBodyLimitBytes = long.TryParse(appSettingDict["EventBodyMaxSizeBytes"], out tempLongVal) ? tempLongVal : (long?)null;
if (eventBodyLimitBytes != null)
_eventBodyLimitBytes = eventBodyLimitBytes;
bool saveMessageTemplate = Convert.ToBoolean(appSettingDict["LogMessageTemplate"]);
if (saveMessageTemplate != false)
_saveMessageTemplate = saveMessageTemplate;
string serverUrl = appSettingDict["Url"];
//baseUri = "http://localhost:49774/";
if (!serverUrl.EndsWith("/"))
serverUrl += "/";
_baseUriPath = serverUrl;
_baseUri = new Uri(serverUrl);
TimeSpan timeout = TimeSpan.FromSeconds(Convert.ToDouble(appSettingDict["WebRequestTimeoutSeconds"]));
if (timeout != default(TimeSpan))
_timeout = timeout;
//Default Authentication via http client handler
HttpClientHandler handler = new HttpClientHandler()
{
PreAuthenticate = true,
UseDefaultCredentials = true
};
_httpClient = new HttpClient(handler);
_httpClient.BaseAddress = _baseUri;
_httpClient.DefaultRequestHeaders.Accept.Clear();
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
_httpClient.Timeout = _timeout;
//Init Context properties
OsId = Process.GetCurrentProcess().Id;
Server = Environment.MachineName;
Username = Environment.UserName;
ThreadId = Thread.CurrentThread.ManagedThreadId;
Appcode = config["JA:AppCatalog:AppCode"];
}
private static Dictionary<string,string> GetConfigParams(IConfiguration config)
{
Dictionary<string, string> appSettings = new Dictionary<string, string>();
var SerilogSection = config.GetSection("AppCentralLogging");
appSettings.Add("Url", SerilogSection["Url"]);
appSettings.Add("BatchSizeLimit", SerilogSection["BatchSizeLimit"]);
appSettings.Add("BatchEmitIntervalSeconds", SerilogSection["BatchEmitIntervalSeconds"]);
appSettings.Add("EventBodyMaxSizeBytes", SerilogSection["EventBodyMaxSizeBytes"]);
appSettings.Add("LogMessageTemplate", SerilogSection["LogMessageTemplate"]);
appSettings.Add("WebRequestTimeoutSeconds", SerilogSection["WebRequestTimeoutSeconds"]);
appSettings.Add("SelfLogFileLocationAndPrefix", config["Serilog:SelfLogFileLocationAndPrefix"]);
return appSettings;
}
// The sink must emit at least one event on startup, and the server be
// configured to set a specific level, before background level checks will be performed.
protected override void OnEmptyBatch()
{
if (_levelControlSwitch != null &&
_nextRequiredLevelCheckUtc < DateTime.Now)
{
EmitBatch(Enumerable.Empty<LogEvent>());
}
}
protected override async Task EmitBatchAsync(IEnumerable<LogEvent> events)
{
_nextRequiredLevelCheckUtc = DateTime.Now.Add(RequiredLevelCheckInterval);
var formatter = new JsonFormatter();
List<LogEntry> logEntriesList = new List<LogEntry>();
try
{
foreach (var logEvent in events)
{
EventsCount++;
LogEntry jaLogEvent = ConvertToLogEntry(logEvent);
if (_eventBodyLimitBytes.HasValue)
{
var scratch = new StringWriter();
formatter.Format(logEvent, scratch);
var buffered = scratch.ToString();
if (Encoding.UTF8.GetByteCount(buffered) > _eventBodyLimitBytes.Value)
{
SelfLog.WriteLine("Event JSON representation exceeds the byte size limit of {0} set for this sink and will be dropped; data: {1}", _eventBodyLimitBytes, buffered);
}
else
{
logEntriesList.Add(jaLogEvent);
}
}
else
{
logEntriesList.Add(jaLogEvent);
}
}
var result = await _httpClient.PostAsJsonAsync(BulkAddUri, logEntriesList);
if (!result.IsSuccessStatusCode)
{
try
{
var error = await result.Content.ReadAsStringAsync();
var responseExcep = new Exception(error);
throw responseExcep;
}
catch (Exception e)
{
SelfLog.WriteLine("FailedEvents: " + GetEventsAsString(events));
throw new Exception("Error calling Logging Web Service: status code: " + result.StatusCode +
" reason: " + result.ReasonPhrase + " excep: " + e.ToString());
}
}
_logServiceResponse = await result.Content.ReadAsAsync<LoggingRepositoryServiceResponse>();
if (_logServiceResponse.ResponseException != null)
{
SelfLog.WriteLine("FailedEvents: " + GetEventsAsString(events));
SelfLog.WriteLine(_logServiceResponse.ResponseMessage);
throw new Exception("Error calling Logging Web Service: " +
_logServiceResponse.ResponseMessage);
}
_totalInsertedRecords = _totalInsertedRecords + _logServiceResponse.NumRecordsInserted;
ResponseReceived(this, new ResponseEventArgs(result));
}
catch (Exception e)
{
SelfLog.WriteLine("Error processing log batch, excep: " + e.ToString());
SelfLogEvents(events);
throw;
}
}
private void SelfLogEvents(IEnumerable<LogEvent> events)
{
SelfLog.WriteLine("Failed to write following log events:");
foreach (var e in events)
{
SelfLog.WriteLine($" Event: " + e.RenderMessage());
}
}
private string GetEventsAsString(IEnumerable<LogEvent> events)
{
string eventsResult = string.Empty;
foreach(LogEvent le in events)
{
eventsResult += "[" + le.RenderMessage() + "]";
}
return eventsResult;
}
private LogEntry ConvertToLogEntry(LogEvent logEvent)
{
string propertiesString = JsonConvert.SerializeObject(logEvent.Properties);
string messageTemplate = _saveMessageTemplate == true ? logEvent.MessageTemplate.Text : string.Empty;
//Append Exception to the message if it's not null
string logEventMessage = logEvent.RenderMessage();
if (logEvent.Exception != null)
{
logEventMessage = logEventMessage + " Exception: " + logEvent.Exception.ToString();
}
LogEntry logEntry = new LogEntry("AppCode", "Action", logEvent.Level.ToString(), messageTemplate,
logEventMessage, propertiesString,
logEvent.Timestamp);
//Append additional properties
if (String.IsNullOrEmpty(Appcode))
{
logEntry.AppCode = logEvent.Properties.Keys.Contains("appcode") ? logEvent.Properties["appcode"].ToString().Replace("\"", "") : string.Empty;
logEntry.OsPId = logEvent.Properties.Keys.Contains("os_pid") ? logEvent.Properties["os_pid"].ToString().Replace("\"", "") : string.Empty;
logEntry.ThreadId = logEvent.Properties.Keys.Contains("thread_id") ? logEvent.Properties["thread_id"].ToString().Replace("\"", "") : string.Empty;
logEntry.Server = logEvent.Properties.Keys.Contains("server") ? logEvent.Properties["server"].ToString().Replace("\"", "") : string.Empty;
logEntry.Username = logEvent.Properties.Keys.Contains("username") ? logEvent.Properties["username"].ToString().Replace("\"", "") : string.Empty;
}
else
{
logEntry.AppCode = Appcode;
logEntry.OsPId = OsId.ToString();
logEntry.ThreadId = ThreadId.ToString();
logEntry.Server = Server;
logEntry.Username = Username;
}
logEntry.SessionId = logEvent.Properties.Keys.Contains("session_id") ? logEvent.Properties["session_id"].ToString().Replace("\"", "") : string.Empty;
logEntry.Action = logEvent.Properties.Keys.Contains("action") ? logEvent.Properties["action"].ToString().Replace("\"", "") : string.Empty;
//Append SourceContext
//Append SourceContext
LogEventPropertyValue propertyValue;
if (logEvent.Properties.TryGetValue("SourceContext", out propertyValue))
{
logEntry.SourceContext = propertyValue.ToString().Trim(new[] { '"' });
}
return logEntry;
}
public int EventsCount
{
get
{
return eventsCount;
}
set
{
eventsCount = value;
}
}
public LoggingRepositoryServiceResponse LogServiceResponse
{
get
{
return _logServiceResponse;
}
set
{
_logServiceResponse = value;
}
}
public int TotalInsertedRecords
{
get
{
return _totalInsertedRecords;
}
set
{
_totalInsertedRecords = value;
}
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
_httpClient.Dispose();
}
public HttpClient HttpClient
{
get { return _httpClient; }
}
}
public class ResponseEventArgs : EventArgs
{
public ResponseEventArgs(HttpResponseMessage response)
{
Response = response;
}
public HttpResponseMessage Response { get; }
}
}

Setup Owin for Custom UserManager in Asp.Net Identity

I'm using neo4j.AspNet.Identity for authentication of my website and I have the following class to connect to database that name is GraphClientWrapper and Neo4jUserManager.The GraphClientWrapper class is:
using System;
using Neo4jClient;
/// <summary>A wrapper class to allow the GraphClient to be used within the OWIN framework (must implement <see cref="IDisposable"/>)</summary>
public class GraphClientWrapper : IDisposable
{
public GraphClientWrapper(IGraphClient graphClient)
{
GraphClient = graphClient;
}
public IGraphClient GraphClient { get; set; }
public void Dispose()
{
}
}
and Neo4jUserStore class code is
public class Neo4jUserManager : UserManager<ApplicationUser>
{
public Neo4jUserManager(IUserStore<ApplicationUser> store)
: base(store)
{
}
public async Task SetLastLogin()
{
// Store.FindByIdAsync()
}
public static Neo4jUserManager Create(IdentityFactoryOptions<Neo4jUserManager> options, IOwinContext context)
{
var graphClientWrapper = context.Get<GraphClientWrapper>();
var manager = new Neo4jUserManager(new Neo4jUserStore<ApplicationUser>(graphClientWrapper.GraphClient));
// Configure validation logic for usernames
// manager.UserValidator = new UserValidator<Neo4jUser>(manager)
// {
// AllowOnlyAlphanumericUserNames = false,
// RequireUniqueEmail = true
// };
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true
};
// Configure user lockout defaults
manager.UserLockoutEnabledByDefault = false;
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
manager.MaxFailedAccessAttemptsBeforeLockout = 5;
// 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<Neo4jUser>
// {
// MessageFormat = "Your security code is {0}"
// });
// manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<Neo4jUser>
// {
// Subject = "Security Code",
// BodyFormat = "Your security code is {0}"
// });
// manager.EmailService = new EmailService();
// manager.SmsService = new SmsService();
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}
return manager;
}
}
but for connecting to the database,I should follow these codes
var gc = new GraphClient(new Uri("http://localhost.:7474/db/data"));
gc.Connect();
var graphClientWrapper = new GraphClientWrapper(gc);
var manager = new Neo4jUserManager(new Neo4jUserStore<ApplicationUser>(graphClientWrapper.GraphClient));
and the problem is I don't know how to setup owin to use my custom UserManager. Can anybody help to setup owin?

AuthorizationState cannot be serialized because it does not have a parameterless constructor

The implementation for authorization state in the source indicates that the authorization state should be serializable, but when I try to serialize the authorization state to store in my authentication ticket, I get an error saying that the implementation needs a parameterless constructor.
Snipped from the referenced source:
[Serializable]
public class AuthorizationState : IAuthorizationState {
...
public AuthorizationState(IEnumerable<string> scopes = null) {
How I'm getting the state:
var Authorization = Client.ProcessUserAuthorization();
How I'm trying to serialize the state:
public string Serialize(IAuthorizationState objectInstance)
{
var serializer = new XmlSerializer(objectInstance.GetType());
var sb = new StringBuilder();
using (TextWriter writer = new StringWriter(sb))
{
serializer.Serialize(writer, objectInstance);
}
return sb.ToString();
}
I ran a quick console app
class Program
{
static void Main(string[] args)
{
var can = new CanSerialize();
var cant = new CantSerialize();
var ser1 = can.Serialize();
var ser2 = cant.Serialize();
}
}
[Serializable]
public class CantSerialize
{
public int id { get; set; }
public CantSerialize(int ID = 1)
{
id = ID;
}
public string Serialize()
{
var serializer = new XmlSerializer(this.GetType());
var sb = new StringBuilder();
using (TextWriter writer = new StringWriter(sb))
{
serializer.Serialize(writer, this);
}
return sb.ToString();
}
}
[Serializable]
public class CanSerialize
{
public int id { get; set; }
private CanSerialize()
{
id = 1;
}
public CanSerialize(int ID = 1)
{
id = ID;
}
public string Serialize()
{
var serializer = new XmlSerializer(this.GetType());
var sb = new StringBuilder();
using (TextWriter writer = new StringWriter(sb))
{
serializer.Serialize(writer, this);
}
return sb.ToString();
}
}
Can the implementation have a default parameterless constructor? As the sample shows, it can be private if there is concern about having a public ctor.
In the meantime, I'm going to create a data transfer object to ferry the information back and forth between my authorization token and the state.
EDIT:
I've found that the JSON.net conversion works well:
var a = JsonConvert.SerializeObject(Authorization);
var b = JsonConvert.DeserializeObject(a, typeof(AuthorizationState));
I've found that the JSON.net conversion works well:
var a = JsonConvert.SerializeObject(Authorization);
var b = JsonConvert.DeserializeObject(a, typeof(AuthorizationState));

Cannot use ComboBox SelectedItem as BindingSource for cascaded ComboBox

I have 2 ComboBoxes on my form. I create the bindings as follows:
TestClass myclass = new TestClass("Instruments");
myclass.Add(instr1 = new TestClass("INSTR1"));
myclass.Add(instr2 = new TestClass("INSTR2"));
myclass.Add(instr3 = new TestClass("INSTR3"));
myclass.Add(instr4 = new TestClass("INSTR4"));
instr1.Add(app1 = new TestClass("app1"));
instr1.Add(app2 = new TestClass("app2"));
instr1.Add(app3 = new TestClass("app3"));
instr1.Add(app4 = new TestClass("app4"));
instr2.Add(app5 = new TestClass("app5"));
instr2.Add(app6 = new TestClass("app6"));
instr2.Add(app7 = new TestClass("app7"));
instr2.Add(app8 = new TestClass("app8"));
mysource = new BindingSource(myclass, null);
selectedComboBox1.DataSource = mysource;
selectedComboBox1.DisplayMember = "NAME";
mysource2 = new BindingSource(selectedComboBox1, "SelectedItem");
selectedComboBox2.DataSource = mysource2;
selectedComboBox2.DisplayMember = "NAME";
The class used for the binding looks as follows
class TestClass : BindingList<TestClass>, INotifyPropertyChanged
{
public event RunTestChanged RunTestChangedEventHandler;
public TestClass()
{
this.test = "";
this.name = "";
this.runTest = true;
}
public TestClass(string name)
{
this.test = "";
this.name = name;
this.runTest = true;
}
public TestClass LIST
{
get
{
return this;
}
}
public string NAME
{
get
{
return this.name;
}
set
{
this.name = value;
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs("NAME"));
}
}
}
public string TEST
{
get
{
return this.test;
}
set
{
this.test = value;
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs("TEST"));
}
}
}
public bool RUNTEST
{
get
{
return runTest;
}
set
{
runTest = value;
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs("RUNTEST"));
}
RunTestArgs myargs = new RunTestArgs(value);
if (RunTestChangedEventHandler != null)
{
RunTestChangedEventHandler(this, myargs);
}
}
}
private bool runTest;
private string name;
private string test;
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
}
when the form first loads the 2 comboboxes are filled as they should be with the expected items. However, if i change an item in selectedComboBox1, the items in selectedComboBox2 aren't updated. I know that I can subscribe to the selectedComboBox1 SelectedIndexChanged event and then rebind the DataSource on selectedComboBox2 and everything will work as expected.
For example:
void selectedComboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
mysource2.DataSource = selectedComboBox1.SelectedItem;
mysource2.DataMember = null;
}
Another alternative that works is to perform the databinding as follows:
mysource = new BindingSource(myclass, null);
mysource2 = new BindingSource(mysource, "LIST");
mysource3 = new BindingSource(mysource2, "LIST");
selectedComboBox1.DataSource = mysource;
selectedComboBox1.DisplayMember = "NAME";
selectedComboBox2.DataSource = mysource2;
selectedComboBox2.DisplayMember = "NAME";
However I wanted to know if there was a way to avoid having to subscribe to the event or performing the databinding in a different manner and just have the 2nd ComboBox be updated via the BindingSource using the SelectedItem property. In the end I'm curious to know how to get the BindingSource to be updated via the SelectedItem databinding and if it's not possible what is preventing it from working.
Thank you for your help.
i have the same issue and got resolved by binding Name to SelectedValue of combobox and set ValueMember to be "NAME" property
selectedComboBox1.DisplayMember = "NAME";
selectedComboBox1.ValueMember = "NAME";

Resources