2013-05-07 38 views
0

我試圖把一個HTML表單和序列化字段,以便它可以存儲爲JavaScript中的元素的屬性(你可以使用jQuery) 。這可以稍後在C#中解析並轉換爲.NET類型。這必須適用於任何類型,因爲表單是通過對服務器的Ajax調用生成的。在JavaScript中序列化HTML表單,然後轉換爲C#中的.NET類型

例如,給定的格式如下:

<form> 
    <input type="text" name="Assembly" value="MyAssembly.dll" /> 
    <input type="text" name="Class" value="MyClass" /> 
    <input type="text" name="Parameters.Parameter1" value="5" /> 
    <input type="text" name="Parameters.Parameter2" value="10" /> 
</form> 

它會產生這樣的:

<widget assembly="MyAssembly.dll" class="MyClass" parameters="???"></widget> 

注:???將被替換爲JSON或XML(取決於你認爲最好的)。

現在說我將這個字符串存儲在數據庫中,我需要在服務器上解析它以將其轉換爲.NET類型。我可以做一個正則表達式來獲得相應的屬性,讓我用下面的變量:

var assembly = "MyAssembly.dll"; 
var @class = "MyClass"; 
var parameters = "???"; 

現在終於我需要序列化這一個.NET類型。

我會很感激,如果有人可以幫忙。謝謝

+0

首先,我認爲將程序集名稱和類型暴露給html代碼是一個不好的主意,它可能是一個重大的安全漏洞......那麼,容納參數的類會一直存在嗎?或者你打算生成它? – ppetrov 2013-05-07 17:25:36

+0

程序集名稱只會暴露給網站管理員。它將在顯示屏上被替換。該類用作參數傳遞給ASP.NET MVC操作方法的參數。 – nfplee 2013-05-08 07:41:02

+0

你真的從數據庫中得到這個字符串嗎?或者你需要在帖子中獲得相應的模型嗎? – ppetrov 2013-05-08 09:31:59

回答

0

我想出了一些有用的東西。我的解決方案稍微複雜一點,但我會盡量發佈關鍵位以防萬一感興趣。

首先,我創建了以下插件:

$.fn.serializeObject = function(prefix) { 
    var o = {}; 

    // Serialize the form as an array 
    var a = this.serializeArray() 
     .filter($.proxy(function(element) { 
      // Make sure the prefix matches and it is not a checkbox (this is needed since ASP.NET MVC renders a hidden checkbox for the false value) 
      return element.name.indexOf(prefix || '') == 0 && $('[name=\'' + element.name + '\'][type=\'checkbox\']', this).length == 0; 
     }, this)); 

    // Now append the checkbox values (this makes sure we only have one element in the array with the correct value whether it is selected or not) 
    a = a.concat($('input[type=\'checkbox\']', this).map(function() { 
      return { 'name': this.name, 'value': $(this).is(':checked') ? 'true' : 'false' } 
     }).get()); 

    $.each(a, function() { 
     var n = this.name.substr((prefix || '').length); 

     if (o[n] !== undefined) { 
      if (!o[n].push) 
       o[n] = [o[n]]; 

      o[n].push(this.value || ''); 
     } else 
      o[n] = this.value || ''; 
    }); 

    return o; 
}; 

現在我的應用程序其實我有一個所見即所得的插件,嵌入在編輯器中我的自定義窗口小部件標籤。以下是你可以做什麼提交時從表單創建窗口小部件標籤爲例(這將被存儲在數據庫中):您需要更換上顯示小部件

$('form').submit(function(e) { 
    var parameters = JSON.stringify($('form').serializeObject('Parameters.')); 
    var widget = '<widget assembly="' + $('[name=\'Assembly\']').val() + '" class="' + $('[name=\'Class\']').val() + '" parameters="' + parameters + '"></widget>'; 
    ... 
}); 

最後在服務器上通過執行類似:

output = Regex.Replace(output, @"<widget assembly=""(.*?)"" class=""(.*?)"" parameters=""(.*?)""></widget>", m => ReplaceWidget(m, helper)); 

這裏的ReplaceWidget方法:

private static string ReplaceWidget(Match match, HtmlHelper helper) { 
    var assembly = match.Groups[1].Value; 
    var @class = match.Groups[2].Value; 
    var serializedParameters = match.Groups[3].Value; 

    // Get the type 
    var type = Assembly.LoadFrom(HttpContext.Current.Server.MapPath("~/bin/" + assembly)).GetType(@class); 

    // Deserialize the parameters 
    var parameters = JsonConvert.DeserializeObject(HttpUtility.HtmlDecode(serializedParameters), type); 

    // Return the widget 
    return helper.Action("Widget", "Widgets", new { parameters = parameters }).ToString(); 
} 

希望這有助於。