c# - 使用 ajax 将 Knockout.js View 模型发布到 ASP.NET MVC Controller 操作会导致空值

标签 c# jquery ajax asp.net-mvc knockout.js

我正在为网站构建一个简单的 CMS。该网站是使用 asp.net mvc 构建的,我使用 knockout.js 进行双向绑定(bind)。我可以将我的值从数据库发送到我的 View 并更改模型值。当我尝试保存修改后的 View 模型时,我的问题出现了。 我使用以下类将数据保存在数据库中:

public class Content
{
    public int ContentId { get; set; }
    public string Name { get; set; }
    public string Value { get; set; }
}

我的完整 View 模型:

public class CmsStartPageViewModel
{
    public string SectionOneTitle {get; set;}
    public string SectionOneText {get; set;}
    public string SectionTwoTitle {get; set;}
    public string SectionTwoText {get; set;}
    public string SectionThreeTitle {get; set;}
    public string SectionFourTitle {get; set;}
    public string BannerOneTitle {get; set;}
    public string BannerOneSubTitle {get; set;}
    public string BannerOneIcon {get; set;}
    public string SectionFiveTitle {get; set;}
    public string SectionFiveSubTitle {get; set;}
    public string ContactTitle {get; set;}
    public string ContactSubTitleOne {get; set;}
    public string ContactText {get; set;}
    public string ContactSubTitleDetails {get; set;}
    public string ContactSubTitleSocial {get; set;}

    public List<SupportingCompany> SupportingCompanies { get; set; }
    public List<ReasonTemplate> ReasonTemplates { get; set; }
    public List<ProductInfoTemplate> ProductInfoTemplates { get; set; }

    //Kontaktformulär Validering

    public string FormFullName { get; set; }
    public string FormEmail { get; set; }
    public string FormSubject { get; set; }
    public string FormMessage { get; set; }


    public void PopulateViewModel(ICollection<StartContent> data)
    {
        var self = this;

        var properties = typeof(CmsStartPageViewModel).GetProperties();

        foreach (PropertyInfo property in properties)
        {
            var type = property.PropertyType;
            if (type == typeof(String) &! property.Name.StartsWith("Form"))
            {
                var value = data.Single(d => d.Name == property.Name);
                property.SetValue(self, value.Value);
            }
        }
    }
}

我的保存功能(knockout.js View 模型):

ViewModel = function(data) {
    var self = this;
    ko.mapping.fromJS(data, {}, self);

    self.save = function () {
        var model = ko.mapping.toJSON(self);
        $.ajax({
            url: "/Cms/SaveViewModel",
            type: "POST",
            data: model,
            dataType: "json",
            contentType: "json",
            success: function(message) {
                ko.mapping.fromJS(data.viewModel, {}, self);
                if (message.Status === "success") {
                    toastr.success(message.Content);
                } else if (message.Status === "error") {
                    toastr.error(message.Content);
                }
            }
        });
    }
}

最后,我的保存操作方法:

    [HttpPost]
    public ActionResult SaveViewModel(CmsPageViewModel model)
    {
        var content = _contentRepo.GetStartContent();

        foreach (var item in content)
        {
            var property = model.GetType().GetProperty(item.Name);
            property.SetValue(model, item.Value);
        }

        _contentRepo.UpdateStartContent(content);

        var message = new StatusMessageCms
        {
            Content = "Your changes has now been saved!",
            Status = "success"
        };

        return Json(message);
    }

更新:

发送到服务器的 JSON 模型。我找不到与我的 C# Viewmodel 任何不匹配的地方

    {
    "SectionOneTitle": "Aja-Baja.se avskräcker stöld och bedrägerier",
    "SectionOneText": "När vi blir tillräckligt många, kan vi stöldförsäkra till ett subventionerat pris.<br />\nIntresse från flera försäkringsbolag finns",
    "SectionTwoTitle": "Om Aja-Baja.se",
    "SectionTwoText": "Vi är två crossmotionärer som ser ett växande problem med stölder av motorcrosscyklar. För att förhindra detta så startar vi ett register där alla kan registrera sina crossar. <br /><br />\n\nDU vill inte köpa en stulen cross och inte heller bli bestulen på dem. Om alla som har en cross eller tänker köpa en, använder registret och sökfunktionen så hjälps vi åt att hålla koll så att det inte blir så intressant att stjäla dem.",
    "SectionThreeTitle": "Varför ska du registrera dig?",
    "SectionFourTitle": "Priser & Specifikationer",
    "BannerOneTitle": "Samarbeta mot inbrottstjuvarna",
    "BannerOneSubTitle": "REGISTRERA DIG HOS AJA-BAJA OCH HÅLL KOLL DU MED!",
    "BannerOneIcon": "fa-users",
    "SectionFiveTitle": "Vi är inte de enda som är entusiastiska inför Aja-Baja.se...",
    "SectionFiveSubTitle": "Flera samarbetspartners tror på vår idé",
    "ContactTitle": "Kontakta Oss",
    "ContactSubTitleOne": "Gör oss <strong>Bättre</strong>",
    "ContactText": "Det är viktigt för oss och veta vad ni som besökare tycker om vår Mobilapp och Webbapplikation. Har ni ett förslag på vad som skulle kunna göras bättre? Eller är det något som ni saknar? Fyll isåfall i formuläret och skicka det till oss. Tillsammans är vi starka!",
    "ContactSubTitleDetails": "Aja-Bajas <strong>Kontaktuppgifter</strong>",
    "ContactSubTitleSocial": "Sociala <strong>Medier</strong>",
    "SupportingCompanies": [{
        "SupportingCompanyId": 1,
        "ImageUrl": "/Content/img/sponsor/alternativ_mc_sponsor.png",
        "LinkUrl": "http://www.alternativ1mc.se/"
    }, {
        "SupportingCompanyId": 2,
        "ImageUrl": "/Content/img/sponsor/eliasson_racing.png",
        "LinkUrl": "http://www.eliassonracing.se/"
    }, {
        "SupportingCompanyId": 3,
        "ImageUrl": "/Content/img/sponsor/KonicaMinolta_Logo.png",
        "LinkUrl": "http://www.konicaminolta.se/sv/home.html"
    }, {
        "SupportingCompanyId": 4,
        "ImageUrl": "/Content/img/sponsor/frisk_sponsor.png",
        "LinkUrl": null
    }],
    "ReasonTemplates": [{
        "ReasonTemplateId": 1,
        "ReasonTitle": "Sökbarhet",
        "ReasonText": "Möjlighet att via ramnummer se om crossen är stulen.",
        "ReasonIcon": "fa-search"
    }, {
        "ReasonTemplateId": 2,
        "ReasonTitle": "Stöldanmälning",
        "ReasonText": "Anmäl snabbt din cross stulen via app eller hemsida.",
        "ReasonIcon": "fa-bullhorn"
    }, {
        "ReasonTemplateId": 3,
        "ReasonTitle": "Samarbetspartners",
        "ReasonText": "Verkstäder och återförsäljare kan kontrollera om crossen är stulen.",
        "ReasonIcon": "fa-users"
    }, {
        "ReasonTemplateId": 4,
        "ReasonTitle": "Ägarbyten",
        "ReasonText": "Ett smidigt och säkert sätt att registrera ett ägarbyte.",
        "ReasonIcon": "fa-refresh"
    }, {
        "ReasonTemplateId": 6,
        "ReasonTitle": "Motverka stölder",
        "ReasonText": "Stöldanmälda registrerade crossar blir svårare att sälja vidare.",
        "ReasonIcon": "fa-lock"
    }, {
        "ReasonTemplateId": 8,
        "ReasonTitle": "Förmåner som kund",
        "ReasonText": "Rabatter hos utvalda verkstäder och butiker.",
        "ReasonIcon": "fa-user"
    }],
    "ProductInfoTemplates": [],
    "FormFullName": null,
    "FormEmail": null,
    "FormSubject": null,
    "FormMessage": null
}

已编辑的问题

我遇到的问题是,当我尝试发布到 Controller 时,所有值均为空。 ajax 命中了正确的操作,但我找不到发布的 JSON 模型和 C# View 模型之间的任何差异。

感谢任何帮助!

马丁·约翰逊

最佳答案

第一:您的 ContentType 不完整!

第二:将数据映射到 self,这是正确的,然后将方法 save() 分配给 self 并将其作为数据通过 post 发送,因此您还发布了 save()

试试这个:

ViewModel = function(data) {
    var self = this;
    var dataToPost = ko.mapping.fromJS(data, {}, self); 

    /* 
       You can pick another name for the variable dataToPost 
       This has to be a valid json, use a debugger or fiddler to see how it looks like
    */

    self.save = function () {
        var model = ko.mapping.toJSON(dataToPost);
            $.ajax({
            url: "/Cms/SaveViewModel",
            type: "POST",
            data: model,
            dataType: "json",
            contentType: "application/json; charset=utf-8",
            success: function(message) {

                ko.mapping.fromJS(data.viewModel, {}, self);

                if (message.Status === "success") {
                    toastr.success(message.Content);
                } else if (message.Status === "error") {
                    toastr.error(message.Content);
                }

            }
        });
    }
}

希望对你有帮助!

关于c# - 使用 ajax 将 Knockout.js View 模型发布到 ASP.NET MVC Controller 操作会导致空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34179915/

相关文章:

c# - 确认框javascript

c# - HttpContext.Current 在 Identity Framework 的方法中为 null

javascript - 如何过滤项目和显示项目

javascript - '$.fn' 为空或不是对象

jquery - Grails + Jquery,纯 HTML 不起作用

c# - AuthenticateAsServer 不接受 PEM 格式的证书

jquery - 无法将 div 容器居中

javascript - Jquery,在前一个函数级联完成后执行一个函数

ASP.NET MVC 中的 ASP.NET AJAX 与 jQuery

c# - 使用反射(PrivateObject)进行测试