2012-08-30 13 views
7

के साथ एएसपी.NET MVC3 में एक JSON मॉडल पोस्ट करना तो, मैं इसके साथ दीवार के खिलाफ अपने सिर को टक्कर लगी हूं, और मुझे इसके लिए कोई अच्छा स्रोत नहीं मिल रहा है। हो सकता है कि मैं भूल रहा हूं कि मॉडल बाध्यकारी सामान एमवीसी 3 में कैसे काम करता है, लेकिन यहां मैं जो करने की कोशिश कर रहा हूं: मेरे पास मॉडल के संपादन को संभालने के लिए नॉकआउट के साथ कुछ संपादक हैं। वहाँ मॉडल के लिए काफी नहीं है:एंटी-जालसाजी टोकन

public class SetupTemplate 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string Template { get; set; } 
} 

कार्रवाई मैं फोन करने के लिए कोशिश कर रहा हूँ के हस्ताक्षर है:

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult UpdateTemplate(SetupTemplate template) 

यहाँ पर एक और सवाल से, मैं इस बल्कि उपयोगी टुकड़ा उठाया पाने के लिए विरोधी जालसाजी टोकन:

window.addAntiForgeryToken = function(data) { 
    data.__RequestVerificationToken = $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val(); 
    return data; 
}; 

कौन सा सब मेरे ajax के माध्यम से एक अद्यतन पोस्ट करने की कोशिश के साथ एक साथ आता है:

payload = window.addAntiForgeryToken(ko.mapping.toJS(self.data)); 
$.ajax({ 
    type: "post", 
    url: endpoint, 
    data: payload, 
    success: function(data) { 
     //Handle success 
    }}); 

कौन सा Chrome डेवलपर टूल

Id:1 
Name:Greeting 
Template: [Template Text] 
__RequestVerificationToken: [The really long anti-forgery token] 

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

मुझे यकीन है कि मुझे कुछ स्पष्ट याद आ रहा है, यह क्या हो सकता है पर कोई अंतर्दृष्टि?

संपादित करें: @Mark के जवाब में, यह करने के लिए कॉल को बदलने:

इस का एक अनुरोध पेलोड में
$.ajax({ 
type: "post", 
dataType: "json", 
contentType: 'application/json', 
url: endpoint, 
data: JSON.stringify(payload), 
success: function(data) { 
    //Do some stuff 
}}); 

परिणाम:

{"Id":1,"Name":"Greeting","Template":"...","__RequestVerificationToken":"..."}: 

और सर्वर रोधी उठा नहीं जाली टोकन पैरामीटर के साथ $.ajax() दोनों के साथ और बिना दोनों की कोशिश की गई थी।

उत्तर

1

@Mark मुझे इस के लिए सही रास्ते नीचे अग्रणी है, और कुछ लिंक है कि अब मुझे टोकन बल्कि पारदर्शी रूप से विरोधी जालसाजी संभालने दें पर मुझे इशारा कर के लिए श्रेय दिया जाता है।

public ActionResult UpdateTemplate(SetupTemplate template) 

लिए:

public ActionResult UpdateTemplate(SetupTemplate model) 

और अब यह ठीक से मूल्यों में भरने के है फिर भी, क्या इस मुद्दे को बदल रहा था हल किया। मैं वास्तव में जानना चाहता हूं कि यह क्यों तय हुआ, लेकिन अभी के लिए, यह काम करता है।

1

क्या आप JSON.stringify का उपयोग करने का प्रयास कर सकते हैं?

$.ajax({  
    type: "post",  
    url: endpoint,  
    data: JSON.stringify(payload),  
    success: function(data) {   
     //Handle success  
    } 
}); 
+0

के रूप में काम करता है मैंने इस प्रतिक्रिया के साथ अपना प्रश्न अपडेट किया। संक्षेप में: अभी भी कोई पासा नहीं है। –

+1

क्या यह पोस्ट http://haacked.com/archive/2011/10/10/preventing-csrf-with-ajax.aspx आपकी मदद करता है? – VJAI

+0

और यह http://stackoverflow.com/questions/2906754/how-can-i-supply-an-antiforgerytoken-when-posting-json-data-using-ajax – VJAI

2

मानचित्रण पैरामीटर के रूप में पैरामीटर के साथ काम नहीं करता है क्योंकि यह उस संपत्ति के साथ संघर्ष करता है जिसमें समान नाम (असर केस) होता है। यदि आप टेम्पलेट के अलावा कुछ भी उपयोग करते हैं तो यह उस नियंत्रक पैरामीटर के लिए अच्छा काम करेगा।

विवरणों को समझाते हुए एक ऐसा लिंक है, मैं अब आसानी से नहीं ढूंढ पा रहा हूं।

public class SetupTemplate 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string Template { get; set; } 
} 
2

मेरा समाधान यहां है।इस तरह एक jQuery फ़ंक्शन को परिभाषित करें:

(function ($) { 
    $.getAntiForgeryToken = function() { 
     return $('input[name="__RequestVerificationToken"]').val(); 
    }; 

    // (!) use ValidateJsonAntiForgeryToken attribute in your controller 
    $.ajaxJsonAntiforgery = function (settings) { 

     var headers = {}; 
     headers['__RequestVerificationToken'] = $.getAntiForgeryToken(); 

     settings.dataType = 'json'; 
     settings.contentType = 'application/json; charset=utf-8'; 
     settings.type = 'POST'; 
     settings.cache = false; 
     settings.headers = headers; 
     return $.ajax(settings); 
    }; 
})(jQuery); 

यह केवल आपके सत्यापन टोकन को शीर्षकों पर रखता है। अपने एंटीफॉर्गेरी टोकन को जांचने के लिए आपको फ़िल्टर विशेषता की भी आवश्यकता है। संदेश यह है:

[Authorize, HttpPost, ValidateJsonAntiForgeryToken] 
public ActionResult Index(MyViewModel viewModel) 

और क्लाइंट की तरफ:

$.ajaxJsonAntiforgery({ 
    data: dataToSave, 
    success: function() { alert("success"); }, 
    error: function() { alert("error"); } 
}); 

यह काम करता है

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Helpers; 
using System.Web.Mvc; 

namespace MyProject.Web.Infrastructure.Filters 
{ 

    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, 
        AllowMultiple = false, Inherited = true)] 
    public sealed class ValidateJsonAntiForgeryTokenAttribute 
           : FilterAttribute, IAuthorizationFilter 
    { 
     public void OnAuthorization(AuthorizationContext filterContext) 
     { 
      if (filterContext == null) 
      { 
       throw new ArgumentNullException("filterContext"); 
      } 

      var httpContext = filterContext.HttpContext; 
      var cookie = httpContext.Request.Cookies[AntiForgeryConfig.CookieName]; 
      AntiForgery.Validate(cookie != null ? cookie.Value : null, 
           httpContext.Request.Headers["__RequestVerificationToken"]); 
     } 
    } 
} 

अपने नियंत्रक में यह वास्तव में आसान है, बस उसे नई विशेषता (ValidateJsonAntiForgeryToken) के साथ चिह्नित है मेरे लिए। का आनंद लें!

+1

वह एक चैंप @ रोमन-पुशकिन की तरह काम करता था। अपना समाधान पोस्ट करने के लिए धन्यवाद। –

+0

कुछ समय बाद मैंने पाया कि "__RequestVerificationToken" एक अच्छा नाम नहीं है। "X-RequestVerificationToken" चुनना बेहतर है, इसलिए प्रॉक्सी सर्वर इस हेडर को जाने देंगे। –

0

असल में निम्नलिखित ने जटिल वस्तु के साथ मेरे लिए काम किया; नोट के

var application = { 
    Criteria: { 
     ReferenceNumber: $("input[name='Criteria.ReferenceNumber'").val() 
    }, 
    AppliedVia: "Office" 
}; 

// get the next step 
$.ajax({ 
    url: form.attr("action"), 
    dataType: "html", 
    type: "POST", 
    data: { 
     __RequestVerificationToken: $("input[name=__RequestVerificationToken]").val(), 
     application: application 
    }, 
} 

एक बात हालांकि लगता है कि बाईं applicationdata में अपने विधि/कार्रवाई में वास्तविक पैरामीटर का नाम होना चाहिए बनाना है। यह एमवीसी 5 (प्री .NET कोर)

संबंधित मुद्दे