asp.net mvc गलत मूल्य के साथ ASP.Net एमवीसी एचटीएमएल। HiddenFor




asp.net-mvc asp.net-mvc-3 (4)

एक विज़ार्ड लिखते समय मुझे एक ही समस्या का सामना करना पड़ा जो प्रत्येक चरण में बड़े मॉडल के विभिन्न हिस्सों को दिखाता है।
"चरण 1" से डेटा और / या त्रुटियां "चरण 2" आदि के साथ मिश्रित हो जाएंगी, जब तक कि मुझे अंततः एहसास हुआ कि मॉडलस्टेट को 'दोष' देना था।

यह मेरा सरल समाधान था:

if (oldPageIndex != newPageIndex) ModelState.Clear(); // <-- solution
return View(model[newPageIndex]);

मैं अपनी परियोजना में एमवीसी 3 का उपयोग कर रहा हूं, और मुझे बहुत अजीब व्यवहार दिखाई दे रहा है।

मैं अपने मॉडल पर किसी विशेष मूल्य के लिए एक छिपी हुई फ़ील्ड बनाने की कोशिश कर रहा हूं, समस्या यह है कि किसी कारण से फ़ील्ड पर मान सेट मॉडल के मान से मेल नहीं खाता है।

जैसे

मेरे पास यह कोड है, बस एक परीक्षण के रूप में:

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

मुझे लगता है कि दोनों छिपे हुए फ़ील्ड का एक ही मूल्य होगा। मैं क्या करता हूं, पहली बार जब मैं दृश्य प्रदर्शित करता हूं, तो मूल्य 1 को सेट करता है, और फिर सबमिशन के बाद मैं मॉडल फ़ील्ड के मान को 1 तक बढ़ाता हूं।

इसलिए, पहली बार जब मैं पृष्ठ को प्रस्तुत करता हूं तो दोनों नियंत्रणों में मान 1 होता है, लेकिन दूसरी बार दिए गए मान ये हैं:

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

जैसा कि आप देख सकते हैं, पहला मान सही है, लेकिन दूसरा मान पहली बार दिखाई देता है जैसा कि मैंने दृश्य प्रदर्शित किया था।

मैं क्या खो रहा हूँ? क्या * एचटीएमएल हेल्पर्स के लिए कुछ तरीकों से मूल्यों को कैश करना है? यदि हां, तो मैं इस कैशिंग को कैसे अक्षम कर सकता हूं?

आपकी सहायता के लिए धन्यवाद.


यह सामान्य है और एचटीएमएल हेल्पर्स कैसे काम करते हैं। वे पहले POST अनुरोध के मूल्य का उपयोग करते हैं और उसके बाद मॉडल में मान। इसका अर्थ यह है कि यदि आप POST अनुरोध में एक ही चर है तो आपके नियंत्रक कार्रवाई में मॉडल के मान को संशोधित करते हैं, तो भी आपके संशोधन को अनदेखा कर दिया जाएगा और पोस्ट किए गए मान का उपयोग किया जाएगा।

एक संभावित कार्यवाही इस मान को नियंत्रक कार्रवाई में मॉडल स्थिति से निकालना है जो मान को संशोधित करने का प्रयास कर रहा है:

// 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;

एक और संभावना एक कस्टम एचटीएमएल सहायक लिखना है जो हमेशा मॉडल के मूल्य का उपयोग करेगा और पोस्ट मूल्यों को अनदेखा करेगा।

और फिर भी एक और संभावना:

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

यह कोड काम नहीं करेगा

// 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)

यह उल्लेख करने लायक है कि यह संग्रह के साथ भी काम करता है।


मैं उसी स्थिति के साथ बहुत संघर्ष कर रहा हूं, जहां मैं सोचता हूं, जहां मैं कॉल के बीच एक ही मॉडल स्थिति का उपयोग करता हूं, और जब मैं बैकएंड पर मॉडल संपत्ति बदलता हूं। हालांकि, यह मेरे लिए कोई फर्क नहीं पड़ता, अगर मैं textboxfor या hiddenfor का उपयोग करता हूं।

मैं मॉडल मान को जेएस वैरिएबल के रूप में स्टोर करने के लिए पेज स्क्रिप्ट का उपयोग कर स्थिति को बाईपास करता हूं, क्योंकि मुझे शुरुआत में उस उद्देश्य के लिए छुपा क्षेत्र की आवश्यकता है।

यकीन नहीं है कि यह मदद करता है लेकिन बस विचार करें ..







html.hiddenfor