Проблема с сопоставлением объектов C # с XSLT - PullRequest
0 голосов
/ 21 марта 2019

Я недавно начал работать с XSLT, чтобы отправлять электронные письма в моем приложении MVC.Я пытаюсь сделать необходимый HTML-код для электронной почты, указав хеш объекта.но проблема в том, что XSLT отображает данные только в том случае, если назначенная модель имеет .NET Framework 2.0 и не работает для класса .NET Framework 4.0 (ничего, кроме класса EmailPOCO ниже).выдает ошибку 'Функция' UserDetails: get_UserName () 'завершилась неудачно.',Ниже приведены фрагменты кода.Пожалуйста, дайте мне знать, как заставить это работать с классом Framework 4.0.

Почтовый код:

     public void SendForgotPasswordMail(string loginID, string password)
    {
        EmailPOCO email = new EmailPOCO();

        email.FirstName = "";
        email.LastName = "";
        email.UserName = loginID;
        email.Password = password;
        //User myuser = new User();

        //myuser.UserName = "ABC";
        //myuser.EmailAddress = "abc@someemail.com";

        Hashtable objHash = new Hashtable();
        objHash["ext:User"] = email;

        SMTPMail.GetEmailContent("emailtemplate.xslt", objHash, "sampleTest@gmail.com");
    }

Сопоставление объектов с XSLT: Ошибка в строке "objxslt.Transform (xpathnav, xslarg, xmlwriter, null); "

public static void GetEmailContent(string xslttemplatename, IDictionary objDictionary, string emailTo)
    {
        //var templatepath = System.Web.HttpContext.Current.Server.MapPath("~/EmailTemplates");
        //var objxslt = new XslTransform();
        //objxslt.Load(templatepath + "\\" + xslttemplatename);
        string templatepath = ConfigurationSettings.AppSettings["EmailTemplates"];

        var objxslt = new XslTransform();

        objxslt.Load(templatepath + xslttemplatename);
        var xmldoc = new XmlDocument();
        xmldoc.AppendChild(xmldoc.CreateElement("DocumentRoot"));
        var xpathnav = xmldoc.CreateNavigator();
        var xslarg = new XsltArgumentList();
        if (objDictionary != null)
        {
            foreach (DictionaryEntry entry in objDictionary)
            {
                xslarg.AddExtensionObject(entry.Key.ToString(), entry.Value);
            }
        }
        var emailbuilder = new StringBuilder();
        var xmlwriter = new XmlTextWriter(new System.IO.StringWriter(emailbuilder));
        objxslt.Transform(xpathnav, xslarg, xmlwriter, null);
        string subjecttext, bodytext;
        var xemaildoc = new XmlDocument();
        xemaildoc.LoadXml(emailbuilder.ToString());
        var titlenode = xemaildoc.SelectSingleNode("//title");
        subjecttext = titlenode.InnerText;
        var bodynode = xemaildoc.SelectSingleNode("//body");
        bodytext = bodynode.InnerXml;
        if (!string.IsNullOrEmpty(bodytext))
        {
            bodytext = bodytext.Replace("&", "&");
        }
        SendEmail(emailTo, subjecttext, bodytext);
    }

XSLT:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:UserDetails="ext:User">
	<xsl:template match="/">
		<html>
			<head>
				<title>Welcome <xsl:value-of select="UserDetails:get_UserName()" /></title>
			</head>
			<body>
				<P>Dear <xsl:value-of select="UserDetails:get_UserName()" />,</P>
					Your Password is <xsl:value-of select="UserDetails:get_Password()" />
          <BR />
				<P>
			Regards
			MyService Administrator
		</P>
				
				</body>
		</html>
	</xsl:template>
</xsl:stylesheet>


Exception Details:

{"Function 'UserDetails:get_UserName()' has failed."}

Inner Exception:  Request failed.

   at System.RuntimeMethodHandle.PerformSecurityCheck(Object obj, RuntimeMethodHandleInternal method, RuntimeType parent, UInt32 invocationFlags)
   at System.RuntimeMethodHandle.PerformSecurityCheck(Object obj, IRuntimeMethodInfo method, RuntimeType parent, UInt32 invocationFlags)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at System.Xml.Xsl.XsltOld.XsltCompileContext.FuncExtension.Invoke(XsltContext xsltContext, Object[] args, XPathNavigator docContext)
   at MS.Internal.Xml.XPath.FunctionQuery.Evaluate(XPathNodeIterator nodeIterator)

1 Ответ

1 голос
/ 21 марта 2019

Объекты расширений предназначены для предоставления дополнительных функций, которые недоступны в XSLT, но вы, похоже, используете его как обходной путь просто для передачи коллекций значений в ваш XSLT.

Если вы просто хотитепередавайте значения, вы должны передавать их как параметры, а не как объекты расширения.

Код C #:

var values = new Dictionary<string, string>
{
    { "User", "the username" },
    { "Password", "t3hpassw0rd" }
}

var xslarg = new XsltArgumentList();
foreach (var kv in values)
{
    xslarg.AddParam(kv.Key, "ext:User", kv.Value);
}

XSLT:

<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:user="ext:User">
    <xsl:param name="user:User" />
    <xsl:param name="user:Password" />

    <xsl:template match="/">
        <html>
            <head>
                <title>Welcome <xsl:value-of select="$user:User" /></title>
            </head>
            <body>
                <P>Dear <xsl:value-of select="$user:User" />,</P>
                    Your Password is <xsl:value-of select="$user:Password" />
          <BR />
                <P>
            Regards
            MyService Administrator
        </P>

                </body>
        </html>
    </xsl:template>
</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...