ভুল মান সহ এএসপি.নেট এমভিসি এইচটিএমএল.হাইডেন


132

আমি আমার প্রকল্পে এমভিসি 3 ব্যবহার করছি এবং আমি খুব অদ্ভুত আচরণ দেখছি।

আমি আমার মডেলটিতে একটি নির্দিষ্ট মানের জন্য একটি লুকানো ক্ষেত্র তৈরি করার চেষ্টা করছি, সমস্যাটি হ'ল কোনও কারণে ক্ষেত্রের উপর সেট মানটি মডেলের মানের সাথে মিলে না।

যেমন

আমার কাছে এই কোডটি রয়েছে, ঠিক যেমন একটি পরীক্ষা:

<%:Html.Hidden("Step2", Model.Step) %>
<%:Html.HiddenFor(m => m.Step) %>

আমি ভাবব যে দুটি লুকানো ক্ষেত্রেই একই মান থাকবে same আমি যা করি তা হ'ল আমি প্রথমবার প্রদর্শনটি প্রদর্শনের জন্য 1 তে মান সেট করে এবং তারপরে জমা দেওয়ার পরে আমি মডেল ক্ষেত্রের মান 1 দ্বারা বাড়িয়ে দেব।

সুতরাং, আমি প্রথমবার পৃষ্ঠাটি রেন্ডার করি উভয় কন্ট্রোলের মান 1 হয় তবে দ্বিতীয়বারের সাথে রেন্ডার করা মানগুলি হ'ল:

<input id="Step2" name="Step2" type="hidden" value="2" />
<input id="Step" name="Step" type="hidden" value="1" />

আপনি দেখতে পাচ্ছেন, প্রথম মানটি সঠিক, তবে দ্বিতীয় মানটি আমি প্রথমবার প্রদর্শনটি প্রদর্শিত হিসাবে একই বলে মনে হয়।

আমি কী মিস করছি? * এইচটিএমএল সহায়কদের জন্য কি কোনও উপায়ে মানগুলি ক্যাশে করা হচ্ছে? যদি তা হয় তবে আমি এই ক্যাচিংটি কীভাবে অক্ষম করতে পারি?

আপনার সাহায্যের জন্য ধন্যবাদ.


আমি সবেমাত্র অন্য কিছু পরীক্ষা করেছি। আমি যদি হিডফোর্ড কলটি সরিয়ে ফেলে এবং কেবল লুকানো কলটিই করি তবে "পদক্ষেপ" নামটি ব্যবহার করে, এটি কেবল প্রথম মানটিকে (1) রেন্ডার করে।
willvv

1
সাথে সাথে ঘটে
ওরেেন এ

উত্তর:


191

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

সম্ভাব্য একটি কার্যকর সমাধান হ'ল নিয়ন্ত্রক ক্রিয়ায় মডেল রাষ্ট্র থেকে এই মানটি সরিয়ে ফেলা যা মানটি সংশোধন করার চেষ্টা করছে:

// remove the Step variable from the model state 
// if you want the changes in the model to be
// taken into account
ModelState.Remove("Step");
model.Step = 2;

আর একটি সম্ভাবনা হ'ল একটি কাস্টম এইচটিএমএল সহায়ক লিখুন যা সর্বদা মডেলের মান ব্যবহার করবে এবং পোস্ট মানগুলি উপেক্ষা করবে ignore

এবং আরও একটি সম্ভাবনা:

<input type="hidden" name="Step" value="<%: Model.Step %>" />

5
আমি এই সম্পর্কে সাইমন ইনস এর ব্লগ পোস্ট সত্যিই প্রশংসা। আপনার কার্যপ্রবাহটি সঠিক কিনা তা নিশ্চিত করার জন্য আমি এটি থেকে উপসংহারটি নিয়েছি। সুতরাং আপনি যদি কোনও বৈধ দৃশ্যের মডেল গ্রহণ করেছেন এবং এর সাথে কিছু করেছেন তবে একটি নিশ্চিতকরণ ক্রিয়ায় পুনর্নির্দেশ করুন, এমনকি যদি এটি সহজেই পুনরুদ্ধার করে এবং একটি সমমানের মডেল প্রদর্শন করে। এর অর্থ আপনার কাছে একটি নতুন মডেলস্টেট রয়েছে। ব্লগস.এমএসডিএন / বি / সিমোননস / অর্চিভ / ২০০০/০/0/২০১৫ (আমি আজকে এই লেখা একটি পোস্ট থেকে লিঙ্ক করেছি: oceanbites.blogspot.com/2011/02/mvc-renders-wrong-value.html )
লিসা

2
আমি সত্যিই এমভিসি 3 পছন্দ করি তবে এই বিটটি সত্যিই আটকানো। আমি আশা করি তারা এটি এমভিসি 4 এ স্থির করেছেন।
কেনেজেড

5
বাহ, এই একজন আমাকে বেশ কিছুক্ষণ যাচ্ছিলেন। আমি প্রথমে প্রথম পরামর্শটি ব্যবহার করেছি তবে ফিরে আসার আগে মডেলস্টেট.ক্লেয়ার () বলেছি called এটি দুর্দান্ত কাজ করছে বলে মনে হচ্ছে, ক্লিয়ার ব্যবহার না করার কোনও কারণ আছে কি?
জেসন

1
"। সরানো" আমার পক্ষে কাজ করে না। কিন্তু মডেলস্টেট.ক্লায়ার () কন্ট্রোলারে ফিরে আসার ঠিক আগেই করেছিল। আপনার লুকানো কাস্টম-লেখাও ভাল কাজ করবে। এটি সব ঘটায় কারণ বিকাশকারীরা "জমা দিন" টিপলে এবং ডিবি সঠিকভাবে সংরক্ষণ না করে তবে তাদের "ফর্মের মানগুলি" হারাতে চান না। সেরা সমাধান: একই পৃষ্ঠায় বিভিন্ন ক্ষেত্রের একই নাম / আইডি রাখবেন না।
ডেক্সটার

1
এফওয়াইআই এই বিরক্তিকর আচরণটি করুণভাবে এএসপি.নেট কোরের হাতে নিয়ে গিয়েছিল যদি কেউ উদ্বিগ্ন যে বিষয়গুলি আরও ভাল হয়ে উঠবে
জন হারগ্রোভ

19

উইজার্ড লেখার সময় আমি একই সমস্যার মুখোমুখি হয়েছি যা প্রতিটি পদক্ষেপে বৃহত্তর মডেলের বিভিন্ন অংশ দেখায়।
"পদক্ষেপ 1" থেকে ডেটা এবং / বা ত্রুটিগুলি "ধাপ 2" ইত্যাদির সাথে মিশ্রিত হয়ে উঠবে যতক্ষণ না অবশেষে আমি বুঝতে পারি যে মডেলস্টেটটি 'দোষারোপ' করার জন্য।

এটি ছিল আমার সহজ সমাধান:

if (oldPageIndex != newPageIndex)
{
    ModelState.Clear(); // <-- solution
}

return View(model[newPageIndex]);

10
ModelState.Clear()অনুরূপ পরিস্থিতিতে ক্রমিক পোস্টের অনুরোধগুলির সাথে আমার সমস্যাটি সমাধান করুন।
ইভান মুলাওস্কি

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

1

এই কোড কাজ করবে না

// remove the Step variable from the model state
// if you want the changes in the model to be
// taken into account
ModelState.Remove("Step");
model.Step = 2;

... কারণ হাইডফোর্ড সর্বদা (!) মডেলস্টেট থেকে পড়ে মডেল নয়। এবং যদি এটি "পদক্ষেপ" কীটি না খুঁজে পায় তবে এটি সেই পরিবর্তনশীল প্রকারের জন্য ডিফল্ট উত্পাদন করে যা এই ক্ষেত্রে 0 হবে

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

public static class CustomExtensions
{
    public static MvcHtmlString HiddenFor2<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
    {
        ReplacePropertyState(htmlHelper, expression);
        return htmlHelper.HiddenFor(expression);
    }

    public static MvcHtmlString HiddenFor2<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes)
    {
        ReplacePropertyState(htmlHelper, expression);
        return htmlHelper.HiddenFor(expression, htmlAttributes);
    }

    public static MvcHtmlString HiddenFor2<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes)
    {
        ReplacePropertyState(htmlHelper, expression);
        return htmlHelper.HiddenFor(expression, htmlAttributes);
    }

    private static void ReplacePropertyState<TModel, TProperty>(HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
    {
        string text = ExpressionHelper.GetExpressionText(expression);
        string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(text);
        ModelStateDictionary modelState = htmlHelper.ViewContext.ViewData.ModelState;
        ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);

        if (modelState.ContainsKey(fullName))
        {                
            ValueProviderResult currentValue = modelState[fullName].Value;
            modelState[fullName].Value = new ValueProviderResult(metadata.Model, Convert.ToString(metadata.Model), currentValue.Culture);
        }
        else
        {
            modelState[fullName] = new ModelState
            {
                Value = new ValueProviderResult(metadata.Model, Convert.ToString(metadata.Model), CultureInfo.CurrentUICulture)
            };
        }
    }
}

তারপরে আপনি যা দেখেন তার মধ্যে থেকে এটি যথারীতি ব্যবহার করুন:

@Html.HiddenFor2(m => m.Id)

এটি উল্লেখ করার মতো এটি সংগ্রহের সাথেও কাজ করে।


এই সমাধান সম্পূর্ণরূপে কাজ করে না। পরবর্তী পোস্টের পরে সম্পত্তি ক্রিয়াকলাপে বাতিল হয়
user576510

ঠিক আছে, এটি উত্পাদন থেকে কোড যেখানে এটি সূক্ষ্ম কাজ করে। এটি আপনার পক্ষে কেন কাজ করে না তা আমি বলতে পারি না তবে আপনি যদি পৃষ্ঠায় সঠিক মানের সাথে লুকানো ক্ষেত্রটি রেন্ডার করে দেখেন তবে মডেলের সম্পত্তিতে এটি পুনরুদ্ধার করা হবে না তার কোনও স্পষ্ট কারণ আমি দেখতে পাচ্ছি না। আপনি যদি পৃষ্ঠায় ভুল লুকানো ফিল্ডের মান দেখতে পান - তবে এটি অন্য গল্প, আমার প্রযোজনায় একই ঘটনা ঘটে যাওয়ার আগে কী পরিস্থিতিতে এটি ঘটে তা জানতে আমি খুব আগ্রহী হব :-) আপনাকে ধন্যবাদ।
রুসলান জর্জিভস্কিই

0

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

আমি কেবল জেসি ভেরিয়েবল হিসাবে মডেল মান সংরক্ষণ করতে পৃষ্ঠা স্ক্রিপ্টগুলি ব্যবহার করে পরিস্থিতিটিকে বাইপাস করছি, কারণ শুরুর দিকে সেই উদ্দেশ্যে আমার গোপনক্ষেত্রের প্রয়োজন।

নিশ্চিত না যে এটি সাহায্য করে তবে কেবল বিবেচনা করুন ..

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