【问题标题】:Dynamically add controls in ASP.NET: factory pattern design pattern?在 ASP.NET 中动态添加控件:工厂模式设计模式?
【发布时间】:2022-10-15 01:15:18
【问题描述】:

我试图了解如何将这些 JSON 数据转换为工厂模式设计模式。下面的 JSON 数据有两个MeetingPollingQuestionType,一个用于LongAnswerText,一个用于MultipleChoice。从那我需要两个类ConcreteStrategyLongAnswerTextMultipleChoice? MeetingPollingPartsValues 是不同的两个。 LongAnswerText 只有一个标签控件,但 MultipleChoice 有单选控件

任何帮助都会很棒,目标是创建一个带有 MVC 控件(如标签文本框和单选列表)的 MVC 表单。

[
    {
        "MeetingPollingQuestionId": 2,
        "MeetingPollingQuestionType": "LongAnswerText",
        "MeetingPollingId": 3,
        "SequenceOrder": 1,
        "MeetingPollingParts": [
            {
                "MeetingPollingPartsId": 2,
                "Type": "Question",
                "MeetingPollingQuestionId": 2,
                "MeetingPollingPartsValues": [
                    {
                        "Type": "label",
                        "QuestionValue": "This is a long question",
                        "FileManagerId": 0,
                        "FileName": null,
                        "FileData": null,
                        "FileType": null
                    }
                ]
            }
        ]
    },
    {
        "MeetingPollingQuestionId": 3,
        "MeetingPollingQuestionType": "MultipleChoice",
        "MeetingPollingId": 3,
        "SequenceOrder": 2,
        "MeetingPollingParts": [
            {
                "MeetingPollingPartsId": 3,
                "Type": "Question",
                "MeetingPollingQuestionId": 3,
                "MeetingPollingPartsValues": [
                    {
                        "Type": "label",
                        "QuestionValue": "this is a multiple choice question",
                        "FileManagerId": 0,
                        "FileName": null,
                        "FileData": null,
                        "FileType": null
                    }
                ]
            },
            {
                "MeetingPollingPartsId": 4,
                "Type": "Image",
                "MeetingPollingQuestionId": 3,
                "MeetingPollingPartsValues": [
                    {
                        "Type": "Image",
                        "QuestionValue": null,
                        "FileManagerId": 14552,
                        "FileName": null,
                        "FileData": null,
                        "FileType": null
                    }
                ]
            },
            {
                "MeetingPollingPartsId": 5,
                "Type": "Answers",
                "MeetingPollingQuestionId": 3,
                "MeetingPollingPartsValues": [
                    {
                        "Type": "radio",
                        "QuestionValue": "Yes",
                        "FileManagerId": 0,
                        "FileName": null,
                        "FileData": null,
                        "FileType": null
                    },
                    {
                        "Type": "radio",
                        "QuestionValue": "No",
                        "FileManagerId": 0,
                        "FileName": null,
                        "FileData": null,
                        "FileType": null
                    },
                    {
                        "Type": "radio",
                        "QuestionValue": "Abstain",
                        "FileManagerId": 0,
                        "FileName": null,
                        "FileData": null,
                        "FileType": null
                    }
                ]
            }
        ]
    }
]

目标 MVC 表单视图

这将是 LongAnswerText 的基础。

<div class="form-group">
    @Html.LabelFor(c => c.LongAnswerText)
    @Html.TextBoxFor(c => c.LongAnswerText, new { @class = "form-control" })
</div>

这将是多项选择的基础

 <div class="form-group">
        @Html.LabelFor(c => c.MultipleChoice)
        @Html.RadioButtonFor(model => model.QuestionValue, item.Value, false)
</div>

应用程序

static void Main(string[] args)
    {
        LongAnswerText LongAnswerTextParts = new LongAnswerText();
        var control = LongAnswerTextParts ()

    }

    interface MeetingQuestionInterface
    {
        string Label(string target, string text);
    }
    
    public class LongAnswerText : MeetingQuestionInterface
    {
        public static string Label(string target, string text)
        {
            return String.Format("<label for='{0}'>{1}</label>", target, text);
        }
    
        public static string TextBox(string target, string text)
        {
            return String.Format("<input  for='{0}'>{1}</input>", target, text);
        }
    
    }

【问题讨论】:

  • 不清楚你在问什么。策略,就像所有模式一样,是做某事的一种方式,那么你的意思是什么将此 JSON 数据转换为策略设计模式?您不是将数据放入模式中,而是使用模式来解决问题。请解释您要做什么,我们将能够提供帮助。具体来说,您认为策略模式会为您解决什么问题?
  • @avrohom-yisroel 我更新了帖子的目标,我试图解决基于 JSON/ 控件(如标签文本框和单选列表)创建 MVC 控件的问题。
  • 回复Strategy Design Pattern - 问:所以您希望读取 JSON“UI 定义文件”,并相应地动态创建 Razor 页面 UI 元素,对吗?看这里:codemag.com/article/0401041/Dynamically-Adding-Controls
  • 如果你可以使用 ASP.Net Core,你也可以考虑使用Dynamic Component class
  • 我认为您实际上会在这里使用工厂模式,工厂采用 MeetingPollingQuestionType 并返回适合问题类型的 UI/MVC。我过去这样做的方式是让类负责绘制自己。

标签: c# asp.net-web-api factory-pattern strategy-pattern


【解决方案1】:

如果我正确理解了您的问题,您正在尝试将数据解析为相应的类,因此您可以在 MVC 应用程序中以某种 OOP 方式相应地使用这些值。

好吧,这是一个开始。如果你有数据的json,可以使用Newtonsoft.JsonConverter反序列化成一些类。将需要自定义 JsonConverter,因为 Newtonsoft 没有足够的信息来反序列化到接口:

void Main()
{
    var obj = JsonConvert.DeserializeObject<IMeetingPollingQuestion[]>(
        "JSONSTRING", 
        new MeetingPollingQuestionConverter());
    
    Console.WriteLine(obj);
}

public class MeetingPollingQuestionConverter : JsonConverter
{
  public override bool CanConvert(Type objectType) => objectType == typeof(IMeetingPollingQuestion);

  public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  {
        var obj = JObject.Load(reader);

        var id = obj["MeetingPollingQuestionId"].ToObject<int>();
        var type = obj["MeetingPollingQuestionType"].ToObject<MeetingPollingQuestionType>();
        var polId = obj["MeetingPollingId"].ToObject<int>();
        var seq = obj["SequenceOrder"].ToObject<int>();
        var parts = obj["MeetingPollingParts"].ToObject<MeetingPollingPart[]>();
        if(type == MeetingPollingQuestionType.LongAnswerText) {
            return new LongAnswerText{
                MeetingPollingQuestionId = id,
                MeetingPollingQuestionType = type,
                MeetingPollingId = polId,
                SequenceOrder = seq,
                MeetingPollingParts = parts,
            };
        }

        return new MultipleChoice{
                MeetingPollingQuestionId = id,
                MeetingPollingQuestionType = type,
                MeetingPollingId = polId,
                SequenceOrder = seq,
                MeetingPollingParts = parts,
            };
      }

  public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  {
    serializer.Serialize(writer, value);
  }
}

public abstract class IMeetingPollingQuestion {
    public int MeetingPollingQuestionId {get; set;}
    public MeetingPollingQuestionType MeetingPollingQuestionType {get;set;}
    public int MeetingPollingId {get; set;}
    public int SequenceOrder {get; set;}
    public MeetingPollingPart[] MeetingPollingParts {get; set;}
    public virtual string Label(string target, string text) => $"<label for='{target}'>{text}</label>";
    public abstract string Control(string target, string text);
}

public class LongAnswerText : IMeetingPollingQuestion {
    public override string Control(string target, string text) => $"<input  for='{target}'>{text}</input>";
}

public class MultipleChoice : IMeetingPollingQuestion {
    public override string Control(string target, string text) => "...";
}

public class MeetingPollingPart {
    public int MeetingPollingPartsId {get; set;}
    public MeetingPollingPartsType Type {get; set; }
    public int MeetingPollingQuestionId {get; set;} 
    public MeetingPollingPartsValue[] MeetingPollingPartsValues {get; set;}
}

public class MeetingPollingPartsValue {
    public MeetingPollingPartsValueType Type {get; set;}
    public string QuestionValue {get; set;}
    public int FileManagerId {get; set;}
    public string FileName {get; set;}
    public string FileData {get; set;}
    public string FileType {get; set;}
}

public enum MeetingPollingQuestionType {
    LongAnswerText, MultipleChoice
}

public enum MeetingPollingPartsType {
    Question, Image, Answers
}

public enum MeetingPollingPartsValueType {
    label, Image, radio
}

这是运行示例:https://dotnetfiddle.net/NRCE3d

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-20
    • 2010-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多