What's the difference between context.Get() and its generic version? - asp.net

I'm trying to get familiar with OWIN and there are a lot of things that confuse me. For example, in partial startup.cs class I register context callback via
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
What's the difference? Why do we need that generic method?
I can get that context like this:
context.Get<ApplicationDbContext>())
context.GetUserManager<ApplicationUserManager>()
What's the difference between the Get and GetUserManager methods? Why can't I just call context.Get for ApplicationUserManager?

There is no difference between Get<UserManager> and GetUserManager<UserManager>
Here's the source code for both...
/// <summary>
/// Retrieves an object from the OwinContext using a key based on the AssemblyQualified type name
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="context"></param>
/// <returns></returns>
public static T Get<T>(this IOwinContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
return context.Get<T>(GetKey(typeof (T)));
}
/// <summary>
/// Get the user manager from the context
/// </summary>
/// <typeparam name="TManager"></typeparam>
/// <param name="context"></param>
/// <returns></returns>
public static TManager GetUserManager<TManager>(this IOwinContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
return context.Get<TManager>();
}

Related

Protobuf-net v3 DateTimeOffset Surrogate

I've seen some other SO's where people are using DateTimeOffset surrogates to handle deserializing those properties, however when I try to copy those, I continue to get a System.InvalidOperationException: No serializer defined for type: System.DateTimeOffset error.
[ProtoContract]
public TestClass
{
[ProtoMember(1)]
public DateTimeOffset Time { get; set; }
}
Surrogate class
[ProtoContract]
public class DateTimeOffsetSurrogate
{
[ProtoMember(1)]
public long DateTimeTicks { get; set; }
[ProtoMember(2)]
public short OffsetMinutes { get; set; }
public static implicit operator DateTimeOffsetSurrogate(DateTimeOffset value)
{
return new DateTimeOffsetSurrogate
{
DateTimeTicks = value.Ticks,
OffsetMinutes = (short)value.Offset.TotalMinutes
};
}
public static implicit operator DateTimeOffset(DateTimeOffsetSurrogate value)
{
return new DateTimeOffset(value.DateTimeTicks, TimeSpan.FromMinutes(value.OffsetMinutes));
}
}
Then I'm registering it right before the http call. I've tried moving this registration into a few different places but it doesn't seem to make a difference. Did this change in v3 or something or am I doing something wrong? Sorry - new to protobuf-net :)
public async Task<Response<IEnumerable<TestClass>>> GetData()
{
RuntimeTypeModel.Default.Add(typeof(DateTimeOffset), false).SetSurrogate(typeof(DateTimeOffsetSurrogate));
var request = new HttpRequestMessage(HttpMethod.Get, "my-url");
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-protobuf"));
var result = await _httpClient.SendAsync(request);
var items= ProtoBuf.Serializer.Deserialize<Response<IEnumerable<TestClass>>>(await result.Content.ReadAsStreamAsync());
return items;
}
I am using version 3.1.22 (Currently the latest) of protobuf-net right now with the following setup.
// Needs to be only called at application startup, e.g. in the Startup.cs calls of your web API.
RuntimeTypeModel.Default.Add(typeof(DateTimeOffset), false).SetSurrogate(typeof(DateTimeOffsetSurrogate));
RuntimeTypeModel.Default.Add(typeof(DateTimeOffset?), false).SetSurrogate(typeof(DateTimeOffsetSurrogate));
The surrogate handler I use successfully, can be found below. No black magic happening here, just serializing / deserializing the unix timestamp to long and vice versa:
namespace Something
{
using System;
using ProtoBuf;
/// <summary>
/// A surrogate handler for the <see cref="DateTimeOffset"/> class.
/// </summary>
[ProtoContract(Name = nameof(DateTimeOffset))]
public class DateTimeOffsetSurrogate
{
/// <summary>
/// Gets or sets the value.
/// </summary>
[ProtoMember(1)]
public long? Value { get; set; }
/// <summary>
/// Converts the <see cref="DateTimeOffsetSurrogate"/> to a <see cref="DateTimeOffset"/>.
/// </summary>
/// <param name="surrogate">The surrogate handler.</param>
public static implicit operator DateTimeOffset(DateTimeOffsetSurrogate surrogate)
{
if (surrogate?.Value is null)
{
throw new ArgumentNullException(nameof(surrogate));
}
var dt = DateTimeOffset.FromUnixTimeMilliseconds(surrogate.Value.Value);
dt = dt.ToLocalTime();
return dt;
}
/// <summary>
/// Converts the <see cref="DateTimeOffsetSurrogate"/> to a <see cref="DateTimeOffset"/>.
/// </summary>
/// <param name="surrogate">The surrogate handler.</param>
public static implicit operator DateTimeOffset?(DateTimeOffsetSurrogate? surrogate)
{
if (surrogate?.Value is null)
{
return null;
}
var dt = DateTimeOffset.FromUnixTimeMilliseconds(surrogate.Value.Value);
dt = dt.ToLocalTime();
return dt;
}
/// <summary>
/// Converts the <see cref="DateTimeOffset"/> to a <see cref="DateTimeOffsetSurrogate"/>.
/// </summary>
/// <param name="source">The source.</param>
public static implicit operator DateTimeOffsetSurrogate(DateTimeOffset source)
{
return new DateTimeOffsetSurrogate
{
Value = source.ToUnixTimeMilliseconds()
};
}
/// <summary>
/// Converts the <see cref="DateTimeOffset"/> to a <see cref="DateTimeOffsetSurrogate"/>.
/// </summary>
/// <param name="source">The source.</param>
public static implicit operator DateTimeOffsetSurrogate(DateTimeOffset? source)
{
return new DateTimeOffsetSurrogate
{
Value = source?.ToUnixTimeMilliseconds()
};
}
}
}
Maybe, you want to give it a try. Maybe [ProtoContract(Name = nameof(DateTimeOffset))] is what you're missing, but I'm not sure.

When do you need a parameterless constructor on a Command/DTO object for an API call?

I am getting the following exception thrown: "System.NotSupportedException: Deserialization of reference
types without parameterless constructor is not supported."
It is JSON being passed into the controller.
When do you need a parameterless constructor vs. one with parameters?
I am using ASP.NetCore.App.Ref 3.1.3 and NetCore.App.Ref 3.1.0.
Here is the class that it is saying needs a parameterless constructor:
public class JobApplicationStatusModel : BaseEntityModel
{
/// <summary>
///JobApplicationStatus ID
/// </summary>
public int Id { get; set; }
/// <summary>
/// Description/Name of Status.
/// </summary>
public string StatusDescription { get; set; }
/// <summary>
/// Main constructor
/// </summary>
/// <param name="id">JobApplication StatusID</param>
/// <param name="statusDescription">Status Description</param>
public JobApplicationStatusModel(int id, string statusDescription)
{
Id = id;
StatusDescription = statusDescription ?? throw new ArgumentNullException(nameof(statusDescription));
}
/// <summary>
/// Returns an enumeration of all atomic values.
/// </summary>
/// <returns>An enumeration of all atomic values.</returns>
protected override IEnumerable<object> GetAtomicValues()
{
// Using a yield return statement to return each element one at a time
yield return Id;
yield return StatusDescription;
}
}

Xamarin Form's HttpWebRequest no timeout property?

Am using HttpWebRequest to make HTTP calls, i see it doesn't have a Timeout property ?
For example:
HttpWebRequest request = WebRequest.Create(aWebUrl) as HttpWebRequest;
request.ContentType = "application/json";
request.Method = "GET";
Thanks
I think you can take a look to James Montemagno's plugin
there is a Utils that help you to check if an async call goes in timeout. I think you can use it with your Web Request.
namespace MvvmHelpers
{
/// <summary>
/// Extension Utils
/// </summary>
public static class Utils
{
/// <summary>
/// Task extension to add a timeout.
/// </summary>
/// <returns>The task with timeout.</returns>
/// <param name="task">Task.</param>
/// <param name="timeoutInMilliseconds">Timeout duration in Milliseconds.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public async static Task<T> WithTimeout<T>(this Task<T> task, int timeoutInMilliseconds)
{
var retTask = await Task.WhenAny(task, Task.Delay(timeoutInMilliseconds))
.ConfigureAwait(false);
if (retTask is Task<T>)
return task.Result;
return default(T);
}
/// <summary>
/// Task extension to add a timeout.
/// </summary>
/// <returns>The task with timeout.</returns>
/// <param name="task">Task.</param>
/// <param name="timeout">Timeout Duration.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public static Task<T> WithTimeout<T>(this Task<T> task, TimeSpan timeout) =>
WithTimeout(task, (int)timeout.TotalMilliseconds);
}
}
you can find an explanation of it in this video Channel 9 MVVM helper
Otherwise you can use HttpClient that has a "Timeout" property
Timeout

signalR OnDisconnected() cancel task

When a page loads I start a new task in my hub. This task sends data to a browser updating a certain html elements. When I browse away from the page I want to stop the task.
The problem is that before the task is stopped (due to it's sleep argument), a new tokenSource = new CancellationTokenSource();
is set before the previous instance of this task had a chance to stop.
What i'm trying to do is to have the task stop when browsing away from the page to a different page that is not requiring signalR. BUT maybe, not stop it if it's only a refresh of the same page. Not sure how to do it. To sum it up, I want to guarantee that only 1 instance of this task is running (AND only on the page that requires it/or have a listener)
any info greatly appreciated.
thanks
CODE:
public class TaskActionStatus : Hub
{
#region Static Fields
/// <summary>
/// The token source.
/// </summary>
private static CancellationTokenSource tokenSource;
/// <summary>
/// The url string.
/// </summary>
private static string url = string.Empty;
#endregion
#region Public Methods and Operators
/// <summary>
/// The get tasks status.
/// </summary>
/// <param name="siteId">
/// The site id.
/// </param>
/// <param name="location"></param>
public void GetTasksStatus(int? siteId)
{
var taskRepository = UnityContainerSetup.Container.Resolve<ITaskRepository>();
tokenSource = new CancellationTokenSource();
CancellationToken ct = tokenSource.Token;
// init task for checking task statuses
var tasksItem = new DownloadTaskItem();
// start task only if at least one listener
if (UserHandler.ConnectedIds.Count < 2 && !taskRepository.IsTasksStatusAsyncRunning())
{
taskRepository.GetTasksStatusAsync(siteId, tasksItem, ct);
// subscribe to event [ listener ]
tasksItem.Changed += this.UpdateTasksStatus;
}
else tokenSource.Cancel();
}
/// <summary>
/// The on connected.
/// </summary>
/// <returns>
/// The <see cref="Task"/>.
/// </returns>
public override Task OnConnected()
{
UserHandler.ConnectedIds.Add(this.Context.ConnectionId);
return base.OnConnected();
}
/// <summary>
/// The on disconnected.
/// </summary>
/// <returns>
/// The <see cref="Task"/>.
/// </returns>
public override Task OnDisconnected()
{
UserHandler.ConnectedIds.Remove(this.Context.ConnectionId);
if (UserHandler.ConnectedIds.Count == 0)
{
try
{
tokenSource.Cancel();
}
catch (Exception ex)
{
Log.Error(ex);
}
}
return base.OnDisconnected();
}
/// <summary>
/// The update tasks status.
/// </summary>
/// <param name="sender">
/// The sender.
/// </param>
/// <param name="e">
/// The e.
/// </param>
public void UpdateTasksStatus(object sender, TaskEventArgs e)
{
this.Clients.All.updateMessages(e.Tasks);
}
#endregion
}
/// <summary>
/// The user handler.
/// </summary>
public static class UserHandler
{
#region Static Fields
/// <summary>
/// The connected ids.
/// </summary>
public static HashSet<string> ConnectedIds = new HashSet<string>();
#endregion
}
public bool IsTasksStatusAsyncRunning()
{
if (tasksStatusAsync != null && tasksStatusAsync.Status.Equals(TaskStatus.Running))
{
return true;
}
return false;
}
Moving this line:
tokenSource = new CancellationTokenSource();
CancellationToken ct = tokenSource.Token;
...
making it this:
if (UserHandler.ConnectedIds.Count < 2)
{
Trace.WriteLine("GetTasksStatus: Starting new task");
tokenSource = new CancellationTokenSource();
CancellationToken ct = tokenSource.Token;
taskRepository.GetTasksStatusAsync(siteId, tasksItem, ct);
// subscribe to event [ listener ]
tasksItem.Changed += this.UpdateTasksStatus;
}
did it for me. thanks

dynamic load recive activity wf

I'm trying to load and invoke activityes from custom activity as follows:
Imagine I have a xamlx like this:
--Sequence
|----- LoadActiviy
|--Initialize dictionary with input data of activitity
|----- Invoke
This works when activity NOT CONTAINS receive/send messages. But when i try with activity wich contains receive/send messages the result is a exception
WorkflowApplicationUnhandledExceptionEventArgs: Only registered bookmark scopes can be used for creating scoped bookmarks.
The code:
1-Load xaml: (Load activity)
public sealed class LoadActivity : CodeActivity<Activity>
{
#region Properties
/// <summary>
/// Gets or sets Path.
/// </summary>
[RequiredArgument]
public InArgument<string> Path { get; set; }
#endregion
#region Methods
/// <summary>
/// The execute method.
/// </summary>
/// <param name="context">
/// The context.
/// </param>
/// <returns>
/// An activity loaded from a file
/// </returns>
protected override Activity Execute(CodeActivityContext context)
{
return ActivityXamlServices.Load(this.Path.Get(context));
}
#endregion
}
2- Run activity:
public class SynchronousSynchronizationContext : SynchronizationContext
{
public override void Post(SendOrPostCallback d, object state)
{
d(state);
}
}
public sealed class Invoke : CodeActivity
{
#region Properties
/// <summary>
/// Gets or sets Activity.
/// </summary>
/// <remarks>
/// The activity that will be invoked. Can be loaded from XAML.
/// </remarks>
[RequiredArgument]
public InArgument<Activity> Activity { get; set; }
public OutArgument<IDictionary<string, object>> Output { get; set; }
/// <summary>
/// Gets or sets Input.
/// </summary>
/// <remarks>
/// The input arguments you want to pass to the other workflow
/// </remarks>
public InArgument<IDictionary<string, object>> Input { get; set; }
#endregion
// If your activity returns a value, derive from CodeActivity<TResult>
// and return the value from the Execute method.
protected override void Execute(CodeActivityContext context)
{
try
{
IDictionary<string,object> _input= this.Input.Get(context);
foreach (KeyValuePair<string,object> item in _input )
{
Debug.WriteLine(string.Format("{0} {1}", item.Key, item.Value));
}
// AutoResetEvent idleEvent = new AutoResetEvent(false);
WorkflowApplication app = new WorkflowApplication(this.Activity.Get(context),this.Input.Get(context));
app.SynchronizationContext = new SynchronousSynchronizationContext();
app.Completed = delegate(WorkflowApplicationCompletedEventArgs e)
{
// idleEvent.Set();
};
app.OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e)
{
// Display the unhandled exception.
Console.WriteLine("OnUnhandledException in Workflow {0}\n{1}",
e.InstanceId, e.UnhandledException.Message);
Console.WriteLine("ExceptionSource: {0} - {1}",
e.ExceptionSource.DisplayName, e.ExceptionSourceInstanceId);
// Instruct the runtime to terminate the workflow.
// Other choices are Abort and Cancel. Terminate
// is the default if no OnUnhandledException handler
// is present.
return UnhandledExceptionAction.Terminate;
};
app.Idle = e => Console.WriteLine("WorkflowApplication.Idle called");
Console.WriteLine("Before WorkflowApplication.Run()");
app.Run();
}
catch
{
throw;
}
}
}
Any ideas?
You can only use a Receive activity in a workflow hosted in a WorkflowServiceHost. Even if your main workflow is hosted in a WorkflowServiceHost the child workflow is hosted in a WorkflowApplication and can't contain a Receive activity because it isn't running as part of the WCF infrastructure.

Resources