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

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));

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
}
}

HttpClient is sending NULL in web Api in mvc5

HttpClient is sending null values to controller while post and my code is here please help me
....................
using (HttpClient client=new HttpClient())
{
var parameters = ConvertToDictionary(tc);
client.BaseAddress = new Uri($"http://localhost:9797/");
var json = JsonConvert.SerializeObject(tc);
var data = new StringContent(content: json,encoding: Encoding.UTF8,mediaType: "application/json");
var response = client.PostAsync(api_url, data).GetAwaiter().GetResult();
var k = JsonConvert.DeserializeObject<Api>(response.Content.ReadAsStringAsync().GetAwaiter().GetResult());
}
Thanks in advance
Try to use # insted of $ in client.BaseAddress. And check if tc object is not null.
I used Your code like this:
class Program
{
static void Main(string[] args)
{
using (HttpClient client=new HttpClient())
{
client.BaseAddress = new Uri(#"http://localhost:61737/api/presidents");
var json = JsonConvert.SerializeObject(new { name = "name", value = "value" });
var data = new StringContent(content: json,encoding: Encoding.UTF8,mediaType: "application/json");
var response = client.PostAsync(#"http://localhost:61737/api/presidents/post", data).GetAwaiter().GetResult();
var k = (response.Content.ReadAsStringAsync().GetAwaiter().GetResult());
}
}
}
And controller looks like this:
[RoutePrefix("api/presidents")]
public class PresidentsController : ApiController
{
public class oooo
{
public string Name { get; set; }
public string Value { get; set; }
}
[Route("post")]
public IHttpActionResult Post(oooo o)
{
return Ok(o);
}
}
and everything is working.

BreezeSharp Attach Property key not found

I'm implementing an application with Breezesharp. I ran into a issue when insert the entity in the EntityManager. The error is:
There are no KeyProperties yet defined on EntityType: 'TransportReceipt:#Business.DomainModels'
I already faced this error with my first entity type "Customer" and implement a mismatching approach as suggested here. In that case I made the get operation against my WebApi with success. But now I'm creating the TransportReceipt entity inside my application.
Mapping mismatch fix
public static class ExtendMap
{
private static bool? executed;
public static void Execute(MetadataStore metadataStore) {
if (ExtendMap.executed == true)
{
return;
}
var customerBuilder = new EntityTypeBuilder<Customer>(metadataStore);
customerBuilder.DataProperty(t => t.id).IsPartOfKey().IsAutoIncrementing();
var transportReceiptBuilder = new EntityTypeBuilder<TransportReceipt>(metadataStore);
transportReceiptBuilder.DataProperty(t => t.id).IsPartOfKey().IsAutoIncrementing();
var transportReceiptAttachmentBuilder = new EntityTypeBuilder<TransportReceiptAttachment>(metadataStore);
transportReceiptAttachmentBuilder.DataProperty(t => t.id).IsPartOfKey().IsAutoIncrementing();
var uploadedFileBuilder = new EntityTypeBuilder<UploadedFile>(metadataStore);
uploadedFileBuilder.DataProperty(t => t.id).IsPartOfKey().IsAutoIncrementing();
ExtendMap.executed = true;
}
}
My base dataservice core code
public abstract class SimpleBaseDataService
{
public static string Metadata { get; protected set; }
public static MetadataStore MetadataStore { get; protected set; }
public string EntityName { get; protected set; }
public string EntityResourceName { get; protected set; }
public EntityManager EntityManager { get; set; }
public string DefaultTargetMethod { get; protected set; }
static SimpleBaseDataService()
{
try
{
var metadata = GetMetadata();
metadata.Wait();
Metadata = metadata.Result;
MetadataStore = BuildMetadataStore();
}
catch (Exception ex)
{
var b = 0;
}
}
public SimpleBaseDataService(Type entityType, string resourceName, string targetMethod = null)
{
var modelType = typeof(Customer);
Configuration.Instance.ProbeAssemblies(ConstantsFactory.BusinessAssembly);
try
{
this.EntityName = entityType.FullName;
this.EntityResourceName = resourceName;
this.DefaultTargetMethod = (string.IsNullOrWhiteSpace(targetMethod) ? "GetAllMobile" : targetMethod);
var dataService = new DataService($"{ConstantsFactory.Get.BreezeHostUrl}{this.EntityResourceName}", new CustomHttpClient());
dataService.HasServerMetadata = false;
this.EntityManager = new EntityManager(dataService, SimpleBaseDataService.MetadataStore);
this.EntityManager.MetadataStore.AllowedMetadataMismatchTypes = MetadataMismatchTypes.AllAllowable;
// Attach an anonymous handler to the MetadataMismatch event
this.EntityManager.MetadataStore.MetadataMismatch += (s, e) =>
{
// Log the mismatch
var message = string.Format("{0} : Type = {1}, Property = {2}, Allow = {3}",
e.MetadataMismatchType, e.StructuralTypeName, e.PropertyName, e.Allow);
// Disallow missing navigation properties on the TodoItem entity type
if (e.MetadataMismatchType == MetadataMismatchTypes.MissingCLRNavigationProperty &&
e.StructuralTypeName.StartsWith("TodoItem"))
{
e.Allow = false;
}
};
}
catch (Exception ex)
{
var b = 0;
}
}
}
This is who I'm trying to add the new entity
//DataService snippet
public void AttachEntity(T entity)
{
this.EntityManager.AttachEntity(entity, EntityState.Added);
}
//Business
this.TransportReceipt = new TransportReceipt { id = Guid.NewGuid(), date = DateTime.Now, customerId = Customer.id/*, customer = this.Customer*/ };
this.Attachments = new List<TransportReceiptAttachment>();
this.TransportReceipt.attachments = this.Attachments;
TransportReceiptDataService.AttachEntity(this.TransportReceipt);
When I try to add add the entity to the EntityManager, I can see the custom mapping for all my entity classes.
So my question is what I'm doing wrong.
Ok. That was weird.
I changed the mapping for a new fake int property and works. I'll test the entire save flow soon and I'll share the result here.
Update
I moved on and start removing Breezesharp. The Breezesharp project is no up-to-date and doesn't have good integration with Xamarin. I'll appreciate any comment with your experience.

Unique constraint with data annotation

I'm using the System.ComponentModel.DataAnnotations namespace to validate my domain classes. How can I create a custom attribute to validate the uniqueness of a property regardless of the database (through some interface, for example)?
This is the solution I came up with for this situation, it simply checks the table for a record with a different id that has the same value for the property being validated. It assumes that you will be using LinqToSQL, and that any table on which this kind of validation is required has a single ID column.
I'd also put a unique constraint on the underlying table in the database. This attribute allows me to put a nice error message on the form and associate it with the appropriate property.
public class UniqueAttribute : ValidationAttribute
{
public Func<DataContext> GetDataContext { get; private set; }
public string IDProperty { get; private set; }
public string Message { get; private set; }
public UniqueAttribute(Type dataContextType, string idProperty, string message)
{
IDProperty = idProperty;
Message = message;
GetDataContext = () => (DataContext)Activator.CreateInstance(dataContextType);
}
public UniqueAttribute(Type dataContextType, string idProperty, string message, string connectionString)
{
IDProperty = idProperty;
Message = message;
GetDataContext = () => (DataContext)Activator.CreateInstance(dataContextType, new object[] { connectionString });
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var idProperty = validationContext.ObjectType.GetProperty(IDProperty);
var idType = idProperty.PropertyType;
var id = idProperty.GetValue(validationContext.ObjectInstance, null);
// Unsightly hack due to validationContext.MemberName being null :(
var memberName = validationContext.ObjectType.GetProperties()
.Where(p => p.GetCustomAttributes(false).OfType<DisplayAttribute>().Any(a => a.Name == validationContext.DisplayName))
.Select(p => p.Name)
.FirstOrDefault();
if (string.IsNullOrEmpty(memberName))
{
memberName = validationContext.DisplayName;
}
// End of hack
var validateeProperty = validationContext.ObjectType.GetProperty(memberName);
var validateeType = validateeProperty.PropertyType;
var validatee = validateeProperty.GetValue(validationContext.ObjectInstance, null);
var idParameter = Expression.Constant(id, idType);
var validateeParameter = Expression.Constant(validatee, validateeType);
var objectParameter = Expression.Parameter(validationContext.ObjectType, "o");
var objectIDProperty = Expression.Property(objectParameter, idProperty);
var objectValidateeProperty = Expression.Property(objectParameter, validateeProperty);
var idCheck = Expression.NotEqual(objectIDProperty, idParameter);
var validateeCheck = Expression.Equal(objectValidateeProperty, validateeParameter);
var compositeCheck = Expression.And(idCheck, validateeCheck);
var lambda = Expression.Lambda(compositeCheck, objectParameter);
var countMethod = typeof(Queryable).GetMethods().Single(m => m.Name == "Count" && m.GetParameters().Length == 2);
var genericCountMethod = countMethod.MakeGenericMethod(validationContext.ObjectType);
using (var context = GetDataContext())
{
var table = context.GetTable(validationContext.ObjectType) as IQueryable<Models.Group>;
var count = (int)genericCountMethod.Invoke(null, new object[] { table, lambda });
if (count > 0)
{
return new ValidationResult(Message);
}
}
return null;
}
}
Example usage:
[MetadataType(typeof(UserMetadata))]
public partial class Group : IDatabaseRecord
{
public class UserMetadata
{
[Required(ErrorMessage = "Name is required")]
[StringLength(255, ErrorMessage = "Name must be under 255 characters")]
[Unique(typeof(MyDataContext), "GroupID", "Name must be unique")]
public string Name { get; set; }
}
}
just do something like this on your model
[StringLength(100)]
[Index("IX_EntidadCodigoHabilitacion", IsUnique = true)]
public string CodigoHabilitacion { get; set; }
If I am understanding you properly, you should be able to create a custom ValidationAttribute and get a context to your repository through a custom factory.
Validator:
using System.ComponentModel.DataAnnotations;
public class DBUniqueAttribute : ValidationAttribute
{
private IRepository Repository{ get; set;}
public DBUniqueAttribute()
{
this.Repository = MyRepositoryFactory.Create();
}
public override bool IsValid(object value)
{
string stringValue = Convert.ToString(value, CultureInfo.CurrentCulture);
return Repository.IsUnique(stringValue);
}
}
You would have an IRepository interface with an IsUnique() method. The MyRepositoryFactory would have a static method called Create() which would create the concrete Repository necessary for your database. If the database type changes, you only need to update the Factory to return a new Repository for your new database.
I love #daveb's solution. Unfortunately, three years later it required some pretty heavy modification for me. Here's his solution updated for EF6. Hopefully will save someone an hour or so of fiddling.
public class UniqueAttribute : ValidationAttribute
{
public UniqueAttribute(string idProperty, string message)
{
IdProperty = idProperty;
Message = message;
}
[Inject]
public DataContext DataContext { get; set; }
private string IdProperty { get; set; }
private string Message { get; set; }
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var objectType = validationContext.ObjectType;
if (objectType.Namespace == "System.Data.Entity.DynamicProxies")
{
objectType = objectType.BaseType;
}
var idProperty = objectType.GetProperty(IdProperty);
var idType = idProperty.PropertyType;
var id = idProperty.GetValue(validationContext.ObjectInstance, null);
var memberName = validationContext.MemberName;
var validateeProperty = objectType.GetProperty(memberName);
var validateeType = validateeProperty.PropertyType;
var validatee = validateeProperty.GetValue(validationContext.ObjectInstance, null);
var idParameter = Expression.Constant(id, idType);
var validateeParameter = Expression.Constant(validatee, validateeType);
var objectParameter = Expression.Parameter(objectType, "o");
var objectIdProperty = Expression.Property(objectParameter, idProperty);
var objectValidateeProperty = Expression.Property(objectParameter, validateeProperty);
var idCheck = Expression.NotEqual(objectIdProperty, idParameter);
var validateeCheck = Expression.Equal(objectValidateeProperty, validateeParameter);
var compositeCheck = Expression.And(idCheck, validateeCheck);
var lambda = Expression.Lambda(compositeCheck, objectParameter);
var countMethod = typeof(Queryable).GetMethods().Single(m => m.Name == "Count" && m.GetParameters().Length == 2);
var genericCountMethod = countMethod.MakeGenericMethod(objectType);
var table = DataContext.Set(objectType);
var count = (int)genericCountMethod.Invoke(null, new object[] { table, lambda });
if (count > 0)
{
return new ValidationResult(Message);
}
return null;
}
}

Mocking a Customer SessionHandler Object in ASP.NET MVC for Unittests with Rhino Mocks

I currently use the following approach to create a strongly typed object representing session variables.
public abstract class SessionController : Controller
{
private const string SESSION_NAME = "UserSession";
public SessionData SessionData
{
get
{
SessionData sessionData = (SessionData)Session[SESSION_NAME];
if (sessionData != null)
{
return sessionData;
}
else
{
sessionData = new SessionData();
Session[SESSION_NAME] = sessionData;
return sessionData;
}
}
set
{
Session[SESSION_NAME] = value;
}
}
}
SessionData is a simple object like for example
[Serializable]
public class SessionData
{
public String SessionId { get; set; }
public Int64 UserId { get; set; }
public String NameOfUser { get; set; }
}
When creating a new Controller I derivate it from the SessionController so that I have strongley typed access to my SessionData. For example
public CityController : SessionController
{
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Index()
{
ViewData.Model = _cityService.GetAll(SessionData.UserId);
return View("Index");
}
}
So, I am struggling at the moment to get this approached covered by a unittest. A shortened version of what I have tried is the following snippet
[SetUp]
public void SetUp()
{
mocks = new MockRepository();
_cityService = MockRepository.GenerateStub<ICityService>();
_sesssionData = new SessionData { UserId = 1, SessionId = "1" };
// First Approach
controller = new CityController(_cityService);
controller.Expect(p => p.SessionData).Return(_sesssionData);
// Second Approach
cctx = MockRepository.GenerateStub<ControllerContext>();
cctx.Expect(p=>p.HttpContext.Session["UserSession"] as SessionData).Return(_sesssionData);
controller.ControllerContext = cctx;
}
Has anyone a tip on how to get this problem solved?
If you make your SessionData property virtual then your first approach could work:
// Arrange
var mocks = new MockRepository();
var cityService = MockRepository.GenerateStub<ICityService>();
var sesssionData = new SessionData { UserId = 1, SessionId = "1" };
var controller = mocks.PartialMock<CityController>(cityService);
controller.Expect(c => c.SessionData).Return(sessionData);
controller.Replay();
// Act
controller.Index();
//Assert
...
IMO this approach is not very good because the SUT (Subject Under Test => in this case CityController) is being mocked with PartialMock.

Resources