दिलचस्प पोस्ट
सूची <T> से तत्वों को निकालने के लिए LINQ का उपयोग करना मैं कैसे जांच सकता हूं कि Google Maps पूरी तरह भरी हुई है या नहीं? वर्तमान WCF कॉल के लिए डेटा कहाँ स्टोर करना है? थ्रेडस्टैटिक सुरक्षित है? एसक्यूएल सर्वर मैनेजमेंट स्टूडियो विकल्प टेबल को ब्राउज़ / संपादित करने और चलाने के लिए विकल्प सभी जावास्क्रिप्ट घटनाओं की सूची जेक्जरी का उपयोग कर किसी पेज पर वायर्ड करें स्टोरीबोर्ड के बिना एक्सकोड 6 में रिक्त एप्लिकेशन कैसे बनाएं एक स्ट्रिंग में पैटर्न की पहली घटना बदलें बाल राज्यों में कोणीय यूआई राउटर नेस्टेड स्टेट का हल इंटरफ़ेस के खिलाफ प्रोग्रामिंग के द्वारा डाटा जारी रखें लोड पर Angular2 बहुत अधिक फ़ाइल अनुरोध एंड्रॉइड XXHDPI संसाधन छवियों को ओवरले कैसे करें CURLOPT_FOLLOWLOCATION को सक्रिय नहीं किया जा सकता क्या गणना () में शर्त निर्दिष्ट करना संभव है? सी ++ सीरियलाइजेशन ओवरहेड बढ़ाएं

Asp.net MVC मॉडलस्टेट। क्लीअर

क्या कोई मुझे asp.net MVC में ModelState की भूमिका की एक संक्षिप्त परिभाषा दे सकता है (या एक के लिए एक लिंक) विशेष रूप से मुझे यह पता होना चाहिए कि यह ModelState.Clear() क्या है या इसे ModelState.Clear() कॉल करने के लिए वांछनीय है। ModelState.Clear()

बिट खुला समाप्त हो गया … क्षमा करें, मुझे लगता है कि यह आपको बताएगा कि मैं क्या कर रहा हूँ:

मेरे पास "पृष्ठ" नामक एक नियंत्रक पर संपादन की कार्रवाई है जब मैं पहली बार पेज का विवरण बदलना चाहता हूं तो सब कुछ लोड हो जाता है ("MyCmsPage" ऑब्जेक्ट के लिए बाइंडिंग)। फिर मैं एक बटन क्लिक करता हूं जो कि MyCmsPage ऑब्जेक्ट के फ़ील्ड ( MyCmsPage.SeoTitle ) में से एक के लिए एक मान उत्पन्न करता है। यह ठीक जनरेट करता है और ऑब्जेक्ट को अपडेट करता है और फिर मैं नए संशोधित पृष्ठ ऑब्जेक्ट के साथ कार्रवाई परिणाम लौटाता हूं और प्रासंगिक टेक्स्टबॉक्स ( <%= Html.TextBox("seoTitle", page.SeoTitle)%> ) का उपयोग करके अपडेट किया जा सकता है। .. लेकिन अफसोस यह लोड किया गया था कि पुराने मॉडल से मूल्य प्रदर्शित करता है।

मैंने इसे ModelState.Clear() का उपयोग करके इसके आसपास काम किया है लेकिन मुझे यह जानना होगा कि क्यों / यह कैसे काम किया है, इसलिए मैं केवल आँख बंद करके इसे नहीं कर रहा हूँ

PageController:

 [AcceptVerbs("POST")] public ActionResult Edit(MyCmsPage page, string submitButton) { // add the seoTitle to the current page object page.GenerateSeoTitle(); // why must I do this? ModelState.Clear(); // return the modified page object return View(page); } 

aspx:

 <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MyCmsPage>" %> .... <div class="c"> <label for="seoTitle"> Seo Title</label> <%= Html.TextBox("seoTitle", page.SeoTitle)%> <input type="submit" value="Generate Seo Title" name="submitButton" /> </div> 

वेब के समाधान से एकत्रित समाधान "Asp.net MVC मॉडलस्टेट। क्लीअर"

मुझे लगता है कि एमवीसी में एक बग है आज के घंटों के लिए मैं इस मुद्दे से संघर्ष किया

अगर यह दिया रहे:

 public ViewResult SomeAction(SomeModel model) { model.SomeString = "some value"; return View(model); } 

दृश्य मूल मॉडल के साथ प्रस्तुत करता है, परिवर्तनों की अनदेखी कर रहा है तो मैंने सोचा, शायद यह मुझे एक ही मॉडल का उपयोग करना पसंद नहीं करता, इसलिए मैंने इस तरह की कोशिश की:

 public ViewResult SomeAction(SomeModel model) { var newModel = new SomeModel { SomeString = "some value" }; return View(newModel); } 

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

आखिरकार मैंने ऐसा ही काम किया जो आपने किया था:

 public ViewResult SomeAction(SomeModel model) { var newModel = new SomeModel { SomeString = "some value" }; ModelState.Clear(); return View(newModel); } 

अपेक्षित काम करता है

मुझे नहीं लगता कि यह एक "सुविधा" है, है ना?

अद्यतन करें:

  • यह एक बग नहीं है।
  • कृपया POST कार्यवाही से View() लौटना बंद करें इसके बजाय पीआरजी का उपयोग करें और अगर एक सफलता है तो एक जीईटी पर रीडायरेक्ट करें।
  • अगर आप POST कार्रवाई से View() लौट रहे हैं , तो इसे फॉर्म के सत्यापन के लिए करें, और इसे जिस तरह से बनाया गया है, मददगारों के उपयोग से एमवीसी डिजाइन किया गया है। यदि आप ऐसा करते हैं तो आपको उपयोग करने की आवश्यकता नहीं होनी चाहिए। .Clear()
  • यदि आप ModelState वापस करने के लिए इस क्रिया का उपयोग कर रहे हैं, तो एक वेब एपीआई नियंत्रक का उपयोग करें और ModelState भूल ModelState क्योंकि आप इसे वैसे भी उपयोग नहीं करना चाहिए।

पुराना उत्तर:

एमवीसी में मॉडलस्टेट मुख्य रूप से एक मॉडल ऑब्जेक्ट की स्थिति का वर्णन करने के लिए प्रयोग किया जाता है, जिसका मुख्य रूप से संबंध है कि वह ऑब्जेक्ट मान्य है या नहीं। इस ट्यूटोरियल को बहुत समझा जाना चाहिए

आम तौर पर आपको मॉडलस्टेट साफ़ करने की आवश्यकता नहीं है क्योंकि यह आपके लिए एमवीसी इंजन द्वारा बनाए रखा गया है। MVC सत्यापन का पालन करने का प्रयास करते समय मैन्युअल रूप से इसे साफ़ करने से अवांछित परिणाम हो सकते हैं।

ऐसा लगता है कि आप शीर्षक के लिए एक डिफ़ॉल्ट मान सेट करने का प्रयास कर रहे हैं। यह तब किया जाना चाहिए जब मॉडल ऑब्जेक्ट को तत्काल (डोमेन परत को किसी वस्तु में या स्वयं वस्तु में – पैरामीटरलेस सीटीओआर) प्राप्त हो जाना चाहिए, जैसे कि यह पृष्ठ पर पहली बार या पूरी तरह से क्लाइंट पर जाता है (एजेक्स या कुछ और के माध्यम से) ताकि ऐसा प्रतीत हो सके कि उपयोगकर्ता ने इसे दर्ज किया है और यह पोस्ट किए गए फ़ॉर्म संग्रह के साथ वापस आता है। कुछ इस तरह के फॉर्म कलेक्शन (पोस्ट कार्रवाई // संपादन) को प्राप्त करने पर इस वैल्यू को जोड़ने के आपके दृष्टिकोण से इस विचित्र व्यवहार का कारण हो सकता है जिसके परिणाम स्वरूप आपके लिए काम करने के लिए दिखाई देने वाले .Clear() हो। मेरा विश्वास करो – आप स्पष्ट का उपयोग नहीं करना चाहते। अन्य विचारों में से एक को आज़माएं

यदि आप किसी व्यक्तिगत क्षेत्र के लिए एक मूल्य साफ़ करना चाहते हैं तो मुझे निम्नलिखित तकनीक उपयोगी मिल गई है।

 ModelState.SetModelValue("Key", new ValueProviderResult(null, string.Empty, CultureInfo.InvariantCulture)); 

नोट: उस क्षेत्र के नाम पर "कुंजी" बदलें, जिसे आप रीसेट करना चाहते हैं।

अच्छी तरह से ModelState मूल रूप से मान्यता के मामले में मॉडल के वर्तमान राज्य रखती है, यह धारण करता है

ModelErrorCollection: मॉडल को बाँधने की कोशिश करते समय त्रुटियों का प्रतिनिधित्व करें। पूर्व।

 TryUpdateModel(); UpdateModel(); 

या ActionResult में एक पैरामीटर की तरह

 public ActionResult Create(Person person) 

ValueProviderResult : मॉडल के लिए प्रयास किए गए प्रयास के बारे में विवरण पकड़ो। पूर्व। प्रयास, मूल्य, संस्कृति, कच्चावल

स्पष्ट () विधि सावधानी के साथ उपयोग किया जाना चाहिए क्योंकि यह गलत परिणाम उत्पन्न कर सकता है और आप ModelState के कुछ अच्छे गुणों की तरह, AttemptedValue खो देंगे, इसका उपयोग पृष्ठभूमि में एमवीसी द्वारा त्रुटि के मामले में फार्म मूल्यों को फिर से संगृहीत करने के लिए किया जाता है।

 ModelState["a"].Value.AttemptedValue 

मेरे पास एक ऐसा उदाहरण था जहां मैं एक योगित फॉर्म के मॉडल को अपडेट करना चाहता था, और प्रदर्शन के कारण के लिए 'रीडायरेक्ट टू एक्शन' नहीं करना चाहता था मेरे अद्यतित मॉडल पर छिपे हुए क्षेत्रों के पिछले मूल्यों को बनाए रखा जा रहा था – सभी मुद्दों के कारण!

कोड की कुछ पंक्तियों ने जल्द ही मॉडलस्टेट के अंदर तत्वों को पहचान लिया था कि मैं (सत्यापन के बाद) निकालना चाहता था, इसलिए नए मानों को इस रूप में उपयोग किया गया था: –

 while (ModelState.FirstOrDefault(ms => ms.Key.ToString().StartsWith("SearchResult")).Value != null) { ModelState.Remove(ModelState.FirstOrDefault(ms => ms.Key.ToString().StartsWith("SearchResult"))); } 

ठीक है, हममें से बहुत से इस पर काट लिया गया है, और यद्यपि ऐसा होने के कारण समझ में आता है कि मुझे यह सुनिश्चित करने के लिए एक तरीका चाहिए कि मेरे मॉडल का मूल्य दिखाया गया, और मॉडलस्टैट नहीं।

कुछ ने ModelState.Remove(string key) को ModelState.Remove(string key) किया है। ModelState.Remove(string key) , लेकिन यह स्पष्ट नहीं है कि key रूप से नेस्टेड मॉडल यहाँ कुछ तरीके हैं जिनके साथ मैं इस के साथ सहायता करने आया था।

RemoveStateFor विधि एक ModelStateDictionary , एक मॉडल, और वांछित संपत्ति के लिए एक अभिव्यक्ति ले जाएगा, और इसे हटा दें। HiddenForModel का उपयोग मॉडल से केवल मूल्य का उपयोग करके छुपा इनपुट फ़ील्ड बनाने के लिए आपके दृश्य में किया जा सकता है, पहले उसका मॉडलस्टेट एंट्री हटाया जा रहा है (यह आसानी से अन्य सहायक विस्तार विधियों के लिए विस्तारित किया जा सकता है)।

 /// <summary> /// Returns a hidden input field for the specified property. The corresponding value will first be removed from /// the ModelState to ensure that the current Model value is shown. /// </summary> public static MvcHtmlString HiddenForModel<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression) { RemoveStateFor(helper.ViewData.ModelState, helper.ViewData.Model, expression); return helper.HiddenFor(expression); } /// <summary> /// Removes the ModelState entry corresponding to the specified property on the model. Call this when changing /// Model values on the server after a postback, to prevent ModelState entries from taking precedence. /// </summary> public static void RemoveStateFor<TModel, TProperty>(this ModelStateDictionary modelState, TModel model, Expression<Func<TModel, TProperty>> expression) { var key = ExpressionHelper.GetExpressionText(expression); modelState.Remove(key); } 

इस तरह एक नियंत्रक से कॉल करें:

 ModelState.RemoveStateFor(model, m => m.MySubProperty.MySubValue); 

या इस तरह से एक दृश्य से:

 @Html.HiddenForModel(m => m.MySubProperty.MySubValue) 

यह ModelState संपत्ति का नाम प्राप्त करने के लिए System.Web.Mvc.ExpressionHelper का उपयोग करता है

मैं एक मूल्य को अपडेट या रीसेट करना चाहता था, अगर वह काफी मान्य नहीं हुआ, और इस समस्या में भाग लिया।

आसान जवाब, मॉडलस्टेट। निकालें .. समस्याग्रस्त है .. क्योंकि अगर आप सहायकों का प्रयोग कर रहे हैं तो आपको वास्तव में नाम नहीं पता है (जब तक कि आप नामकरण परंपरा से चिपक न दें)। जब तक आप एक ऐसा फ़ंक्शन नहीं बनाते हैं, जो आपके कस्टम सहायक और आपके नियंत्रक का नाम पाने के लिए उपयोग कर सकते हैं।

यह सुविधा सहायक के विकल्प के रूप में कार्यान्वित होनी चाहिए थी, जहां डिफ़ॉल्ट रूप से ऐसा नहीं होता है, लेकिन अगर आप अस्वीकृत इनपुट को फिर से दिखाने के लिए चाहते थे तो आप ऐसा कह सकते हैं।

लेकिन कम से कम मैं अब इस मुद्दे को समझता हूँ;)

इसे अंत में मिला मेरा कस्टम मॉडल बिल्डर जो पंजीकृत नहीं था और यह करता है:

 var mymsPage = new MyCmsPage(); NameValueCollection frm = controllerContext.HttpContext.Request.Form; myCmsPage.SeoTitle = (!String.IsNullOrEmpty(frm["seoTitle"])) ? frm["seoTitle"] : null; 

तो ऐसा कुछ जो डिफ़ॉल्ट मॉडल बाइंडिंग कर रहा था वह समस्या पैदा कर रहा होगा। निश्चित नहीं है कि, लेकिन मेरी समस्या अब कम से कम तय हो गई है कि मेरा कस्टम मॉडल बाइंडर पंजीकृत है।

आम तौर पर, जब आप अपने आप को एक ढांचा मानक प्रथाओं से लड़ते हैं, तो यह आपके दृष्टिकोण पर पुनर्विचार करने का समय है। इस मामले में, मॉडलस्टेट का व्यवहार उदाहरण के लिए, जब आप किसी POST के बाद मॉडल राज्य नहीं चाहते हैं, तो प्राप्त करने के लिए रीडायरेक्ट पर विचार करें।

 [HttpPost] public ActionResult Edit(MyCmsPage page, string submitButton) { if (ModelState.IsValid) { SomeRepository.SaveChanges(page); return RedirectToAction("GenerateSeoTitle",new { page.Id }); } return View(page); } public ActionResult GenerateSeoTitle(int id) { var page = SomeRepository.Find(id); page.GenerateSeoTitle(); return View("Edit",page); } 

संस्कृति टिप्पणी का उत्तर देने के लिए संपादित किया गया:

एक मल्टी-सांस्कृतिक एमवीसी आवेदन को संभालने के लिए मैं इसका उपयोग करता हूं। पहले मार्ग हैंडलर उप-वर्ग:

 public class SingleCultureMvcRouteHandler : MvcRouteHandler { protected override IHttpHandler GetHttpHandler(RequestContext requestContext) { var culture = requestContext.RouteData.Values["culture"].ToString(); if (string.IsNullOrWhiteSpace(culture)) { culture = "en"; } var ci = new CultureInfo(culture); Thread.CurrentThread.CurrentUICulture = ci; Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ci.Name); return base.GetHttpHandler(requestContext); } } public class MultiCultureMvcRouteHandler : MvcRouteHandler { protected override IHttpHandler GetHttpHandler(RequestContext requestContext) { var culture = requestContext.RouteData.Values["culture"].ToString(); if (string.IsNullOrWhiteSpace(culture)) { culture = "en"; } var ci = new CultureInfo(culture); Thread.CurrentThread.CurrentUICulture = ci; Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ci.Name); return base.GetHttpHandler(requestContext); } } public class CultureConstraint : IRouteConstraint { private string[] _values; public CultureConstraint(params string[] values) { this._values = values; } public bool Match(HttpContextBase httpContext,Route route,string parameterName, RouteValueDictionary values, RouteDirection routeDirection) { // Get the value called "parameterName" from the // RouteValueDictionary called "value" string value = values[parameterName].ToString(); // Return true is the list of allowed values contains // this value. return _values.Contains(value); } } public enum Culture { es = 2, en = 1 } 

और यहाँ मैं मार्गों को तार कैसे करता हूं मार्गों को बनाने के बाद, मैं अपने subagent (example.com/subagent1, example.com/subagent2, आदि) में पहले संस्कृति कोड यदि आपको सभी की जरूरत है, तो बस रूट हैंडलर और मार्गों से subagent को हटा दें।

  public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.IgnoreRoute("Content/{*pathInfo}"); routes.IgnoreRoute("Cache/{*pathInfo}"); routes.IgnoreRoute("Scripts/{pathInfo}.js"); routes.IgnoreRoute("favicon.ico"); routes.IgnoreRoute("apple-touch-icon.png"); routes.IgnoreRoute("apple-touch-icon-precomposed.png"); /* Dynamically generated robots.txt */ routes.MapRoute( "Robots.txt", "robots.txt", new { controller = "Robots", action = "Index", id = UrlParameter.Optional } ); routes.MapRoute( "Sitemap", // Route name "{subagent}/sitemap.xml", // URL with parameters new { subagent = "aq", controller = "Default", action = "Sitemap"}, new[] { "aq3.Controllers" } // Parameter defaults ); routes.MapRoute( "Rss Feed", // Route name "{subagent}/rss", // URL with parameters new { subagent = "aq", controller = "Default", action = "RSS"}, new[] { "aq3.Controllers" } // Parameter defaults ); /* remap wordpress tags to mvc blog posts */ routes.MapRoute( "Tag", "tag/{title}", new { subagent = "aq", controller = "Default", action = "ThreeOhOne", id = UrlParameter.Optional}, new[] { "aq3.Controllers" } ).RouteHandler = new MultiCultureMvcRouteHandler(); ; routes.MapRoute( "Custom Errors", "Error/{*errorType}", new { controller = "Error", action = "Index", id = UrlParameter.Optional}, new[] { "aq3.Controllers" } ); /* dynamic images not loaded from content folder */ routes.MapRoute( "Stock Images", "{subagent}/Images/{*filename}", new { subagent = "aq", controller = "Image", action = "Show", id = UrlParameter.Optional, culture = "en"}, new[] { "aq3.Controllers" } ); /* localized routes follow */ routes.MapRoute( "Localized Images", "Images/{*filename}", new { subagent = "aq", controller = "Image", action = "Show", id = UrlParameter.Optional}, new[] { "aq3.Controllers" } ).RouteHandler = new MultiCultureMvcRouteHandler(); routes.MapRoute( "Blog Posts", "Blog/{*postname}", new { subagent = "aq", controller = "Blog", action = "Index", id = UrlParameter.Optional}, new[] { "aq3.Controllers" } ).RouteHandler = new MultiCultureMvcRouteHandler(); routes.MapRoute( "Office Posts", "Office/{*address}", new { subagent = "aq", controller = "Offices", action = "Address", id = UrlParameter.Optional }, new[] { "aq3.Controllers" } ).RouteHandler = new MultiCultureMvcRouteHandler(); routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { subagent = "aq", controller = "Home", action = "Index", id = UrlParameter.Optional }, new[] { "aq3.Controllers" } // Parameter defaults ).RouteHandler = new MultiCultureMvcRouteHandler(); foreach (System.Web.Routing.Route r in routes) { if (r.RouteHandler is MultiCultureMvcRouteHandler) { r.Url = "{subagent}/{culture}/" + r.Url; //Adding default culture if (r.Defaults == null) { r.Defaults = new RouteValueDictionary(); } r.Defaults.Add("culture", Culture.en.ToString()); //Adding constraint for culture param if (r.Constraints == null) { r.Constraints = new RouteValueDictionary(); } r.Constraints.Add("culture", new CultureConstraint(Culture.en.ToString(), Culture.es.ToString())); } } }