চেকবক্সফোর কেন একটি অতিরিক্ত ইনপুট ট্যাগ সরবরাহ করে এবং আমি ফর্মোকল্যাকশনটি ব্যবহার করে কীভাবে মান পেতে পারি?


130

আমার এএসপি.নেট এমভিসি অ্যাপে আমি নীচের কোডটি ব্যবহার করে একটি চেকবক্স রেন্ডার করছি:

<%= Html.CheckBoxFor(i=>i.ReceiveRSVPNotifications) %>

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

FormValues["ReceiveRSVPNotifications"]

আমি "সত্য, মিথ্যা" মানটি পাই। রেন্ডার করা এইচটিএমএলটি দেখার সময় আমি নিম্নলিখিতগুলি দেখতে পারি:

 <input id="ReceiveRSVPNotifications" name="ReceiveRSVPNotifications" value="true" type="checkbox">
 <input name="ReceiveRSVPNotifications" value="false" type="hidden">

সুতরাং ফর্মভ্যালু সংগ্রহগুলি একই নাম হওয়ায় এই দুটি মানগুলিতে যোগ দেবে বলে মনে হচ্ছে।

কোন ধারনা?

উত্তর:


168

এখানে একবার দেখুন:

http://forums.asp.net/t/1314753.aspx

এটি কোনও ত্রুটি নয়, এবং বাস্তবে একই পদ্ধতি যা রেল ও মনোরেল উভয়ই ব্যবহার করে।

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

চেকবাক্সটি চেক করা হলে, মডেলবাইন্ডার স্বয়ংক্রিয়ভাবে 'সত্য, মিথ্যা' থেকে 'সত্য' বের করে নেওয়ার যত্ন নেবে


10
এটি একটি ভাল ব্যাখ্যা তবে কিছু ক্ষেত্রে সেকেকবক্সটি চেক না করা অবস্থায় আপনি কোয়েরি স্ট্রিংয়ে 'কিছুই না' পেতে চাইতে পারেন - তাই ডিফল্ট আচরণ। এইচটিএমএল সহায়ক ব্যবহার করে কি এটি সম্ভব বা আমাকে কেবল <input>ট্যাগটি ব্যবহার করতে হবে ?
ম্যাকসিমিলিয়ান মাজার

13
আমি এটি পছন্দ করি না .... আমার কাছে একটি অনুসন্ধান পৃষ্ঠা রয়েছে যা জিইটি ব্যবহার করে এবং এখন আমার ইউআরএল সত্য / মিথ্যা প্যারামে পূর্ণ ...
শন ম্লেয়ান

1
বাহ, এটি অপ্রত্যাশিত। এর অর্থ কি এইচটিএমএল চেকবক্সটি আসলে "ভাঙ্গা"?
ইসানটিপভ

1
@ ইসান্টিপভ: না, এর অর্থ কেবল এই যে এই ওয়েব ফ্রেমওয়ার্কগুলি একটি চেকবাক্স নির্দেশিত করার জন্য কোনও পোস্ট মানের অভাবে নির্ভর করে না false। নীচে রায়ানজেএমসিগওয়ানের উত্তরটি দেখুন: "একটি লুকানো ইনপুট পাঠানো এটি জানতে সক্ষম করে যে অনুরোধটি জমা দেওয়ার সময় পৃষ্ঠায় চেকবক্সটি উপস্থিত ছিল" "
রবার্ট হার্ভে

1
আচ্ছা @ রবার্ট, এটি আমার পক্ষে কাজ করে না। যদি আমার চিবক্স মাইচেকবক্সটি চেক না করা হয় তবে আমি মিথ্যা হয়ে যাই, যখন মাইচেকবক্সটি চেক করা হয় তখন আমি এর মান হিসাবে [সত্য, মিথ্যা] এর অ্যারে পাই। আমি পুরো ফর্মটি সিরিয়ালাইজ করছি এবং এজ্যাক্সের মাধ্যমে এটি নিয়ামক পদক্ষেপে প্রেরণ করছি। অ্যাডটুআর্ডার (মাইমোডেল মডেল) যেখানে আমি মডেলটি পাই M আমারচেকবক্স = সত্যের পরিবর্তে মিথ্যা
নিকর্নোটো

18

শান (উপরে) এর মতো আমারও একই সমস্যা ছিল। এই পদ্ধতির পোষ্টের জন্য দুর্দান্ত হতে পারে, কিন্তু এটি সত্যিই জিইটি-র জন্য সফল হয়। অতএব আমি একটি সাধারণ এইচটিএমএল এক্সটেনশন বাস্তবায়ন করেছি যা কেবল গোপন ক্ষেত্রটিকে চাবুক দিয়ে দেয়।

public static MvcHtmlString BasicCheckBoxFor<T>(this HtmlHelper<T> html, 
                                                Expression<Func<T, bool>> expression,
                                                object htmlAttributes = null)
{
    var result = html.CheckBoxFor(expression).ToString();
    const string pattern = @"<input name=""[^""]+"" type=""hidden"" value=""false"" />";
    var single = Regex.Replace(result, pattern, "");
    return MvcHtmlString.Create(single);
}

আমার এখন সমস্যাটি হ'ল আমি আমার কোডটি ভেঙে এমভিসি কাঠামোর পরিবর্তন চাই না। সুতরাং আমাকে নিশ্চিত করতে হবে যে আমার কাছে এই নতুন চুক্তিটি ব্যাখ্যা করে পরীক্ষার কভারেজ রয়েছে।


5
আপনি কি কিছুটা নোংরামি অনুভব করেন না যে আপনি কেবলমাত্র একটি চেকবক্স ইনপুট তৈরির চেয়ে লুকানো ইনপুটটি মেলে / মুছে ফেলার জন্য আপনি রেজেক্স ব্যবহার করেছিলেন ? :)
টিম হাবস

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

10
শুধু একটি ছোট পর্যবেক্ষণ। আপনার বাস্তবায়নটি পাস হওয়া কোনও কাস্টম বৈশিষ্ট্য সরবরাহ করবে না। "HtmlAttributes" প্যারামিটারটি মূল "চেকবক্সফোর্ড" পদ্ধতিতে প্রেরণ করা হয়নি।
এমিল লুন্ডিন

16

জিইটি ফর্মগুলির জন্য চেকবক্সগুলি রেন্ডার করতে আমি এই বিকল্প পদ্ধতিটি ব্যবহার করি:

/// <summary>
/// Renders checkbox as one input (normal Html.CheckBoxFor renders two inputs: checkbox and hidden)
/// </summary>
public static MvcHtmlString BasicCheckBoxFor<T>(this HtmlHelper<T> html, Expression<Func<T, bool>> expression, object htmlAttributes = null)
{
    var tag = new TagBuilder("input");

    tag.Attributes["type"] = "checkbox";
    tag.Attributes["id"] = html.IdFor(expression).ToString();
    tag.Attributes["name"] = html.NameFor(expression).ToString();
    tag.Attributes["value"] = "true";

    // set the "checked" attribute if true
    ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
    if (metadata.Model != null)
    {
        bool modelChecked;
        if (Boolean.TryParse(metadata.Model.ToString(), out modelChecked))
        {
            if (modelChecked)
            {
                tag.Attributes["checked"] = "checked";
            }
        }
    }

    // merge custom attributes
    tag.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));

    var tagString = tag.ToString(TagRenderMode.SelfClosing);
    return MvcHtmlString.Create(tagString);
}

এটি ক্রিস কেম্পের পদ্ধতির মতো, যা সূক্ষ্মভাবে কাজ করছে, বাদে এটি অন্তর্নিহিত এবং ব্যবহার করে না । এটি মূল পদ্ধতির উত্সের ভিত্তিতে ।CheckBoxForRegex.ReplaceHtml.CheckBoxFor


এটি এই সমস্যার একেবারে সেরা সমাধান এবং এমভিসি কাঠামোর অংশ হওয়া উচিত ... এটি নিখুঁতভাবে কাজ করে। আমি নিশ্চিত না কেন আপনার উত্তরটি আরও মনোযোগ পেল না ... ধন্যবাদ!
ব্যবহারকারী 2315985

@ ব্যবহারকারী 2315985: আমি এটি কিছুটা দেরিতে পোস্ট করেছি;) এটি কারণ।
টম পাউরেক

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

@TiesonT। আপনি নিজের মডেল বাইন্ডার লিখতে না চাইলে ফাঁকা প্রতিরোধের একমাত্র সমাধান। এই পদ্ধতিটি চেক না হওয়া চেকবক্সগুলির জন্য মিথ্যা প্রেরণ করে না, তাই আপনি এটি করতে পারেন যে মূল এইচটিএমএল.চেকবক্সের জন্য পদ্ধতিটি ব্যবহার করতে পারেন।
টম পাউরেক

10

অতিরিক্ত ইনপুট ট্যাগের জন্য উত্স কোডটি এখানে । মাইক্রোসফ্ট এই মতামতগুলিকে অন্তর্ভুক্ত করতে যথেষ্ট সদয় ছিল যে এটিকে সঠিকভাবে সম্বোধন করে।

if (inputType == InputType.CheckBox)
{
    // Render an additional <input type="hidden".../> for checkboxes. This
    // addresses scenarios where unchecked checkboxes are not sent in the request.
    // Sending a hidden input makes it possible to know that the checkbox was present
    // on the page when the request was submitted.
    StringBuilder inputItemBuilder = new StringBuilder();
    inputItemBuilder.Append(tagBuilder.ToString(TagRenderMode.SelfClosing));

    TagBuilder hiddenInput = new TagBuilder("input");
    hiddenInput.MergeAttribute("type", HtmlHelper.GetInputTypeString(InputType.Hidden));
    hiddenInput.MergeAttribute("name", fullName);
    hiddenInput.MergeAttribute("value", "false");
    inputItemBuilder.Append(hiddenInput.ToString(TagRenderMode.SelfClosing));
    return MvcHtmlString.Create(inputItemBuilder.ToString());
}

9

আমি মনে করি যে সহজ সমাধান হ'ল ইনপুট উপাদানটি সরাসরি নীচে রেন্ডার করা:

<input type="checkbox" 
       id="<%=Html.IdFor(i => i.ReceiveRSVPNotifications)%>"
       name="<%=Html.NameFor(i => i.ReceiveRSVPNotifications)%>"
       value="true"
       checked="<%=Model.ReceiveRSVPNotifications ? "checked" : String.Empty %>" />

রেজার সিনট্যাক্সে এটি আরও সহজ, কারণ যখন 'সত্য' সার্ভার-সাইড মান দেওয়া হয় তখন 'পরীক্ষিত' বৈশিষ্ট্যটি সরাসরি "পরীক্ষিত" মানের সাথে রেন্ডার হয়।

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