How to Get email id using asp.net mvc4 openid api [closed] - c#

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
Looking to get the email id along with the openid while
Using the Internet template for MVC4
This is available for auth using google but not for facebook
wondering how to get/request the email id in the extraData dictionary
Looking at the code in AspNetWebStack project at http://aspnetwebstack.codeplex.com/, it looks like
OAuthWebSecurity.RegisterFacebookClient()
makes use of FacebookClient in DotNetOpenAuth.AspNet.dll hosted at https://github.com/AArnott/dotnetopenid
and the code in FacebookClient.GetUserData() has
var userData = new NameValueCollection();
userData.AddItemIfNotEmpty("id", graphData.Id);
userData.AddItemIfNotEmpty("username", graphData.Email);
userData.AddItemIfNotEmpty("name", graphData.Name);
userData.AddItemIfNotEmpty("link", graphData.Link == null ? null : graphData.Link.AbsoluteUri);
userData.AddItemIfNotEmpty("gender", graphData.Gender);
userData.AddItemIfNotEmpty("birthday", graphData.Birthday);
return userData;
which should return the email-id in username but it's not being returned
any help is appreciated
thanks

The provided Facebook OAuth client will not let you get anything beyond the default info. To get anything else, you need to be able to change the value of the scope parameter, something the included client doesn't allow. So, to get around this and still use the other boilerplate code the Internet template provides, you need to implement a custom OAuth client that follows the same pattern.
Since the entire ASP.NET source is open source, as is the OAuth library DotNetOpenAuth, you can actually look into the OAuth library and see exactly how the Facebook provider is built. Using that, I was able to come up with this:
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Net;
using System.Web;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.AspNet;
using DotNetOpenAuth.AspNet.Clients;
using Validation;
using Newtonsoft.Json;
namespace OAuthProviders
{
/// <summary>
/// The facebook client.
/// </summary>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Facebook", Justification = "Brand name")]
public sealed class FacebookScopedClient : OAuth2Client
{
#region Constants and Fields
/// <summary>
/// The authorization endpoint.
/// </summary>
private const string AuthorizationEndpoint = "https://www.facebook.com/dialog/oauth";
/// <summary>
/// The token endpoint.
/// </summary>
private const string TokenEndpoint = "https://graph.facebook.com/oauth/access_token";
/// <summary>
/// The _app id.
/// </summary>
private readonly string appId;
/// <summary>
/// The _app secret.
/// </summary>
private readonly string appSecret;
private readonly string scope;
#endregion
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="FacebookScopedClient"/> class.
/// </summary>
/// <param name="appId">
/// The app id.
/// </param>
/// <param name="appSecret">
/// The app secret.
/// </param>
/// <param name="scope">
/// The scope (requested Facebook permissions).
/// </param>
public FacebookScopedClient(string appId, string appSecret, string scope)
: base("facebook")
{
Requires.NotNullOrEmpty(appId, "appId");
Requires.NotNullOrEmpty(appSecret, "appSecret");
Requires.NotNullOrEmpty(scope, "scope");
this.appId = appId;
this.appSecret = appSecret;
this.scope = scope;
}
#endregion
#region Methods
/// <summary>
/// The get service login url.
/// </summary>
/// <param name="returnUrl">
/// The return url.
/// </param>
/// <returns>An absolute URI.</returns>
protected override Uri GetServiceLoginUrl(Uri returnUrl)
{
// Note: Facebook doesn't like us to url-encode the redirect_uri value
var builder = new UriBuilder(AuthorizationEndpoint);
builder.AppendQueryArgument("client_id", this.appId);
builder.AppendQueryArgument("redirect_uri", returnUrl.AbsoluteUri);
builder.AppendQueryArgument("scope", this.scope);
return builder.Uri;
}
/// <summary>
/// The get user data.
/// </summary>
/// <param name="accessToken">
/// The access token.
/// </param>
/// <returns>A dictionary of profile data.</returns>
protected override IDictionary<string, string> GetUserData(string accessToken)
{
FacebookGraphData graphData;
var request =
WebRequest.Create("https://graph.facebook.com/me?access_token=" + UriDataStringRFC3986(accessToken));
using (var response = request.GetResponse())
{
using (var responseStream = response.GetResponseStream())
{
graphData = OAuthJsonHelper.Deserialize<FacebookGraphData>(responseStream);
}
}
// this dictionary must contains
var userData = new Dictionary<string, string>();
if (!string.IsNullOrEmpty(graphData.Id)) { userData.Add("id", graphData.Id); }
if (!string.IsNullOrEmpty(graphData.Email)) { userData.Add("username", graphData.Email); }
if (!string.IsNullOrEmpty(graphData.Name)) { userData.Add("name", graphData.Name); }
if (graphData.Link != null && !string.IsNullOrEmpty(graphData.Link.AbsoluteUri)) { userData.Add("link", graphData.Link == null ? null : graphData.Link.AbsoluteUri); }
if (!string.IsNullOrEmpty(graphData.Gender)) { userData.Add("gender", graphData.Gender); }
if (!string.IsNullOrEmpty(graphData.Birthday)) { userData.Add("birthday", graphData.Birthday); }
return userData;
}
/// <summary>
/// Obtains an access token given an authorization code and callback URL.
/// </summary>
/// <param name="returnUrl">
/// The return url.
/// </param>
/// <param name="authorizationCode">
/// The authorization code.
/// </param>
/// <returns>
/// The access token.
/// </returns>
protected override string QueryAccessToken(Uri returnUrl, string authorizationCode)
{
// Note: Facebook doesn't like us to url-encode the redirect_uri value
var builder = new UriBuilder(TokenEndpoint);
builder.AppendQueryArgument("client_id", this.appId);
builder.AppendQueryArgument("redirect_uri", NormalizeHexEncoding(returnUrl.AbsoluteUri));
builder.AppendQueryArgument("client_secret", this.appSecret);
builder.AppendQueryArgument("code", authorizationCode);
builder.AppendQueryArgument("scope", this.scope);
using (WebClient client = new WebClient())
{
string data = client.DownloadString(builder.Uri);
if (string.IsNullOrEmpty(data))
{
return null;
}
var parsedQueryString = HttpUtility.ParseQueryString(data);
return parsedQueryString["access_token"];
}
}
/// <summary>
/// Converts any % encoded values in the URL to uppercase.
/// </summary>
/// <param name="url">The URL string to normalize</param>
/// <returns>The normalized url</returns>
/// <example>NormalizeHexEncoding("Login.aspx?ReturnUrl=%2fAccount%2fManage.aspx") returns "Login.aspx?ReturnUrl=%2FAccount%2FManage.aspx"</example>
/// <remarks>
/// There is an issue in Facebook whereby it will rejects the redirect_uri value if
/// the url contains lowercase % encoded values.
/// </remarks>
private static string NormalizeHexEncoding(string url)
{
var chars = url.ToCharArray();
for (int i = 0; i < chars.Length - 2; i++)
{
if (chars[i] == '%')
{
chars[i + 1] = char.ToUpperInvariant(chars[i + 1]);
chars[i + 2] = char.ToUpperInvariant(chars[i + 2]);
i += 2;
}
}
return new string(chars);
}
/// <summary>
/// The set of characters that are unreserved in RFC 2396 but are NOT unreserved in RFC 3986.
/// </summary>
private static readonly string[] UriRfc3986CharsToEscape = new[] { "!", "*", "'", "(", ")" };
internal static string UriDataStringRFC3986(string value)
{
// Start with RFC 2396 escaping by calling the .NET method to do the work.
// This MAY sometimes exhibit RFC 3986 behavior (according to the documentation).
// If it does, the escaping we do that follows it will be a no-op since the
// characters we search for to replace can't possibly exist in the string.
var escaped = new StringBuilder(Uri.EscapeDataString(value));
// Upgrade the escaping to RFC 3986, if necessary.
for (int i = 0; i < UriRfc3986CharsToEscape.Length; i++)
{
escaped.Replace(UriRfc3986CharsToEscape[i], Uri.HexEscape(UriRfc3986CharsToEscape[i][0]));
}
// Return the fully-RFC3986-escaped string.
return escaped.ToString();
}
#endregion
}
}
There are a few dependent libraries required to make this work as-is, all of which are available on NuGet. You already have DotNetOpenAuth; http://nuget.org/packages/Validation/ is another. The OAuthJsonHelper is a copy of an internal class used by DotNetOpenAuth - to get this provider to work I had to re-implement it in my own namespace:
using System;
using System.IO;
using System.Runtime.Serialization.Json;
using Validation;
namespace OAuthProviders
{
/// <summary>
/// The JSON helper.
/// </summary>
internal static class OAuthJsonHelper
{
#region Public Methods and Operators
/// <summary>
/// The deserialize.
/// </summary>
/// <param name="stream">
/// The stream.
/// </param>
/// <typeparam name="T">The type of the value to deserialize.</typeparam>
/// <returns>
/// The deserialized value.
/// </returns>
public static T Deserialize<T>(Stream stream) where T : class
{
Requires.NotNull(stream, "stream");
var serializer = new DataContractJsonSerializer(typeof(T));
return (T)serializer.ReadObject(stream);
}
#endregion
}
}
This is all provided as-is, with no guarantee that it will work via copy/paste - it's up to you to figure out how to integrate it into your project.

Related

How to pull a List of objects from FormDataCollection

I'm calling my API via a post. I am trying to get the values out from the FormDataCollection, but I cannot figure out how to get the list called ResourcesInfo?
UPDATE:
Here are the raw values:
Here is my setup:
What am I doing wrong here?
var resourceInfo2 = form.Get("ResourcesInfo");
var resourceInfo = JsonConvert.DeserializeObject<IList<SchedulerConflictResourceInfoModel>>(form.Get("ResourcesInfo"));
namespace WebPortal.MVC.Areas.Scheduler.Models
{
using System;
using System.Collections.Generic;
/// <summary>
/// Scheduler conflict param model
/// Obtain the values after the start or end date changes to check for conflicts
/// </summary>
public class SchedulerConflictParamModel
{
/// <summary>
/// Gets or sets the start date.
/// </summary>
/// <value>
/// The start date.
/// </value>
public DateTime StartDate { get; set; }
/// <summary>
/// Gets or sets the end date.
/// </summary>
/// <value>
/// The end date.
/// </value>
public DateTime EndDate { get; set; }
/// <summary>
/// Gets or sets the resources information.
/// </summary>
/// <value>
/// The resources information.
/// </value>
public IList<SchedulerConflictResourceInfoModel> ResourcesInfo { get; set; }
}
}
namespace WebPortal.MVC.Areas.Scheduler.Models
{
/// <summary>
/// Scheduler conflict resource info model
/// Holds the resource type id and resource id to check for conflicts
/// </summary>
public class SchedulerConflictResourceInfoModel
{
/// <summary>
/// Gets or sets the resource type identifier.
/// </summary>
/// <value>
/// The resource type identifier.
/// </value>
public int ResourceTypeId { get; set; }
/// <summary>
/// Gets or sets the resource identifier.
/// </summary>
/// <value>
/// The resource identifier.
/// </value>
public int ResourceId { get; set; }
}
}
function schedulerCheckForConflicts2(model) {
var deferred = $.Deferred()
let apiUrl = BuildSafeURL("api/SchedulerData/SchedulerCheckForConflicts", null)
$.post(apiUrl, {
StartDate: model.StartDate,
EndDate: model.EndDate,
ResourcesInfo: model.ResourcesInfo
})
.done(function (conflicts) {
DevExpress.ui.notify("called server... ", "warning", 1200)
deferred.resolve(conflicts)
})
.fail(function (error) {
genericErrorMessage()
console.log("error⚠️", error)
})
return deferred.promise();
}
/// <summary>
/// Gets the items scheduler file manager.
/// </summary>
/// <param name="form">The form.</param>
/// <returns>File system items</returns>
[HttpPost]
[WebAPIValidateAntiForgeryToken]
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
public async Task<HttpResponseMessage> SchedulerCheckForConflicts(FormDataCollection form)
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
{
var startDate = form.Get("StartDate");
var endDate = form.Get("EndDate");
var resourceInfo2 = form.Get("ResourcesInfo");
var resourceInfo = JsonConvert.DeserializeObject<IList<SchedulerConflictResourceInfoModel>>(form.Get("ResourcesInfo"));
var schedulerConflictParamModel = new SchedulerConflictParamModel();
return Request.CreateResponse(new List<int>
{
1, 2, 3
});
}

How to get the My Documents folder paths from all users of a machine

I am looking for a way to get the paths of the My Documents folders from all users (each user) of a local machine.
I found several articles, but they show how to do this for the current user.
I tested the code below, using SHGetKnownFolderPath, but it works only for the logged user. In the class ctor that receives a WindowsIdentity object, I create it with tokens of other users, but the paths returned were of the logged-in user.
Does anyone know how I could get the folders paths?
Thanks.
using Syroot.Windows.IO;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace ConsoleApplication2
{
class Program
{
private static Dictionary<KnownFolderType, KnownFolder> _knownFolderInstances;
static void Main(string[] args)
{
KnownFolderType type = KnownFolderType.Documents;
KnownFolder knownFolder = new KnownFolder(type);
//Ctor with WindowsIdentity parameter
//public KnownFolder(KnownFolderType type, WindowsIdentity identity)
//{
// Type = type;
// Identity = identity;
//}
// Write down the current and default path.
Console.WriteLine(knownFolder.Type.ToString());
try
{
Console.Write("Current Path: ");
Console.WriteLine(knownFolder.Path);
Console.Write("Default Path: ");
Console.WriteLine(knownFolder.DefaultPath);
}
catch (ExternalException ex)
{
// While uncommon with personal folders, other KnownFolders don't exist on every system, and trying
// to query those returns an error which we catch here.
Console.WriteLine("<Exception> " + ex.ErrorCode);
}
Console.ReadLine();
}
private static KnownFolder GetInstance(KnownFolderType type)
{
// Check if the caching directory exists yet.
if (_knownFolderInstances == null)
{
_knownFolderInstances = new Dictionary<KnownFolderType, KnownFolder>();
}
// Get a KnownFolder instance out of the cache dictionary or create it when not cached yet.
KnownFolder knownFolder;
if (!_knownFolderInstances.TryGetValue(type, out knownFolder))
{
knownFolder = new KnownFolder(type);
_knownFolderInstances.Add(type, knownFolder);
}
return knownFolder;
}
/// <summary>
/// The per-user Documents folder.
/// Defaults to "%USERPROFILE%\Documents".
/// </summary>
public static KnownFolder Documents
{
get { return GetInstance(KnownFolderType.Documents); }
}
}
}
KnownFolder.cs
using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
namespace Syroot.Windows.IO
{
/// <summary>
/// Represents a special Windows directory and provides methods to retrieve information about it.
/// </summary>
public sealed class KnownFolder
{
// ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------
/// <summary>
/// Initializes a new instance of the <see cref="KnownFolder"/> class for the folder of the given type. It
/// provides the values for the current user.
/// </summary>
/// <param name="type">The <see cref="KnownFolderType"/> of the known folder to represent.</param>
public KnownFolder(KnownFolderType type)
: this(type, WindowsIdentity.GetCurrent())
{
}
/// <summary>
/// Initializes a new instance of the <see cref="KnownFolder"/> class for the folder of the given type. It
/// provides the values for the given impersonated user.
/// </summary>
/// <param name="type">The <see cref="KnownFolderType"/> of the known folder to represent.</param>
/// <param name="identity">The <see cref="WindowsIdentity"/> of the impersonated user which values will be
/// provided.</param>
public KnownFolder(KnownFolderType type, WindowsIdentity identity)
{
Type = type;
Identity = identity;
}
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
/// <summary>
/// Gets the type of the known folder which is represented.
/// </summary>
public KnownFolderType Type
{
get;
private set;
}
/// <summary>
/// Gets the <see cref="WindowsIdentity"/> of the user whose folder values are provided.
/// </summary>
public WindowsIdentity Identity
{
get;
private set;
}
/// <summary>
/// Gets or sets the default path of the folder.
/// This does not require the folder to be existent.
/// </summary>
/// <exception cref="ExternalException">The known folder could not be retrieved.</exception>
public string DefaultPath
{
get
{
return GetPath(KnownFolderFlags.DontVerify | KnownFolderFlags.DefaultPath);
}
set
{
}
}
/// <summary>
/// Gets or sets the path as currently configured.
/// This does not require the folder to be existent.
/// </summary>
/// <exception cref="ExternalException">The known folder could not be retrieved.</exception>
public string Path
{
get
{
return GetPath(KnownFolderFlags.DontVerify);
}
set
{
SetPath(KnownFolderFlags.None, value);
}
}
/// <summary>
/// Gets or sets the path as currently configured, with all environment variables expanded.
/// This does not require the folder to be existent.
/// </summary>
/// <exception cref="ExternalException">The known folder could not be retrieved.</exception>
public string ExpandedPath
{
get
{
return GetPath(KnownFolderFlags.DontVerify | KnownFolderFlags.NoAlias);
}
set
{
SetPath(KnownFolderFlags.DontUnexpand, value);
}
}
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
/// <summary>
/// Creates the folder using its Desktop.ini settings.
/// </summary>
/// <exception cref="ExternalException">The known folder could not be retrieved.</exception>
public void Create()
{
GetPath(KnownFolderFlags.Init | KnownFolderFlags.Create);
}
// ---- METHODS (PRIVATE) --------------------------------------------------------------------------------------
private string GetPath(KnownFolderFlags flags)
{
IntPtr outPath;
int result = SHGetKnownFolderPath(Type.GetGuid(), (uint)flags, Identity.Token, out outPath);
if (result >= 0)
{
return Marshal.PtrToStringUni(outPath);
}
else
{
throw new ExternalException("Cannot get the known folder path. It may not be available on this system.",
result);
}
}
private void SetPath(KnownFolderFlags flags, string path)
{
int result = SHSetKnownFolderPath(Type.GetGuid(), (uint)flags, Identity.Token, path);
if (result < 0)
{
throw new ExternalException("Cannot set the known folder path. It may not be available on this system.",
result);
}
}
/// <summary>
/// Retrieves the full path of a known folder identified by the folder's known folder ID.
/// </summary>
/// <param name="rfid">A known folder ID that identifies the folder.</param>
/// <param name="dwFlags">Flags that specify special retrieval options. This value can be 0; otherwise, one or
/// more of the <see cref="KnownFolderFlags"/> values.</param>
/// <param name="hToken">An access token that represents a particular user. If this parameter is NULL, which is
/// the most common usage, the function requests the known folder for the current user. Assigning a value of -1
/// indicates the Default User. The default user profile is duplicated when any new user account is created.
/// Note that access to the Default User folders requires administrator privileges.</param>
/// <param name="ppszPath">When this method returns, contains the address of a string that specifies the path of
/// the known folder. The returned path does not include a trailing backslash.</param>
/// <returns>Returns S_OK if successful, or an error value otherwise.</returns>
/// <msdn-id>bb762188</msdn-id>
[DllImport("Shell32.dll")]
private static extern int SHGetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)]Guid rfid, uint dwFlags,
IntPtr hToken, out IntPtr ppszPath);
/// <summary>
/// Redirects a known folder to a new location.
/// </summary>
/// <param name="rfid">A <see cref="Guid"/> that identifies the known folder.</param>
/// <param name="dwFlags">Either 0 or <see cref="KnownFolderFlags.DontUnexpand"/>.</param>
/// <param name="hToken"></param>
/// <param name="pszPath"></param>
/// <returns></returns>
/// <msdn-id>bb762249</msdn-id>
[DllImport("Shell32.dll")]
private static extern int SHSetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)]Guid rfid, uint dwFlags,
IntPtr hToken, [MarshalAs(UnmanagedType.LPWStr)]string pszPath);
// ---- ENUMERATIONS -------------------------------------------------------------------------------------------
/// <summary>
/// Represents the retrieval options for known folders.
/// </summary>
/// <msdn-id>dd378447</msdn-id>
[Flags]
private enum KnownFolderFlags : uint
{
None = 0x00000000,
SimpleIDList = 0x00000100,
NotParentRelative = 0x00000200,
DefaultPath = 0x00000400,
Init = 0x00000800,
NoAlias = 0x00001000,
DontUnexpand = 0x00002000,
DontVerify = 0x00004000,
Create = 0x00008000,
NoAppcontainerRedirection = 0x00010000,
AliasOnly = 0x80000000
}
}
}
I figured it out.
I got all SIDs from the system and then searched the Windows registry for each SID by the "Personal" key in the following format: "HKEY_USERS" + "SID" + "\ Software \ Microsoft \ Windows \ CurrentVersion \ Explorer \ Shell Folders \ Personal ".
The "Personal" key retains the current path of each user's "My Documents" folder.
Get SIDs:
public static List<string> GetMachineSids()
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_UserProfile");
var regs = searcher.Get();
string sid;
List<string> sids = new List<string>();
foreach (ManagementObject os in regs)
{
if (os["SID"] != null)
{
sid = os["SID"].ToString();
sids.Add(sid);
}
}
searcher.Dispose();
return sids.Count > 0 ? sids : null;
}
Get MyDocuments Path:
public static List<string> GetMyDocumentsPathAllUsers()
{
const string parcialSubkey = #"\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders";
string subkey = string.Empty;
const string keyName = "Personal";
//get sids
List<string> sids = GetMachineSids();
List<string> myDocumentsPaths = new List<string>();
if (sids != null)
{
foreach (var sid in sids)
{
//get paths
subkey = sid + parcialSubkey;
using (RegistryKey key = Registry.Users.OpenSubKey(subkey))
{
if (key != null)
{
Object o = key.GetValue(keyName);
if (o != null)
{
myDocumentsPaths.Add(o.ToString());
}
}
}
}
}
return myDocumentsPaths.Count > 0 ? myDocumentsPaths : null;
}

Understanding Serialization

Context
I'm trying to understand how to use Serialization, never used it previously.
Right now I have a populate method in my singleton object (Main class) that basically adds a few member objects to a list of members using my addMember methods
I want to serialize this Members List Once I can serialize and deserialize the list I can delete my populate method.
Questions
HOW do I serialize this list so that the members list is deserialized upon startup?
WHERE do I serialize specifically? Do I serialize when I'm creating a new member, or do I just serialize the list at shutdown and deserialize at startup.
Since member information can be edited, how do I serialize the updates and overwrite the previously held data?
Code Listings
I'm kinda new to Serialization, but here's my code, I'm using a method for this because I I think it's cleaner this way, using ISerializable in my main class. Here's a few snippets from my main class, keep in mind I have tons of comments in my code, that's kinda why I didn't post this previously:
namespace HillRacingGraded
{
[Serializable]
public class HillRacing : ISerializable
{
/// <summary>
/// Singleton object hillracing
/// </summary>
private static HillRacing hillracing;
GUIUtility gui = new GUIUtility();
/// <summary>
/// Instance property returns the singleton instance
/// </summary>
public static HillRacing Instance
{
get
{
if (hillracing == null)
hillracing = new HillRacing();
return hillracing;
}
}
/// <summary>
/// public Property that returns races list, can be accessed by other classes.
/// </summary>
public List<BaseRace> Races
{
get
{
return races;
}
set
{
races = value;
}
}
/// <summary>
/// public Property that returns members list, can be accessed by other classes.
/// </summary>
public List<BaseMember> Members
{
get
{
return members;
}
set
{
members = value;
}
}
/// <summary>
/// instantiate the list of members
/// </summary>
private List<BaseMember> members; //I WANT TO SERIALIZE THIS
/// <summary>
/// instantiate the list of races
/// </summary>
private List<BaseRace> races; //I WANT TO SERIALIZE THIS
/// <summary>
/// Default constructor for hillracing.
/// </summary>
public HillRacing()
{
//members is a new list of the BaseMember objects.
//races is a new list of the BaseRace objects.
members = new List<BaseMember>();
races = new List<BaseRace>();
//call the populate method on launch, mostly for testing purposes.
Populate();
}
/// <summary>
/// Hillracing constructor for serialization
/// </summary>
/// <param name="info"></param>
/// <param name="ctxt"></param>
public HillRacing(SerializationInfo info, StreamingContext ctxt)
{
this.members = (List<BaseMember>)info.GetValue("Members", typeof(List<BaseMember>));
this.races = (List<BaseRace>)info.GetValue("Races", typeof(List<BaseRace>));
}
/// <summary>
/// get object data
/// </summary>
/// <param name="info"></param>
/// <param name="ctxt"></param>
public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
{
info.AddValue("Members", this.members);
}
/// <summary>
/// Adds a new junior member to the list of all members.
/// </summary>
/// <param name="stringfirstname">first name of the member</param>
/// <param name="stringlastname">last name of the member</param>
/// <param name="stringmiddlename">middle name of the member</param>
/// <param name="stringtitle">title of the member</param>
/// <param name="strst">street of the member</param>
/// <param name="strtwn">Town of the member</param>
/// <param name="strpc">Postcode of the member</param>
/// <param name="strEmail">email of the member</param>
/// <param name="intMobile">Mobile of the member</param>
/// <param name="intHome">Home phone of the member</param>
/// <param name="shrnumber">ID number of the member</param>
/// <param name="memtype">Type of the member</param>
/// <param name="username">username of the member</param>
/// <param name="noracesrun">number of races that the member has run</param>
/// <param name="perraceswon">percentage of races that the member has won</param>
/// <param name="mempic">image of the member</param>
/// <param name="memclub">the club the member is part of</param>
/// <param name="gender">the gender of the member</param>
/// <param name="memexp">the experience level the member has</param>
/// <param name="yearofbirth">the year of birth the member was born in</param>
/// <param name="monthofbirth">the month of birth the member was born in</param>
/// <param name="dayofbirth">the day of birth the member was born on</param>
public void addJunior(string stringfirstname, string stringlastname, string stringmiddlename, string stringtitle, string strst, string strtwn, string strpc, string strEmail, int intMobile, int intHome,
string shrnumber, string memtype, string username, string password, int noracesrun, float perraceswon, string mempic, string memclub, string gender, int memexp, int yearofbirth, int monthofbirth, int dayofbirth, string nextofkin, string docName, string docTel, string healthIssues, string parentalConsent)
{
// create a new member with the entered parameters to add to the list.
JuniorMember newMember = new JuniorMember(stringfirstname, stringlastname, stringmiddlename, stringtitle, strst, strtwn, strpc, strEmail, intMobile, intHome, shrnumber, memtype, username, password, noracesrun, perraceswon, mempic, memclub, gender, memexp, yearofbirth, monthofbirth, dayofbirth,nextofkin,docName,docTel,healthIssues,parentalConsent);
//use add functionality of list to add to the list.
members.Add(newMember);
}
/// <summary>
///
/// </summary>
/// <param name="stringfirstname">first name of the member</param>
/// <param name="stringlastname">last name of the member</param>
/// <param name="stringmiddlename">middle name of the member</param>
/// <param name="stringtitle">title of the member</param>
/// <param name="strst">street of the member</param>
/// <param name="strtwn">Town of the member</param>
/// <param name="strpc">Postcode of the member</param>
/// <param name="strEmail">email of the member</param>
/// <param name="intMobile">Mobile of the member</param>
/// <param name="intHome">Home phone of the member</param>
/// <param name="shrnumber">ID number of the member</param>
/// <param name="memtype">Type of the member</param>
/// <param name="username">username of the member</param>
/// <param name="noracesrun">number of races that the member has run</param>
/// <param name="perraceswon">percentage of races that the member has won</param>
/// <param name="mempic">image of the member</param>
/// <param name="memclub">the club the member is part of</param>
/// <param name="gender">the gender of the member</param>
/// <param name="memexp">the experience level the member has</param>
/// <param name="yearofbirth">the year of birth the member was born in</param>
/// <param name="monthofbirth">the month of birth the member was born in</param>
/// <param name="dayofbirth">the day of birth the member was born on</param>
/// <param name="nextofkin">The next family member contact</param>
/// <param name="docName">The name of the members doctor</param>
/// <param name="docTel">A telephone number for the doctor</param>
/// <param name="healthIssues">the health issues this member has.</param>
public void addSenior(string stringfirstname, string stringlastname, string stringmiddlename, string stringtitle, string strst, string strtwn, string strpc, string strEmail, int intMobile, int intHome,
string shrnumber, string memtype, string username, string password, int noracesrun, float perraceswon, string mempic, string memclub, string gender, int memexp, int yearofbirth, int monthofbirth, int dayofbirth, string nextofkin, string docName, string docTel, string healthIssues)
{
//create a new member with the entered parameters to add to the list.
SeniorMember newMember = new SeniorMember(stringfirstname, stringlastname, stringmiddlename, stringtitle, strst, strtwn, strpc, strEmail, intMobile, intHome, shrnumber, memtype, username, password, noracesrun, perraceswon, mempic, memclub, gender, memexp, yearofbirth, monthofbirth, dayofbirth,docName,docTel,healthIssues);
//use standard list functionality of list to add this new member to the list.
members.Add(newMember);
}
Here is my Serialization method in the Serializer class:
public void SerializeObject(string filename, object objectToSerialize)
{
Stream stream = File.Open(filename + ".bin", FileMode.Create);
BinaryFormatter bFormatter = new BinaryFormatter();
bFormatter.Serialize(stream, objectToSerialize);
stream.Close();
}
Problem is, I don't know how to actually use this.
Also have a deserializer:
public HillRacing DeSerializeObject(string filename)
{
HillRacing hillracing;
Stream stream = File.Open(filename + ".bin", FileMode.Open);
BinaryFormatter bFormatter = new BinaryFormatter();
hillracing = (HillRacing)bFormatter.Deserialize(stream);
stream.Close();
return hillracing;
}
Although you have done most of the part i suggest a little generics make it multiuse as
public static class StreamUtilities
{
public static T GetObject<T>(Byte[] rawimage) where T : class
{
try
{
MemoryStream memStream = new MemoryStream();
BinaryFormatter binForm = new BinaryFormatter();
memStream.Write(rawimage, 0, rawimage.Length);
memStream.Seek(0, SeekOrigin.Begin);
return binForm.Deserialize(memStream) as T;
}
catch (Exception ex)
{
return null;
}
}
public static Byte[] Serialize<T>(this T obj) where T:class
{
if (obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
return ms.ToArray();
}
}
then in your main class or whereever you want it to use include to namespace where the above extention method is then use
Object1 a=new Object1();// any serializable object
serializedbytes=a.Serialize<Object1>();
//deserialize
Object b=StreamUtilities.GetObject<Object1>(serializedbytes);
The above extention method will allow to seriailize/Deserialize any serializable Object.

Problems rendering image from database byte field using WebImage

I have an asp.net mvc 5 app with a database that stores photos. I'm trying to read the photo and resize it for display in a Staff profile.
I'm fairly new to both asp.net mvc and c#
I setup the following controller but am not getting an image display when I use a link to the controller in an img tag.
Any help would be appreciated.
public ActionResult Index(int id)
{
Staff staff = db.StaffList.Find(id);
if (staff.Photo != null)
{
var img = new WebImage(staff.Photo);
img.Resize(100, 100, true, true);
var imgBytes = img.GetBytes();
return File(imgBytes, "image/" + img.ImageFormat);
}
else
{
return null;
}
}
Looking around it seems there's a lot of dissatisfaction with the WebImage class and it has a few prominent bugs. I settled on using a nuget package called ImageProcessor rather than trying to write my own. This seems fairly inefficient to me but I don't have a better answer right now and this isn't heavily used so I'm going with this and just moving on.
Posting it here in case anyone else is struggling with something similar.
public ActionResult Index(int id, int? height, int? width)
{
int h = (height ?? 325);
int w = (width ?? 325);
Staff staff = db.StaffList.Find(id);
if (staff == null)
{
return new HttpNotFoundResult();
}
if (staff.Photo != null)
{
Size size = new Size(w, h);
byte[] rawImg;
using (MemoryStream inStream = new MemoryStream(staff.Photo))
{
using (MemoryStream outStream = new MemoryStream())
{
using (ImageFactory imageFactory = new ImageFactory())
{
imageFactory.Load(inStream)
.Constrain(size)
.Format(format)
.Save(outStream);
}
rawImg = outStream.ToArray();
}
}
return new FileContentResult(rawImg, "image/jpeg");
}
else
{
return null;
}
}
I'm going to answer this using ImageProcessor since your own answer uses the library. Disclaimer. I'm also the author of the library.
You're really not best using an ActionResult for processing images as it will be horribly inefficient. It run's far too late in the pipeline and you will have no caching.
You're much better off installing the Imageprocessor.Web package and implementing your own version of the IImageService interface to serve your images from the database. (On that note storing images in a db unless you are using blob storage is never wise either)
Implementing the IImageService interface allows you to utilise the url api within the library with a specific prefix to identify which image service to use. For example, remote image requests are prefixed with remote.axd to tell IageProcessor.Web to excute the RemoteImageService implementation.
This has the benefit of caching your images so subsequent requests are returned from a cache rather than being reprocessed upon each request.
Here is the full implementation of the LocalFileImageService which is the default service for the library. This should be able to serve as a guide for how to implement your own service.
namespace ImageProcessor.Web.Services
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System.Web;
using ImageProcessor.Web.Helpers;
/// <summary>
/// The local file image service for retrieving images from the
/// file system.
/// </summary>
public class LocalFileImageService : IImageService
{
/// <summary>
/// The prefix for the given implementation.
/// </summary>
private string prefix = string.Empty;
/// <summary>
/// Gets or sets the prefix for the given implementation.
/// <remarks>
/// This value is used as a prefix for any image requests
/// that should use this service.
/// </remarks>
/// </summary>
public string Prefix
{
get
{
return this.prefix;
}
set
{
this.prefix = value;
}
}
/// <summary>
/// Gets a value indicating whether the image service
/// requests files from
/// the locally based file system.
/// </summary>
public bool IsFileLocalService
{
get
{
return true;
}
}
/// <summary>
/// Gets or sets any additional settings required by the service.
/// </summary>
public Dictionary<string, string> Settings { get; set; }
/// <summary>
/// Gets or sets the white list of <see cref="System.Uri"/>.
/// </summary>
public Uri[] WhiteList { get; set; }
/// <summary>
/// Gets a value indicating whether the current request
/// passes sanitizing rules.
/// </summary>
/// <param name="path">
/// The image path.
/// </param>
/// <returns>
/// <c>True</c> if the request is valid; otherwise, <c>False</c>.
/// </returns>
public bool IsValidRequest(string path)
{
return ImageHelpers.IsValidImageExtension(path);
}
/// <summary>
/// Gets the image using the given identifier.
/// </summary>
/// <param name="id">
/// The value identifying the image to fetch.
/// </param>
/// <returns>
/// The <see cref="System.Byte"/> array containing the image data.
/// </returns>
public async Task<byte[]> GetImage(object id)
{
string path = id.ToString();
byte[] buffer;
// Check to see if the file exists.
// ReSharper disable once AssignNullToNotNullAttribute
FileInfo fileInfo = new FileInfo(path);
if (!fileInfo.Exists)
{
throw new HttpException(404, "No image exists at " + path);
}
using (FileStream file = new FileStream(path,
FileMode.Open,
FileAccess.Read,
FileShare.Read,
4096,
true))
{
buffer = new byte[file.Length];
await file.ReadAsync(buffer, 0, (int)file.Length);
}
return buffer;
}
}
}

Sending Data to WEB API function from Code behind C#

I have created Web API Services.
What I am trying to do is to call that API function, namely SaveSession(string data), from code behind button click, and to pass the entire form collection data as parameter in string format.
When I call the api's uri through webclient.uploadstring(url,string);
It is calling the web service but the parameter is not getting passed.
Pls help.
Instead of using a controller action method that accepts a string, you can instead read the form-url-encoded content posted to the controller.
In the example below, the SessionController exposes a SaveSession() method that accepts a POST of form-url-encoded content and then reads the session data as a collection of KeyValuePair instances.
The example client builds a list of key-value pairs and then uses a HttpClient instance to post the FormUrlEncodedContent to the web API controller method.
Example SessionController:
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
namespace MvcApplication1.Controllers
{
public class SessionController : ApiController
{
/// <summary>
/// Saves specified the session data.
/// </summary>
/// <returns>
/// A <see cref="HttpResponseMessage"/> that represents the response to the requested operation.
/// </returns>
[HttpPost()]
public HttpResponseMessage SaveSession()
{
// Ensure content is form-url-encoded
if(!IsFormUrlEncodedContent(this.Request.Content))
{
return this.Request.CreateResponse(HttpStatusCode.BadRequest);
}
// Read content as a collection of key value pairs
foreach (var parameter in ReadAsFormUrlEncodedContentAsync(this.Request.Content).Result)
{
var key = parameter.Key;
var value = parameter.Value;
if(!String.IsNullOrEmpty(key))
{
// Do some work to persist session data here
}
}
return this.Request.CreateResponse(HttpStatusCode.OK);
}
/// <summary>
/// Determines whether the specified content is form URL encoded content.
/// </summary>
/// <param name="content">
/// The type that the <see cref="IsFormUrlEncodedContent(HttpContent)"/> method operates on.
/// </param>
/// <returns>
/// <see langword="true"/> if the specified content is form URL encoded content; otherwise, <see langword="false"/>.
/// </returns>
public static bool IsFormUrlEncodedContent(HttpContent content)
{
if (content == null || content.Headers == null)
{
return false;
}
return String.Equals(
content.Headers.ContentType.MediaType,
FormUrlEncodedMediaTypeFormatter.DefaultMediaType.MediaType,
StringComparison.OrdinalIgnoreCase
);
}
/// <summary>
/// Write the HTTP content to a collection of name/value pairs as an asynchronous operation.
/// </summary>
/// <param name="content">
/// The type that the <see cref="ReadAsFormUrlEncodedContentAsync(HttpContent)"/> method operates on.
/// </param>
/// <returns>The <see cref="Task"/> object representing the asynchronous operation.</returns>
/// <remarks>
/// The <see cref="ReadAsFormUrlEncodedContentAsync(HttpContent, CancellationToken)"/> method
/// uses the <see cref="Encoding.UTF8"/> format (or the character encoding of the document, if specified)
/// to parse the content. URL-encoded characters are decoded and multiple occurrences of the same form
/// parameter are listed as a single entry with a comma separating each value.
/// </remarks>
public static Task<IEnumerable<KeyValuePair<string, string>>> ReadAsFormUrlEncodedContentAsync(HttpContent content)
{
return ReadAsFormUrlEncodedContentAsync(content, CancellationToken.None);
}
/// <summary>
/// Write the HTTP content to a collection of name/value pairs as an asynchronous operation.
/// </summary>
/// <param name="content">
/// The type that the <see cref="ReadAsFormUrlEncodedContentAsync(HttpContent, CancellationToken)"/> method operates on.
/// </param>
/// <param name="cancellationToken">
/// The cancellation token used to propagate notification that the operation should be canceled.
/// </param>
/// <returns>The <see cref="Task"/> object representing the asynchronous operation.</returns>
/// <remarks>
/// The <see cref="ReadAsFormUrlEncodedContentAsync(HttpContent, CancellationToken)"/> method
/// uses the <see cref="Encoding.UTF8"/> format (or the character encoding of the document, if specified)
/// to parse the content. URL-encoded characters are decoded and multiple occurrences of the same form
/// parameter are listed as a single entry with a comma separating each value.
/// </remarks>
public static Task<IEnumerable<KeyValuePair<string, string>>> ReadAsFormUrlEncodedContentAsync(HttpContent content, CancellationToken cancellationToken)
{
return Task.Factory.StartNew<IEnumerable<KeyValuePair<string, string>>>(
(object state) =>
{
var result = new List<KeyValuePair<string, string>>();
var httpContent = state as HttpContent;
if (httpContent != null)
{
var encoding = Encoding.UTF8;
var charSet = httpContent.Headers.ContentType.CharSet;
if (!String.IsNullOrEmpty(charSet))
{
try
{
encoding = Encoding.GetEncoding(charSet);
}
catch (ArgumentException)
{
encoding = Encoding.UTF8;
}
}
NameValueCollection parameters = null;
using (var reader = new StreamReader(httpContent.ReadAsStreamAsync().Result, encoding))
{
parameters = HttpUtility.ParseQueryString(reader.ReadToEnd(), encoding);
}
if (parameters != null)
{
foreach(var key in parameters.AllKeys)
{
result.Add(
new KeyValuePair<string, string>(key, parameters[key])
);
}
}
}
return result;
},
content,
cancellationToken
);
}
}
}
Example Calling Client:
using System;
using System.Collections.Generic;
using System.Net.Http;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
using (var client = new HttpClient())
{
// Initialize HTTP client
client.BaseAddress = new Uri("http://localhost:26242/api/", UriKind.Absolute);
client.Timeout = TimeSpan.FromSeconds(10);
// Build session data to send
var values = new List<KeyValuePair<string, string>>();
values.Add(new KeyValuePair<string, string>("Item1", "Value1"));
values.Add(new KeyValuePair<string, string>("Item2", "Value2"));
values.Add(new KeyValuePair<string, string>("Item3", "Value3"));
// Send session data via POST using form-url-encoded content
using (var content = new FormUrlEncodedContent(values))
{
using (var response = client.PostAsync("session", content).Result)
{
Console.WriteLine(response.StatusCode);
}
}
}
}
}
}
I typically have the IsFormUrlEncodedContent and ReadAsFormUrlEncodedContentAsync methods as extension methods on HttpContent but placed them in the controller for the purpose of this example.

Categories

Resources