ব্যবহারকারীর উপলব্ধ বৈশিষ্ট্যগুলি কীভাবে প্রসারিত করা যায় d


130

ব্যবহারকারীরা আমার ওয়েবসাইটে লগ ইন করতে আমি এমভিসি 5 আইডেন্টিটি 2.0 ব্যবহার করছি, যেখানে প্রমাণীকরণের বিশদটি এসকিউএল ডাটাবেসে সংরক্ষিত থাকে। অনেক অনলাইন টিউটোরিয়ালে যেমন পাওয়া যায় তেমনি Asp.net পরিচয়টি একটি স্ট্যান্ডার্ড উপায়ে প্রয়োগ করা হয়েছে।

আইডেন্টিটি মডেলগুলিতে অ্যাপ্লিকেশন ব্যবহারকারী শ্রেণিটি কিছু কাস্টম বৈশিষ্ট্য, যেমন একটি পূর্ণসংখ্যা সংস্থাআইডি অন্তর্ভুক্ত করার জন্য বাড়ানো হয়েছে। ধারণাটি হ'ল অনেক ব্যবহারকারীকে তৈরি করা যায় এবং একটি সাধারণ সংস্থায় ডাটাবেস সম্পর্কের উদ্দেশ্যে নির্ধারিত করা যায়।

public class ApplicationUser : IdentityUser
    {
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here
            return userIdentity;
        }

        //Extended Properties
        public DateTime? BirthDate { get; set; }
        public long? OrganizationId { get; set; }

        //Key Mappings
        [ForeignKey("OrganizationId")]
        public virtual Organization Organization { get; set; }
    }

আমি কিভাবে একজন নিয়ামকের মধ্যে থেকে বর্তমানে লগ ইন করা ব্যবহারকারীর অর্গানাইজেশন আইডি সম্পত্তি পুনরুদ্ধার করতে পারি? কোনও ব্যবহারকারী একবার লগইন হয়ে গেলে বা ইউজারআইডি-র ভিত্তিতে প্রতিবারই একটি নিয়ামক পদ্ধতি কার্যকর করে, তখন কি আমার কাছে ডেটাবেস থেকে অর্গানাইজেশন আইডি পুনরুদ্ধার করা যায়?

ওয়েবে চারপাশে পড়া দেখেছি ইউজারআইডি ইত্যাদি লগ ইন করার জন্য আমার নিম্নলিখিতগুলি ব্যবহার করতে হবে need

using Microsoft.AspNet.Identity;
...
User.Identity.GetUserId();

যাইহোক, OrganisId কোনও ব্যবহারকারীর আইডেন্টিটিতে উপলব্ধ সম্পত্তি নয়। OrganisId সম্পত্তি অন্তর্ভুক্ত করার জন্য কি আমার ব্যবহারকারীর পরিচয় বাড়ানো দরকার? যদি তা হয় তবে আমি কীভাবে এটি সম্পর্কে যাব।

আমার প্রায়শই অর্গানাইজআইডের প্রয়োজন হওয়ার কারণটি হ'ল লগইন করা ব্যবহারকারীর সাথে সম্পর্কিত এমন সংস্থার সাথে সম্পর্কিত ডেটা পুনরুদ্ধার করতে অনেক টেবিল প্রশ্নগুলি অর্গানাইজডআইডি-র উপর নির্ভরশীল।


3
আমার উত্তর এখানে কি আপনাকে আদৌ সহায়তা করে?
জুতো

1
আমার কাছ থেকে অনেক অনেক একই উত্তর: stackoverflow.com/a/28138594/809357 - যদি অনুরোধের জীবনে আপনার এই তথ্য নিয়মিত প্রয়োজন হয়, আপনি দাবি হিসাবে এটি কুকিতে রাখতে পারেন।
ট্রিলম্যাক্স 5'15

1
ধন্যবাদ @ শো আপনার উত্তর উভয়ই কাজ করেছে। আপনার উত্তরগুলি ছাড়াও, আমাকে কুকিতে সংরক্ষণ করার জন্য একটি দাবি যুক্ত করতে হয়েছিল। আইডেন্টিটি মডেলস ক্লাসে আমাকে ইউজারআইডেন্টিটি যোগ করতে হয়েছিল dএডডক্লেইম (নতুন দাবি ("মাই অ্যাপ: অর্গানাইজেশন আইডি", অর্গানাইজেশনআইডি.টসস্ট্রিং ())); থেকে প্রকাশ্য ASYNC টাস্ক <ClaimsIdentity> GenerateUserIdentityAsync (UserManager <ApplicationUser> পরিচালক) পদ্ধতি।
রবহর্ড

উত্তর:


219

আপনি যখনই ব্যবহারকারীর বৈশিষ্ট্যগুলি প্রসারিত করতে চান above উপরের প্রশ্নের মতো অতিরিক্ত কোনও বৈশিষ্ট্য সহ পরিচয়, এই বৈশিষ্ট্যগুলিকে প্রথমে অ্যাপ্লিকেশন ব্যবহারকারী শ্রেণিতে যুক্ত করুন:

public class ApplicationUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }

    // Your Extended Properties
    public long? OrganizationId { get; set; }
}

তারপরে আপনার যা দরকার তা হ'ল এটির মতো একটি এক্সটেনশন পদ্ধতি তৈরি করা (আমি একটি নতুন এক্সটেনশন ফোল্ডারে খনি তৈরি করি):

namespace App.Extensions
{
    public static class IdentityExtensions
    {
        public static string GetOrganizationId(this IIdentity identity)
        {
            var claim = ((ClaimsIdentity)identity).FindFirst("OrganizationId");
            // Test for null to avoid issues during local testing
            return (claim != null) ? claim.Value : string.Empty;
        }
    }
}

আপনি যখন অ্যাপ্লিকেশন ব্যবহারকারী শ্রেণিতে পরিচয় তৈরি করবেন, কেবলমাত্র দাবি -> সংস্থাপন যোগ করুন:

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here => this.OrganizationId is a value stored in database against the user
        userIdentity.AddClaim(new Claim("OrganizationId", this.OrganizationId.ToString()));

        return userIdentity;
    }

একবার আপনার দাবিটি যুক্ত হয়ে গেলে এবং আপনার ব্যবহারকারীর সম্পত্তি হিসাবে এটি উপলব্ধ করার জন্য আপনার এক্সটেনশন পদ্ধতিটি স্থানে রাখুন d পরিচয়, আপনি যে পৃষ্ঠা / ফাইলটিতে এটি অ্যাক্সেস করতে চান তাতে ব্যবহারের বিবৃতি যুক্ত করুন :

আমার ক্ষেত্রে: using App.Extensions;একটি কন্ট্রোলারের মধ্যে এবং @using. App.Extensionsএকটি .cshtml ভিউ ফাইল সহ।

সম্পাদনা করুন:

আপনি প্রতিটি ভিউতে একটি স্টেটমেন্ট যুক্ত করে এড়াতে যা করতে পারেন তা হ'ল ভিউ ফোল্ডারে গিয়ে সেখানে ওয়েবকনফিগ ফাইলটি সনাক্ত করা। এখন <namespaces>ট্যাগটি সন্ধান করুন এবং আপনার এক্সটেনশনের নাম স্থানটি এখানে যুক্ত করুন:

<add namespace="App.Extensions" />

আপনার ফাইলটি সংরক্ষণ করুন এবং আপনার কাজ শেষ হয়েছে। এখন প্রতিটি ভিউ আপনার এক্সটেনশনগুলি সম্পর্কে জানতে পারবে।

আপনি এক্সটেনশন পদ্ধতি অ্যাক্সেস করতে পারেন:

var orgId = User.Identity.GetOrganizationId();

হাই পাওয়েল, আমিও একই চেষ্টা করেছি, তবে ত্রুটি পেয়েছি যে অ্যাপ্লিকেশন ব্যবহারকারীর অর্গানাইজেশনআইডের সংজ্ঞা নেই
এটি একটি ফাঁদ

@ রচিতগুপ্ত কখন হয়? আপনি যখন দাবি যুক্ত করার চেষ্টা করছেন বা কোডটির পরে আপনি যখন এর মানটি অ্যাক্সেস করার চেষ্টা করছেন? যদি আপনি দাবি যুক্ত করার পরে থাকেন তবে আপনার অ্যাপ্লিকেশন ব্যবহারকারীটির সম্পত্তি নির্ধারিত আছে তা নিশ্চিত করুন ... যদি এটি পরে কোড হয় তবে আপনি যেখানে এক্সটেনশন পদ্ধতিটি তৈরি করেছেন সেখানে ব্যবহারের বিবৃতি যুক্ত করতে ভুলবেন না: অ্যাপ্লিকেশন ব্যবহার করে ;
পাভেল

ইউজারআইডেন্টিটি.এডডক্লেম লাইনে ত্রুটি হয়েছে। আমি আইডেন্টিটি এক্সটেনশনগুলি ক্লাসটি কেবল আইডেন্টিটি মডেলস সি ফাইলগুলিতে তৈরি করেছি। এটা কি সমস্যার উত্স হতে পারে?
এটি

না, আপনি যদি দাবিটি যুক্ত করেন তবে পরিচয় এক্সটেনশানগুলি খেলার আগে আসার আগেই এটি ঘটে থাকে (এটি যখন আপনি আবার মানটি পড়বেন) ... নিশ্চিত করুন যে আপনার অ্যাপ্লিকেশন ব্যবহারকারীটির যে দাবিটি আপনি দাবি হিসাবে যুক্ত করার চেষ্টা করছেন তা আছে: উদাহরণস্বরূপ এটি ছিল সার্বজনীন দীর্ঘ সংস্থা সেট; }
পাভেল

6
ধন্যবাদ, এটি কাজ করেছে। আমি মনে করি এএসপি নেট পরিচয় ২-এ কাস্টম ভেরিয়েবলের জন্য এটি সেরা অনুশীলন I আমি জানি না কেন Asp.Net সম্প্রদায় তাদের ওয়েবসাইটে ডিফল্ট নিবন্ধগুলিতে এমন উদাহরণ দেয় না।
ওয়াননিস্টফ্রেন্ড

17

আমি একই সমাধান খুঁজছিলাম এবং পাভেল আমাকে উত্তরটির 99% দিয়েছেন gave এক্সটেনশনটি প্রদর্শনের জন্য আমার যে একমাত্র জিনিসটি অনুপস্থিত ছিল তা হ'ল cshtml (দেখুন) পৃষ্ঠাতে নিম্নলিখিত রেজার কোডটি যুক্ত করা হয়েছিল:

@using programname.Models.Extensions

আমি লগ-ইন করার পরে আমার নেবারের উপরের ডানদিকে প্রদর্শন করার জন্য আমি ফার্স্টনামের সন্ধান করছিলাম।

আমি ভেবেছিলাম এই পোস্টটি পোস্ট করব তবে এটি অন্য কাউকে সহায়তা করে, সুতরাং আমার কোডটি এখানে:

আমি এক্সটেনশন (আমার মডেল ফোল্ডারের অধীনে) নামে একটি নতুন ফোল্ডার তৈরি করেছি এবং উপরে উল্লিখিত পাওয়েল হিসাবে নতুন শ্রেণি তৈরি করেছি: IdentityExtensions.cs

using System.Security.Claims;
using System.Security.Principal;

namespace ProgramName.Models.Extensions
{
    public static class IdentityExtensions
    {
        public static string GetUserFirstname(this IIdentity identity)
        {
            var claim = ((ClaimsIdentity)identity).FindFirst("FirstName");
            // Test for null to avoid issues during local testing
            return (claim != null) ? claim.Value : string.Empty;
        }
    }
}

IdentityModels.cs :

public class ApplicationUser : IdentityUser
{

    //Extended Properties
    public string FirstName { get; internal set; }
    public string Surname { get; internal set; }
    public bool isAuthorized { get; set; }
    public bool isActive { get; set; }

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        userIdentity.AddClaim(new Claim("FirstName", this.FirstName));

        return userIdentity;
    }
}

তারপরে আমার _LoginPartial.cshtml(আন্ডার Views/Sharedফোল্ডারগুলিতে) আমি যুক্ত করেছি@using.ProgramName.Models.Extensions

আমি তখন কোডটির ফোলিং লাইনে পরিবর্তন যুক্ত করেছি যা লগ ইন করার পরে ব্যবহারকারীদের প্রথম নামটি ব্যবহার করতে চলেছিল:

@Html.ActionLink("Hello " + User.Identity.GetUserFirstname() + "!", "Index", "Manage", routeValues: null, htmlAttributes: new { title = "Manage" })

সম্ভবত এটি অন্য কাউকে লাইনে নামাতে সহায়তা করে।


11

জন অ্যাটেনের এই দুর্দান্ত ব্লগ পোস্টটি দেখুন: এএসপি.নেট আইডেন্টিটি ২.০: কাস্টমাইজিং ব্যবহারকারী এবং ভূমিকা

এটিতে পুরো প্রক্রিয়াটিতে দুর্দান্ত ধাপে ধাপে তথ্য রয়েছে। এটি পড়ুন:)

এখানে কিছু বেসিক দেওয়া হল।

নতুন বৈশিষ্ট্য যুক্ত করে ডিফল্ট অ্যাপ্লিকেশন ব্যবহারকারী শ্রেণি প্রসারিত করুন (যেমন- ঠিকানা, শহর, রাজ্য, ইত্যাদি):

public class ApplicationUser : IdentityUser
{
    public async Task<ClaimsIdentity> 
    GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        var userIdentity = await manager.CreateIdentityAsync(this,  DefaultAuthenticationTypes.ApplicationCookie);
        return userIdentity;
    }
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }

    // Use a sensible display name for views:
    [Display(Name = "Postal Code")]
    public string PostalCode { get; set; }

    // Concatenate the address info for display in tables and such:
    public string DisplayAddress
    {
        get
        {
            string dspAddress = string.IsNullOrWhiteSpace(this.Address) ? "" : this.Address;
            string dspCity = string.IsNullOrWhiteSpace(this.City) ? "" : this.City;
            string dspState = string.IsNullOrWhiteSpace(this.State) ? "" : this.State;
            string dspPostalCode = string.IsNullOrWhiteSpace(this.PostalCode) ? "" : this.PostalCode;

            return string.Format("{0} {1} {2} {3}", dspAddress, dspCity, dspState, dspPostalCode);
        }
    }

তারপরে আপনি আপনার রেজিস্টারভিউমোডেলে আপনার নতুন বৈশিষ্ট্য যুক্ত করুন।

    // Add the new address properties:
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }

তারপরে নতুন বৈশিষ্ট্য অন্তর্ভুক্ত করতে রেজিস্টার ভিউ আপডেট করুন।

    <div class="form-group">
        @Html.LabelFor(m => m.Address, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.Address, new { @class = "form-control" })
        </div>
    </div>

তারপরে নতুন বৈশিষ্ট্য সহ অ্যাকাউন্টকন্ট্রোলারে নিবন্ধ () পদ্ধতিটি আপডেট করুন।

    // Add the Address properties:
    user.Address = model.Address;
    user.City = model.City;
    user.State = model.State;
    user.PostalCode = model.PostalCode;

16
এটি একটি ভাল উদাহরণ তবে এটি কোনও প্রশ্নের উত্তর দেয় না যা আপনি কীভাবে ব্যবহারকারীর কাছ থেকে এই নতুন বৈশিষ্ট্যগুলি পাবেন।
দেজন বোগাটিনভস্কি

5
ডাউনভোটেড কারণ উত্তরটি কীভাবে কাস্টম বৈশিষ্ট্যগুলি ব্যবহারকারীর কাছ থেকে পুনরুদ্ধার করা যায় তা দেখায় না d পরিচয়।
maulik13

3

যে কেউ এএসপি.নেট কোর ২.১ এ কীভাবে কাস্টম বৈশিষ্ট্যগুলি অ্যাক্সেস করবেন তা সন্ধান করে - এটি অনেক সহজ: আপনার একটি ইউজার ম্যানেজার থাকতে হবে, যেমন _ লগিনপার্টিয়াল সিএসটিএমটিএলে, এবং তখন আপনি সহজেই করতে পারেন ("স্ক্রিননাম" ধরে নিলে এটি একটি সম্পত্তি যা আপনি আপনার নিজের AppUser এ যুক্ত করেছেন যা আইডেন্টিটিউসার থেকে উত্তরাধিকার সূত্রে প্রাপ্ত):

@using Microsoft.AspNetCore.Identity

@using <namespaceWhereYouHaveYourAppUser>

@inject SignInManager<AppUser> SignInManager
@inject UserManager<AppUser> UserManager

@if (SignInManager.IsSignedIn(User)) {
    <form asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Action("Index", "Home", new { area = "" })" 
          method="post" id="logoutForm" 
          class="form-inline my-2 my-lg-0">

        <ul class="nav navbar-nav ml-auto">
            <li class="nav-item">
                <a class="nav-link" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">
                    Hello @((await UserManager.GetUserAsync(User)).ScreenName)!
                    <!-- Original code, shows Email-Address: @UserManager.GetUserName(User)! -->
                </a>
            </li>
            <li class="nav-item">
                <button type="submit" class="btn btn-link nav-item navbar-link nav-link">Logout</button>
            </li>
        </ul>

    </form>
} else {
    <ul class="navbar-nav ml-auto">
        <li class="nav-item"><a class="nav-link" asp-area="Identity" asp-page="/Account/Register">Register</a></li>
        <li class="nav-item"><a class="nav-link" asp-area="Identity" asp-page="/Account/Login">Login</a></li>
    </ul>
}

2
এটি লক্ষ্য করা উচিত যে GetUserAsync(User)OrganisId পুনরুদ্ধার করতে ডাটাবেসটি জিজ্ঞাসা করবে। বিপরীতে, গৃহীত সমাধান দাবিগুলির মধ্যে (যেমন কুকি) অর্গানাইজেশন অন্তর্ভুক্ত করবে। ডাটাবেস থেকে এই তথ্যটি টানানোর সুবিধা হ'ল লোকেরা লগআউট / লগইন না করে সংস্থাগুলির মধ্যে স্থানান্তরিত হতে পারে। অবশ্যই অসুবিধাটি হ'ল এটির জন্য একটি অতিরিক্ত ডাটাবেস ক্যোয়ারী প্রয়োজন।
ম্যাট

1

ধাস্ট অ্যাপ্লিকেশন ব্যবহারকারী শ্রেণিতে সম্পত্তি যুক্ত করার জন্য একটি ভাল উপায় দেয়। ওপি কোডটি দেখে মনে হচ্ছে তারা এটি করেছে বা এটি করতে ট্র্যাকে ছিল। প্রশ্ন জিজ্ঞাসা

আমি কিভাবে একজন নিয়ামকের মধ্যে থেকে বর্তমানে লগ ইন করা ব্যবহারকারীর অর্গানাইজেশন আইডি সম্পত্তি পুনরুদ্ধার করতে পারি? যাইহোক, OrganisId কোনও ব্যবহারকারীর আইডেন্টিটিতে উপলব্ধ সম্পত্তি নয়। OrganisId সম্পত্তি অন্তর্ভুক্ত করার জন্য কি আমার ব্যবহারকারীর পরিচয় বাড়ানো দরকার?

পাভেল একটি এক্সটেনশন পদ্ধতি যুক্ত করার জন্য একটি উপায় দেয় যার জন্য স্টেটমেন্টগুলি ব্যবহার করতে বা ওয়েবকনফাইগ ফাইলটিতে নাম স্থান যুক্ত করা দরকার।

তবে, প্রশ্নটি আপনাকে জিজ্ঞাসা করে যে আপনার "ব্যবহারকারী" প্রসারিত করতে হবে new নতুন সম্পত্তি অন্তর্ভুক্ত করতে পরিচয়। ব্যবহারকারীর পরিচয় না বাড়িয়ে সম্পত্তি অ্যাক্সেস করার বিকল্প উপায় রয়েছে d আপনি যদি ধস্ট পদ্ধতি অনুসরণ করেন তবে নতুন সম্পত্তি অ্যাক্সেস করতে আপনার নিয়ামকটিতে নিম্নলিখিত কোডটি ব্যবহার করতে পারেন।

ApplicationDbContext db = new ApplicationDbContext();
var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(db));
var currentUser = manager.FindById(User.Identity.GetUserId());
var myNewProperty = currentUser.OrganizationId;

0

আমি আমার এস্পনেট ব্যবহারকারীদের টেবিলে অতিরিক্ত কলামগুলি যুক্ত বা প্রসারিত করেছি। আমি যখন এই ডেটাটি কেবল দেখতে চেয়েছি তখন উপরের কোডটির মতো "এক্সটেনশানস" ইত্যাদির মতো অনেকগুলি উদাহরণ পেলাম ... এটি আমাকে সত্যিই অবাক করে দিয়েছে যে আপনি কেবলমাত্র বর্তমান ব্যবহারকারীদের কাছ থেকে কয়েকটি মান পেতে আপনাকে এই সমস্ত কোডের লাইনটি লিখতে হয়েছিল।

দেখা যাচ্ছে যে আপনি অন্যান্য টেবিলের মতো অ্যাস্পনেট ব্যবহারকারীদের টেবিলটি জিজ্ঞাসা করতে পারেন:

 ApplicationDbContext db = new ApplicationDbContext();
 var user = db.Users.Where(x => x.UserName == User.Identity.Name).FirstOrDefault();
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.