@ এইচটিএমএল.হিডেনফোর্ড এএসপি.এনইটি এমভিসির তালিকাগুলিতে কাজ করে না


99

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

@Html.HiddenFor(model => model.MyList)

এই কার্যকারিতাটি সম্পাদন করতে, তবে কোনও কারণে POST এ তালিকা সর্বদা শূন্য থাকে।

খুব সাধারণ প্রশ্ন, এমভিসি কেন এমন আচরণ করে কেউ জানেন?


4
সাধারণত আপনি পুরো তালিকাটি গোপন করবেন না। এর ক্ষেত্রে আপনার কাঙ্ক্ষিত আউটপুটটি কী <input />?
C

4
কি আছে MyList? HiddenForএকবারে কেবল একটি ইনপুট জন্য ব্যবহৃত হয়।
ড্যানিয়েল এ হোয়াইট

4
টাইপ কি Model.MyList? আপনাকে নিজের তালিকায় ম্যানুয়ালি কিছু সিরিয়ালাইজেশন / ডিসরিয়ালাইজেশন করার প্রয়োজন হতে পারে।
কাইল ট্রুবারম্যান

4
[ স্ট্যাকওভারফ্লো . com/ প্রশ্নগুলি / 8৩৮১1871১/২ অনুরূপ প্রশ্ন।
সানজিভী সুব্রামণি

উত্তর:


163

আমি এই সমস্যাটি স্রেফ এসেছি এবং নিম্নলিখিতগুলি দ্বারা সহজভাবে সমাধান করেছি:

@for(int i = 0; i < Model.ToGroups.Length; i++)
{
    @Html.HiddenFor(model => Model.ToGroups[i])
}

ফোরচের পরিবর্তে একটি ব্যবহার করে মডেল বাঁধাই সঠিকভাবে কাজ করবে এবং তালিকায় আপনার সমস্ত লুকানো মানকে বাছাই করবে। এই সমস্যাটি সমাধানের সহজ উপায় বলে মনে হচ্ছে।


4
ধন্যবাদ! আমার রাত বাঁচিয়েছে।
টিএসমিথ

7
ধন্যবাদ - চমৎকার সহজ সমাধান। যদিও কেবল একটি ক্ষুদ্রতর Mod প্রয়োজন: অবজেক্টের আইডি ক্ষেত্রটি উল্লেখ করা দরকার। সুতরাং যদি ক্ষেত্রটিকে রওআইড বলা হয়, তবে:@Html.HiddenFor(model => Model.ToGroups[i].RowId)
কৃষ্ণ গুপ্ত

4
আমার পক্ষে কাজ করেছিল, এমনকি যখন সংগ্রহের মডেলগুলিতে আমার একাধিক ক্ষেত্র ছিল। অর্থাত পরবর্তী সময়ে @Html.EditorFor(model => Model.ToGroups[i].Id)অনুসরণ করা @Html.EditorFor(model => Model.ToGroups[i].Description)- উভয় জন্য লুপ। এবং নিয়ামকটি সেই ক্ষেত্রগুলি সহ মডেলগুলির একটি তালিকায় এটি ম্যাপ করতে সক্ষম হয়েছিল। এবং এর <div style="display: none;"></div>
ডন

উজ্জ্বল! সুন্দরভাবে সম্পন্ন. আমার জন্য কাজ!
এক্সলওক

4
@ ব্যবহারকারী3186023 এখানে সত্যই একটি পুরানো মন্তব্যের জবাব দিচ্ছেন, তবে অন্য forকারওরও একই সমস্যা থাকবে: এটিকে লুপটি পরিবর্তন করুন :for(int i = 0; i < Model.Departments.Count(); i++)
স্টিয়ান

28

হাইডফোর্ড কোনও ডিসপ্লেফোর্ড বা এডিটরফোর্ডের মতো নয়। এটি সংগ্রহগুলির সাথে কাজ করবে না, কেবলমাত্র একক মান।

আপনি কোনও লুকানো ক্ষেত্রের কোনও বিষয়কে সিরিয়ালাইজ করতে এমভিসি ফিউচার প্রজেক্টে উপলব্ধ সিরিয়ালাইজ এইচটিএমএল সহায়ক ব্যবহার করতে পারেন, বা আপনাকে কোডটি নিজেরাই লিখতে হবে। আরও ভাল সমাধান হ'ল কিছু সাজানোর আইডি সিরিয়ালাইজ করা এবং পোস্টব্যাকের ডাটাবেস থেকে ডেটা পুনরায় প্রাপ্ত করা।


আপনার কি উদাহরণ আছে? আমি এটি চেষ্টা করেছিলাম এবং ফর্মটি জমা দেওয়ার সময় এটি ভিউমোডেল মানকে আবদ্ধ করতে ব্যর্থ হয়েছিল।
অ্যালান ম্যাকডোনাল্ড

@ অ্যালানম্যাকডোনাল্ড - যদি কোনও কিছু বাঁধতে ব্যর্থ হয় তবে এটি আপনার নামকরণ সঠিক না হওয়ায় সম্ভবত আপনি সূচকযুক্ত ব্যক্তির পরিবর্তে ফোরচ ব্যবহার করেছিলেন। অথবা সম্ভবত আপনি বাঁধাইয়ের ক্ষেত্রে যথাযথ বৈশিষ্ট্যগুলি ব্যবহার করেন নি। দেখুন weblogs.asp.net/shijuvarghese/archive/2010/03/06/...
এরিক Funkenbusch

ধন্যবাদ আসলে আমি যখন চেষ্টা করেছি তখন এটি ছিল আক্ষরিক @ এইচটিএমএল.শিরাইজ ("Model.ModelIDs", Model.ModelIDs) যেখানে মডেলটি আমার ভিউমোডেল ছিল এবং এতে একটি মডেলআইডিএস ইন্টার অ্যারে সম্পত্তি ছিল। সুতরাং কোন লুপ বা কিছুই ছিল না। ফর্মটি জমা দেওয়া হলে মডেলআইডিগুলি সর্বদা আবদ্ধ ভিউমোডেলে শূন্য থাকে।
অ্যালান ম্যাকডোনাল্ড

@ অ্যালানম্যাকডোনাল্ড - আপনি নামটিতে "মডেল" অন্তর্ভুক্ত করবেন না।
এরিক ফানকেনবাশ

16

এটি কিছুটা হ্যাক, তবে আপনার তালিকার জন্য @Html.EditorForবা যদি এটি @Html.DisplayForকাজ করে তবে আপনি যদি এটি নিশ্চিত করতে চান যে এটি পোস্টের অনুরোধে প্রেরিত হয়েছে তবে দৃশ্যমান নয়, তবে আপনি display: none;এটির পরিবর্তে এটি লুকিয়ে রাখতে স্টাইল করতে পারেন , যেমন:

<div style="display: none;">@Html.EditorFor(model => model.MyList)</div>

এটি অনুরোধের পোস্টে মডেলটির মান সংরক্ষণ করে না।
nldev

যদি .এডিটরফোর্ডটি সঠিকভাবে কাজ করার জন্য সেট আপ করা থাকে, তবে এটিরও কাজ করা উচিত আমি বিশ্বাস করি।
মার্ক রোডস

10

জোনস স্ট্রিংয়ের মাধ্যমে অবজেক্টটি ডিসরিয়ালাইজ করার জন্য নিউটনসফ্ট ব্যবহার করার এবং তারপরে আপনার লুকানো ক্ষেত্রের মধ্যে এটি সন্নিবেশ করানোর বিষয়ে কী হবে ( মডেল.ডাটাআরস্পোনস.ইন্টিটি.কমিশন আপনি জেএসওএন-তে দেখতে পাবেন তাই সাধারণ " কমিশনরেঞ্জ " অবজেক্টের একটি তালিকা )

@using (Ajax.BeginForm("Settings", "AffiliateProgram", Model.DataResponse, new AjaxOptions { UpdateTargetId = "result" }))
   {
      string commissionJson = JsonConvert.SerializeObject(Model.DataResponse.Entity.Commission);
      @Html.HiddenFor(data => data.DataResponse.Entity.Guid)
      @Html.Hidden("DataResponse_Entity_Commission", commissionJson)
      [Rest of my form]
   }

রেন্ডার্স হিসাবে:

<input id="DataResponse_Entity_Commission" name="DataResponse_Entity_Commission" type="hidden" value="[{"RangeStart":0,"RangeEnd":0,"CommissionPercent":2.00000},{"RangeStart":1,"RangeEnd":2,"CommissionPercent":3.00000},{"RangeStart":2,"RangeEnd":0,"CommissionPercent":2.00000},{"RangeStart":3,"RangeEnd":2,"CommissionPercent":1.00000},{"RangeStart":15,"RangeEnd":10,"CommissionPercent":5.00000}]">

আমার ক্ষেত্রে আমি পোস্ট দেওয়ার আগে লুকানো ক্ষেত্রে জসন সম্পাদনা করতে কিছু জেএস স্টাফ করি

আমার নিয়ামকটিতে আমি আবার ডিজিটালাইজ করতে নিউটনসফ্ট ব্যবহার করি:

string jsonCommissionRange = Request.Form["DataResponse_Entity_Commission"];
List<CommissionRange> commissionRange = JsonConvert.DeserializeObject<List<CommissionRange>>(jsonCommissionRange);

এটি আমার পক্ষে কাজ করেছে। আমি ভেবেছিলাম এটি অনেক পরিষ্কার ছিল যে গৃহীত সমাধান।
ই-অন

6

Html.HiddenForশুধুমাত্র একটি মান জন্য ডিজাইন করা হয়েছে। লুকানো ক্ষেত্র তৈরির আগে আপনাকে কোনওভাবে আপনার তালিকাটি সিরিয়ালাইজ করতে হবে।

উদাহরণস্বরূপ, যদি আপনার তালিকা টাইপ স্ট্রিংয়ের হয় তবে আপনি তালিকাটি কমা দ্বারা পৃথক করা তালিকায় যোগ দিতে পারেন, তারপরে পোস্টটিকে পোস্টিং পরে আপনার নিয়ামকের মধ্যে বিভক্ত করুন।


4

আমি ঠিক খুঁজে পেয়েছি (মডেল মানগুলি নিয়ামকটিতে কেন ফিরে আসেনি তা বোঝার কয়েক ঘন্টা চেষ্টা করার পরে) যে জন্য লুকানো আছে এডিটরফোর্ড অনুসরণ করা উচিত।

আমি যদি অন্য কিছু ভুল না করি তবে এটিই আমি খুঁজে পেয়েছি। আমি আর ভুল করব না।

এমন একটি মডেলের প্রসঙ্গে যা অন্য শ্রেণীর একটি তালিকা রয়েছে।

এটি কাজ করবে না:

        @{
            for (int i = 0; i < Model.Categories.Count; i++)
            {
                <tr>
                    <td>
                        @Html.HiddenFor(modelItem => Model.Categories[i].Id)
                        @Html.HiddenFor(modelItem => Model.Categories[i].ProductCategoryId)
                        @Html.HiddenFor(modelItem => Model.Categories[i].CategoryName)                            
                        @Html.DisplayFor(modelItem => Model.Categories[i].CategoryName)                            
                    </td>
                    <td>
                        @Html.HiddenFor(modelItem => Model.Categories[i].DailyPurchaseLimit)                                                        
                        @Html.EditorFor(modelItem => Model.Categories[i].DailyPurchaseLimit)
                        @Html.ValidationMessageFor(modelItem => Model.Categories[i].DailyPurchaseLimit)
                    </td>
                    <td style="text-align: center">
                        @Html.HiddenFor(modelItem => Model.Categories[i].IsSelected)                            
                        @Html.EditorFor(modelItem => Model.Categories[i].IsSelected)
                    </td>
                </tr>
            }
        }

কোথায় এই ......

            for (int i = 0; i < Model.Categories.Count; i++)
            {
                <tr>
                    <td>
                        @Html.HiddenFor(modelItem => Model.Categories[i].Id)
                        @Html.HiddenFor(modelItem => Model.Categories[i].ProductCategoryId)
                        @Html.HiddenFor(modelItem => Model.Categories[i].CategoryName)                            
                        @Html.DisplayFor(modelItem => Model.Categories[i].CategoryName)                            
                    </td>
                    <td>
                        @Html.EditorFor(modelItem => Model.Categories[i].DailyPurchaseLimit)
                        @Html.HiddenFor(modelItem => Model.Categories[i].DailyPurchaseLimit)                            
                        @Html.ValidationMessageFor(modelItem => Model.Categories[i].DailyPurchaseLimit)
                    </td>
                    <td style="text-align: center">
                        @Html.EditorFor(modelItem => Model.Categories[i].IsSelected)
                        @Html.HiddenFor(modelItem => Model.Categories[i].IsSelected)                            
                    </td>
                </tr>
            }

3

আমি এর জন্য সোর্স কোডটি দিয়ে খনন শুরু করেছি HiddenForএবং আমার মনে হয় যে আপনি যে রোডব্লকটি দেখছেন তা হ'ল আপনার জটিল অবজেক্টটি MyListস্পষ্টভাবে টাইপের ক্ষেত্রে রূপান্তরযোগ্য নয় string, সুতরাং কাঠামোটি আপনার Modelমান হিসাবে বিবেচনা nullকরে এবং valueবৈশিষ্ট্যটি খালি উপস্থাপন করে ।



3

একই সমস্যার মুখোমুখি। লুপ ছাড়া, এটি কেবলমাত্র তালিকার প্রথম উপাদানটি পোস্ট করেছে। লুপের মাধ্যমে পুনরাবৃত্তি করার পরে, এটি সম্পূর্ণ তালিকা রাখতে এবং সাফল্যের সাথে পোস্ট করতে পারে।

 @if (Model.MyList!= null)
    {
    for (int i = 0; i < Model.MyList.Count; i++)
      {
        @Html.HiddenFor(x => x.MyList[i])
      }
    }

2

অন্য বিকল্পটি হ'ল:

<input type="hidden" value=@(string.Join(",", Model.MyList)) />

এটি আমার প্রথম ধারণাও ছিল। তবে আমার কাছে একটি ভিউ মডেল ছিল, যা মাইলিস্ট ক্ষেত্র এবং কমা বিভাজিত স্ট্রিংয়ের জন্য কোন ইনট [প্রত্যাশা করেছিল] এমভিসি বাইন্ডিং মেকানিজম দ্বারা অ্যারে হিসাবে বিভক্ত হবে না।
তাদেজ মালি

2

foreachএকটি পরিবর্তে লুপ forলুপ সামান্য ক্লিনার সমাধান হতে পারে।

@foreach(var item in Model.ToGroups)
{
    @Html.HiddenFor(model => item)
}

1

এটির সমাধানের আর একটি সম্ভাব্য উপায় @Html.DropDownListFor(model => model.IDs)হ'ল আপনার তালিকার প্রতিটি বস্তুকে একটি আইডি দেওয়া, তারপরে আইডি ধারণ করে এমন একটি অ্যারের ব্যবহার এবং পপুলেট করা।


1

হতে পারে দেরীতে, তবে সংগ্রহ থেকে লুকানো ক্ষেত্রগুলির জন্য আমি এক্সটেনশন পদ্ধতি তৈরি করেছি (সাধারণ ডেটা ধরণের আইটেম সহ):

সুতরাং এটি এখানে:

/// <summary>
/// Returns an HTML hidden input element for each item in the object's property (collection) that is represented by the specified expression.
/// </summary>
public static IHtmlString HiddenForCollection<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression) where TProperty : ICollection
{
    var model = html.ViewData.Model;
    var property = model != null
                ? expression.Compile().Invoke(model)
                : default(TProperty);

    var result = new StringBuilder();
    if (property != null && property.Count > 0)
    {
        for(int i = 0; i < property.Count; i++)
        {
            var modelExp = expression.Parameters.First();
            var propertyExp = expression.Body;
            var itemExp = Expression.ArrayIndex(propertyExp, Expression.Constant(i));

            var itemExpression = Expression.Lambda<Func<TModel, object>>(itemExp, modelExp);

            result.AppendLine(html.HiddenFor(itemExpression).ToString());
        }
    }

    return new MvcHtmlString(result.ToString());
}

ব্যবহার যেমন সহজ:

@Html.HiddenForCollection(m => m.MyList)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.