Extract issuer (CN) from SSL Certificate using openssl in iOS - iphone

I want to extract Issuer CN (Common name) from SSL certificate using openSSL in iOS. I am using the link http://pastebin.com/Vn797Sc0 for extracting the information from the certificate. I am getting the issuer name but could not extract Issuer Common name(Common name) in iOS. Thanks in advance

You can extract the Common Name like the Organization field in the code you linked (Not tested)
static NSString * CertificateGetIssuerCommonName(X509 *certificateX509) {
NSString *issuerCN = nil;
if (certificateX509 != NULL) {
X509_NAME *issuerX509Name = X509_get_issuer_name(certificateX509);
if (issuerX509Name != NULL) {
int nid = OBJ_txt2nid("CN");
int index = X509_NAME_get_index_by_NID(issuerX509Name, nid, -1);
if (index != -1) {
X509_NAME_ENTRY *issuerNameCommonName = X509_NAME_get_entry(issuerX509Name, index);
if (issuerNameEntry) {
ASN1_STRING *issuerCNASN1 = X509_NAME_ENTRY_get_data(issuerNameEntry);
if (issuerCNASN1 != NULL) {
unsigned char *issuerCName = ASN1_STRING_data(issuerCNASN1);
issuerCN = [NSString stringWithUTF8String:(char *)issuerCName];
}
}
}
}
}
return issuerCN;
}

static NSString * CertificateGetIssuerName(X509 *certificateX509)
{
NSString *issuer = nil;
if (certificateX509 != NULL) {
X509_NAME *issuerX509Name = X509_get_issuer_name(certificateX509);
if (issuerX509Name != NULL) {
//NID_commonName extract the common name of the issuer
int index = X509_NAME_get_index_by_NID(issuerX509Name, NID_commonName, -1);
X509_NAME_ENTRY *issuerNameEntry = X509_NAME_get_entry(issuerX509Name, index);
if (issuerNameEntry) {
ASN1_STRING *issuerNameASN1 = X509_NAME_ENTRY_get_data(issuerNameEntry);
if (issuerNameASN1 != NULL) {
unsigned char *issuerName = ASN1_STRING_data(issuerNameASN1);
issuer = [NSString stringWithUTF8String:(char *)issuerName];
}
}
}
}
return issuer;
}

Related

Need to edit the code "user info" for sdk ZKTeco device fb100

I have this code working 100% but with one device zkt fb100,This code is for set user name ,card number , with id to the device to register it:
public int sta_SetUserInfo(ListBox lblOutputInfo, TextBox txtUserID, TextBox txtName, ComboBox cbPrivilege, TextBox txtCardnumber, TextBox txtPassword)
{
if (GetConnectState() == false)
{
lblOutputInfo.Items.Add("*Please connect first!");
return -1024;
}
if (txtUserID.Text.Trim() == "" || cbPrivilege.Text.Trim() == "")
{
lblOutputInfo.Items.Add("*Please input data first!");
return -1023;
}
int iPrivilege = cbPrivilege.SelectedIndex;
bool bFlag = false;
if (iPrivilege == 5)
{
lblOutputInfo.Items.Add("*User Defined Role is Error! Please Register again!");
return -1023;
}
/*
if(iPrivilege == 4)
{
axCZKEM1.IsUserDefRoleEnable(iMachineNumber, 4, out bFlag);
if (bFlag == false)
{
lblOutputInfo.Items.Add("*User Defined Role is unable!");
return -1023;
}
}
*/
//lblOutputInfo.Items.Add("[func IsUserDefRoleEnable]Temporarily unsupported");
int iPIN2Width = 0;
int iIsABCPinEnable = 0;
int iT9FunOn = 0;
string strTemp = "";
axCZKEM1.GetSysOption(GetMachineNumber(), "~PIN2Width", out strTemp);
iPIN2Width = Convert.ToInt32(strTemp);
axCZKEM1.GetSysOption(GetMachineNumber(), "~IsABCPinEnable", out strTemp);
iIsABCPinEnable = Convert.ToInt32(strTemp);
axCZKEM1.GetSysOption(GetMachineNumber(), "~T9FunOn", out strTemp);
iT9FunOn = Convert.ToInt32(strTemp);
/*
axCZKEM1.GetDeviceInfo(iMachineNumber, 76, ref iPIN2Width);
axCZKEM1.GetDeviceInfo(iMachineNumber, 77, ref iIsABCPinEnable);
axCZKEM1.GetDeviceInfo(iMachineNumber, 78, ref iT9FunOn);
*/
if (txtUserID.Text.Length > iPIN2Width)
{
lblOutputInfo.Items.Add("*User ID error! The max length is " + iPIN2Width.ToString());
return -1022;
}
if (iIsABCPinEnable == 0 || iT9FunOn == 0)
{
if (txtUserID.Text.Substring(0,1) == "0")
{
lblOutputInfo.Items.Add("*User ID error! The first letter can not be as 0");
return -1022;
}
foreach (char tempchar in txtUserID.Text.ToCharArray())
{
if (!(char.IsDigit(tempchar)))
{
lblOutputInfo.Items.Add("*User ID error! User ID only support digital");
return -1022;
}
}
}
int idwErrorCode = 0;
string sdwEnrollNumber = txtUserID.Text.Trim();
string sName = txtName.Text.Trim();
string sCardnumber = txtCardnumber.Text.Trim();
string sPassword = txtPassword.Text.Trim();
bool bEnabled = true;
/*if (iPrivilege == 4)
{
bEnabled = false;
iPrivilege = 0;
}
else
{
bEnabled = true;
}*/
axCZKEM1.EnableDevice(iMachineNumber, false);
axCZKEM1.SetStrCardNumber(sCardnumber);//Before you using function SetUserInfo,set the card number to make sure you can upload it to the device
if (axCZKEM1.SSR_SetUserInfo(iMachineNumber, sdwEnrollNumber, sName, sPassword, iPrivilege, bEnabled))//upload the user's information(card number included)
{
lblOutputInfo.Items.Add("Set user information successfully");
}
else
{
axCZKEM1.GetLastError(ref idwErrorCode);
lblOutputInfo.Items.Add("*Operation failed,ErrorCode=" + idwErrorCode.ToString());
}
axCZKEM1.RefreshData(iMachineNumber);//the data in the device should be refreshed
axCZKEM1.EnableDevice(iMachineNumber, true);
return 1;
}
But if I have two device what should I change here ? .
I tried to change iMachineNumber to make first device is 1 and second device is 2 but not working too !
Finally I found the solution : in the button connect to device need to insert the above code in loop for one device and then next device and so on .

How do I use the Mozilla NSS Root Certificate store on Windows, Mac, and Linux?

NSS comes with very little documentation, and a heavily vestigial API. How does it work? It is used for firefox on Window and Mac, and Chrome as well on linux. How do I install, uninstall, and check installation of my own Root Cert?
See this gist, here: https://gist.github.com/pehrlich/08852e8f7da81e136d70
The meat of it is CertificateNSS.cpp, copied here:
#include "stdafx.h"
#include "CertificateNSS.h"
#include "Certificate.h"
#include <boost/filesystem/operations.hpp>
#include <nss.h>
#include <cert.h>
#include <certdb.h>
ProfileLocker::ProfileLocker(const boost::filesystem::path& profilePath) : m_isValid(false)
{
GetSharedMutex().lock();
m_isValid = (NSS_InitReadWrite(profilePath.string().c_str()) == SECSuccess);
if (!m_isValid) {
GetSharedMutex().unlock();
}
}
ProfileLocker::~ProfileLocker()
{
if (m_isValid) {
NSS_Shutdown();
GetSharedMutex().unlock();
}
}
std::mutex& ProfileLocker::GetSharedMutex()
{
static std::mutex s_mutex;
return s_mutex;
}
std::vector<boost::filesystem::path> CertificateNSS::GetUserProfiles()
{
std::vector<boost::filesystem::path> profiles;
const auto path = GetProfilesDirectory();
if (!boost::filesystem::is_directory(path)) {
return profiles;
}
boost::filesystem::directory_iterator endIt;
for (boost::filesystem::directory_iterator it(path); it != endIt; ++it) {
if (boost::filesystem::is_directory(it->status())) {
profiles.push_back(it->path());
}
}
return profiles;
}
bool CertificateNSS::Install() const
{
std::string derCert = m_cert.GetBytes(CertEncoding::DER);
if (derCert.empty()) {
return false;
}
bool wasInstalled = false;
CERTCertDBHandle* certdb = CERT_GetDefaultCertDB();
if (certdb) {
SECItem cert = { siBuffer, (unsigned char*)derCert.c_str(), static_cast<unsigned int>(derCert.size()) };
SECItem* certArray[1] = { &cert };
SECCertUsage noOpUsage = certUsageUserCertImport; // Not used, but required
CERTCertificate** certificates = nullptr;
wasInstalled = (CERT_ImportCerts(certdb, noOpUsage, 1, certArray, &certificates, PR_TRUE, PR_TRUE,
const_cast<char*>(Certificate::GetNickname().c_str())) == SECSuccess);
if (certificates[0]) {
CERTCertTrust trust = { CERTDB_TRUSTED_CA | CERTDB_VALID_CA, 0, 0 };
CERT_ChangeCertTrust(certdb, certificates[0], &trust);
CERT_DestroyCertificate(certificates[0]);
}
}
return wasInstalled;
}
bool CertificateNSS::IsInstalled() const
{
std::string derCert = m_cert.GetBytes(CertEncoding::DER);
if (derCert.empty()) {
return false;
}
bool wasInstalled = false;
SECItem cert = { siBuffer, (unsigned char*)derCert.c_str(), static_cast<unsigned int>(derCert.size()) };
CERTCertDBHandle* certdb = CERT_GetDefaultCertDB();
if (certdb) {
CERTCertificate* certificate = CERT_FindCertByDERCert(certdb, &cert);
if (certificate) {
wasInstalled = true;
CERT_DestroyCertificate(certificate);
}
}
return wasInstalled;
}
bool CertificateNSS::Uninstall() const
{
std::string derCert = m_cert.GetBytes(CertEncoding::DER);
if (derCert.empty()) {
return false;
}
bool wasUninstalled = false;
SECItem cert = { siBuffer, (unsigned char*)derCert.c_str(), static_cast<unsigned int>(derCert.size()) };
CERTCertDBHandle* certdb = CERT_GetDefaultCertDB();
if (certdb) {
CERTCertificate* certificate = CERT_FindCertByDERCert(certdb, &cert);
if (certificate) {
wasUninstalled = (SEC_DeletePermCertificate(certificate) == SECSuccess);
CERT_DestroyCertificate(certificate);
}
}
return wasUninstalled;
}
bool CertificateNSS::UninstallAll()
{
bool wasUninstalled = true;
CERTCertDBHandle* certdb = CERT_GetDefaultCertDB();
if (!certdb) {
return true;
}
// Delete up to 100 profiles
for (int i = 0; i < 100; i++) {
bool failed = true;
CERTCertificate* certificate = CERT_FindCertByNickname(certdb, Certificate::GetNickname().c_str());
if (certificate) {
wasUninstalled = (SEC_DeletePermCertificate(certificate) == SECSuccess);
if (wasUninstalled) {
failed = false;
}
CERT_DestroyCertificate(certificate);
}
if (failed) {
break;
}
}
return wasUninstalled;
}

video overwriting using ffmpeg - I want to Add video rotation code and rewrite the existing file..How can i do that?

I want to rotate the .mov file which is in portrait mode by 90 degrees, for that i used the following code..
It works but, it results in loss of video frames...
My code is,
public void encode(File source, File target, EncodingAttributes attributes,
EncoderProgressListener listener, Integer i) throws IllegalArgumentException,
InputFormatException, EncoderException {
String formatAttribute = attributes.getFormat();
Float offsetAttribute = attributes.getOffset();
Float durationAttribute = attributes.getDuration();
QualityScale qualityScale = attributes.getQualityScale();
AudioAttributes audioAttributes = attributes.getAudioAttributes();
VideoAttributes videoAttributes = attributes.getVideoAttributes();
if (audioAttributes == null && videoAttributes == null) {
throw new IllegalArgumentException(
"Both audio and video attributes are null");
}
target = target.getAbsoluteFile();
target.getParentFile().mkdirs();
FFMPEGExecutor ffmpeg = locator.createExecutor();
if (offsetAttribute != null) {
ffmpeg.addArgument("-ss");
ffmpeg.addArgument(String.valueOf(offsetAttribute.floatValue()));
}
ffmpeg.addArgument("-i");
ffmpeg.addArgument(source.getAbsolutePath());
if (durationAttribute != null) {
ffmpeg.addArgument("-t");
ffmpeg.addArgument(String.valueOf(durationAttribute.floatValue()));
}
if (qualityScale != null) {
ffmpeg.addArgument("-qscale:"+qualityScale.getQualityStreamSpecifier());
ffmpeg.addArgument(String.valueOf(qualityScale.getQualityValue()));
}
if (videoAttributes == null) {
ffmpeg.addArgument("-vn");
} else {
String codec = videoAttributes.getCodec();
if (codec != null) {
ffmpeg.addArgument("-vcodec");
ffmpeg.addArgument(codec);
}
String tag = videoAttributes.getTag();
if (tag != null) {
ffmpeg.addArgument("-vtag");
ffmpeg.addArgument(tag);
}
Integer bitRate = videoAttributes.getBitRate();
if (bitRate != null) {
ffmpeg.addArgument("-b");
ffmpeg.addArgument(String.valueOf(bitRate.intValue()));
}
Integer frameRate = videoAttributes.getFrameRate();
if (frameRate != null) {
ffmpeg.addArgument("-r");
ffmpeg.addArgument(String.valueOf(frameRate.intValue()));
}
VideoSize size = videoAttributes.getSize();
if (size != null) {
ffmpeg.addArgument("-s");
ffmpeg.addArgument(String.valueOf(size.getWidth()) + "x"
+ String.valueOf(size.getHeight()));
}
FilterGraph filterGraph = videoAttributes.getFilterGraph();
if (filterGraph != null) {
ffmpeg.addArgument("-vf");
if(videoAttributes.getRotate() != null && videoAttributes.getRotate() == 90){
ffmpeg.addArgument("transpose=1");
}else if(videoAttributes.getRotate() != null && videoAttributes.getRotate() == 180){
ffmpeg.addArgument("vflip,hflip");
}
else {
if (filterGraph.isUseExpression()) {
ffmpeg.addArgument(filterGraph.getFilterGraphExpression());
}
}
}
}
if (audioAttributes == null) {
ffmpeg.addArgument("-an");
} else {
String codec = audioAttributes.getCodec();
if (codec != null) {
ffmpeg.addArgument("-acodec");
ffmpeg.addArgument(codec);
}
Integer bitRate = audioAttributes.getBitRate();
if (bitRate != null) {
ffmpeg.addArgument("-ab");
ffmpeg.addArgument(String.valueOf(bitRate.intValue()));
}
Integer channels = audioAttributes.getChannels();
if (channels != null) {
ffmpeg.addArgument("-ac");
ffmpeg.addArgument(String.valueOf(channels.intValue()));
}
Integer samplingRate = audioAttributes.getSamplingRate();
if (samplingRate != null) {
ffmpeg.addArgument("-ar");
ffmpeg.addArgument(String.valueOf(samplingRate.intValue()));
}
Integer volume = audioAttributes.getVolume();
if (volume != null) {
ffmpeg.addArgument("-vol");
ffmpeg.addArgument(String.valueOf(volume.intValue()));
}
}
ffmpeg.addArgument("-f");
ffmpeg.addArgument(formatAttribute);
ffmpeg.addArgument("-y");
ffmpeg.addArgument(target.getAbsolutePath());
try {
ffmpeg.execute();
} catch (IOException e) {
throw new EncoderException(e);
}
try {
String lastWarning = null;
long duration;
long progress = 0;
RBufferedReader reader = null;
reader = new RBufferedReader(new InputStreamReader(ffmpeg
.getErrorStream()));
MultimediaInfo info = parseMultimediaInfo(source, reader);
if (durationAttribute != null) {
duration = (long) Math
.round((durationAttribute.floatValue() * 1000L));
} else {
duration = info.getDuration();
if (offsetAttribute != null) {
duration -= (long) Math
.round((offsetAttribute.floatValue() * 1000L));
}
}
if (listener != null) {
listener.sourceInfo(info);
}
int step = 0;
String line;
while ((line = reader.readLine()) != null) {
System.out.println("line::::"+line);
if (step == 0) {
if (line.startsWith("WARNING: ")) {
if (listener != null) {
listener.message(line);
}
} else if (!line.startsWith("Output #0")) {
//throw new EncoderException(line);
} else {
step++;
}
} else if (step == 1) {
if (!line.startsWith(" ")) {
step++;
} else {
System.out.println("line>>>>>>"+line);
Hashtable table1 = new Hashtable();
Matcher m = ROTATE_INFO_PATTERN.matcher(line);
while (m.find()) {
if (table1 == null) {
table1 = new Hashtable();
}
String key = m.group(1);
String value = m.group(2);
table1.put(key, value);
}
System.out.println("Table values"+table1.get("rotate"));
if(table1.get("rotate") != null){
Object videoRotateValue = table1.get("rotate");
int rotate = Integer.valueOf(videoRotateValue.toString());
switch(rotate){
case 90:
videoAttributes.setRotate(rotate);
if(i == 0){
i++;
encode(source, target, attributes, null, i);
}
break;
case 180:
videoAttributes.setRotate(rotate);
if(i == 0){
i++;
encode(source, target, attributes, null, i);
}
break;
case 270: System.out.println("case 3 :: "+videoRotateValue);
break;
}
}
}
}
if (step == 2) {
if (!line.startsWith("Stream mapping:")) {
throw new EncoderException(line);
} else {
step++;
}
} else if (step == 3) {
if (!line.startsWith(" ")) {
step++;
}
}
if (step == 4) {
line = line.trim();
if (line.length() > 0) {
Hashtable table = parseProgressInfoLine(line);
if (table == null) {
if (listener != null) {
listener.message(line);
}
lastWarning = line;
} else {
if (listener != null) {
String time = (String) table.get("time");
if (time != null) {
int dot = time.indexOf('.');
if (dot > 0 && dot == time.length() - 2
&& duration > 0) {
String p1 = time.substring(0, dot);
String p2 = time.substring(dot + 1);
try {
long i1 = Long.parseLong(p1);
long i2 = Long.parseLong(p2);
progress = (i1 * 1000L)
+ (i2 * 100L);
int perm = (int) Math
.round((double) (progress * 1000L)
/ (double) duration);
if (perm > 1000) {
perm = 1000;
}
listener.progress(perm);
} catch (NumberFormatException e) {
;
}
}
}
}
lastWarning = null;
}
}
}
}
if (lastWarning != null) {
if (!SUCCESS_PATTERN.matcher(lastWarning).matches()) {
throw new EncoderException(lastWarning);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
ffmpeg.destroy();
}
}
Please advise, how to achieve video rotation without any video Frame loss
Thanks In Advance
Lakshmi Priya . K
Worked for couple of days and finally tried to write the rotated video in different target file then i got the video output without any loss and video is also rotated....
Thanks
Lakshmi Priya. K

How to calculate the color based on given fgColor indexed

I am working on Open XML,
<x:fill>
<x:patternFill patternType="solid">
<x:fgColor indexed="46" />
<x:bgColor indexed="64" />
</x:patternFill>
</x:fill>
Above is a office 2007 document that converted from office 2003.
According to http://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.foregroundcolor.aspx
Indexed attributes only used for backward compatibility purposes.
Above is my code, how to calculate the #Hex Color Code for indexed = 46?
I made this class for myself. Hope I save someone some trouble
public class IndexedColours
{
static Dictionary<string, string> Data;
IndexedColours()
{
if(Data == null || Data.Count == 0)
{
Data = new Dictionary<string, string>();
Data.Add("0", "000000");
Data.Add("1", "FFFFFF");
Data.Add("2", "FF0000");
Data.Add("3", "00FF00");
Data.Add("4", "0000FF");
Data.Add("5", "FFFF00");
Data.Add("6", "FF00FF");
Data.Add("7", "00FFFF");
Data.Add("8", "000000");
Data.Add("9", "FFFFFF");
Data.Add("10", "FF0000");
Data.Add("11", "00FF00");
Data.Add("12", "0000FF");
Data.Add("13", "FFFF00");
Data.Add("14", "FF00FF");
Data.Add("15", "00FFFF");
Data.Add("16", "800000");
Data.Add("17", "008000");
Data.Add("18", "000080");
Data.Add("19", "808000");
Data.Add("20", "800080");
Data.Add("21", "008080");
Data.Add("22", "C0C0C0");
Data.Add("23", "808080");
Data.Add("24", "9999FF");
Data.Add("25", "993366");
Data.Add("26", "FFFFCC");
Data.Add("27", "CCFFFF");
Data.Add("28", "660066");
Data.Add("29", "FF8080");
Data.Add("30", "0066CC");
Data.Add("31", "CCCCFF");
Data.Add("32", "000080");
Data.Add("33", "FF00FF");
Data.Add("34", "FFFF00");
Data.Add("35", "00FFFF");
Data.Add("36", "800080");
Data.Add("37", "800000");
Data.Add("38", "008080");
Data.Add("39", "0000FF");
Data.Add("40", "00CCFF");
Data.Add("41", "CCFFFF");
Data.Add("42", "CCFFCC");
Data.Add("43", "FFFF99");
Data.Add("44", "99CCFF");
Data.Add("45", "FF99CC");
Data.Add("46", "CC99FF");
Data.Add("47", "FFCC99");
Data.Add("48", "3366FF");
Data.Add("49", "33CCCC");
Data.Add("50", "99CC00");
Data.Add("51", "FFCC00");
Data.Add("52", "FF9900");
Data.Add("53", "FF6600");
Data.Add("54", "666699");
Data.Add("55", "969696");
Data.Add("56", "003366");
Data.Add("57", "339966");
Data.Add("58", "003300");
Data.Add("59", "333300");
Data.Add("60", "993300");
Data.Add("61", "993366");
Data.Add("62", "333399");
Data.Add("63", "333333");
}
}
public static string GetIndexColour(string Index)
{
var d = new IndexedColours();
var res = "";
var exist = Data.TryGetValue(Index, out res);
if (exist)
return res;
else return "000000";
}
}
Method to use the above code:
public static string GetCellColour(this Cell cell, SpreadsheetDocument d)
{
if (cell != null && cell.StyleIndex != null)
{
var valcell = cell;
var styles = d.WorkbookPart.WorkbookStylesPart;
var ss = styles.Stylesheet;
var formats = ss.CellFormats;
var cf = (CellFormat)formats.ElementAt((int)valcell.StyleIndex.Value);
var fill = (Fill)styles.Stylesheet.Fills.ChildElements[(int)cf.FillId.Value];
var fgc = fill.PatternFill.ForegroundColor;
var cl = fgc == null || fgc.Rgb == null ? "FFFFFF" : fgc.Rgb.Value.Remove(0, 2);
if (fgc != null && fgc.Indexed != null && fgc.Indexed.HasValue)
{
cl = IndexedColours.GetIndexColour(fgc.Indexed.Value.ToString());
}
return cl;
}
else return "FFFFFF";
}
Solved my problem, there is color indexes online. just search for it.

Source Code for DataAnnotationsModelMetadataProvider

For some reason, .NET Reflector throws an exception when I try to reflect on this class. It works for everything else.
What is the source code of DataAnnotationsModelMetadataProvider, please?
Feel free to download the ASP.NET MVC source code and inspect the implementation. Here's how it looks in ASP.NET MVC 3 RTM:
namespace System.Web.Mvc {
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
public class DataAnnotationsModelMetadataProvider : AssociatedMetadataProvider {
protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName) {
List<Attribute> attributeList = new List<Attribute>(attributes);
DisplayColumnAttribute displayColumnAttribute = attributeList.OfType<DisplayColumnAttribute>().FirstOrDefault();
DataAnnotationsModelMetadata result = new DataAnnotationsModelMetadata(this, containerType, modelAccessor, modelType, propertyName, displayColumnAttribute);
// Do [HiddenInput] before [UIHint], so you can override the template hint
HiddenInputAttribute hiddenInputAttribute = attributeList.OfType<HiddenInputAttribute>().FirstOrDefault();
if (hiddenInputAttribute != null) {
result.TemplateHint = "HiddenInput";
result.HideSurroundingHtml = !hiddenInputAttribute.DisplayValue;
}
// We prefer [UIHint("...", PresentationLayer = "MVC")] but will fall back to [UIHint("...")]
IEnumerable<UIHintAttribute> uiHintAttributes = attributeList.OfType<UIHintAttribute>();
UIHintAttribute uiHintAttribute = uiHintAttributes.FirstOrDefault(a => String.Equals(a.PresentationLayer, "MVC", StringComparison.OrdinalIgnoreCase))
?? uiHintAttributes.FirstOrDefault(a => String.IsNullOrEmpty(a.PresentationLayer));
if (uiHintAttribute != null) {
result.TemplateHint = uiHintAttribute.UIHint;
}
DataTypeAttribute dataTypeAttribute = attributeList.OfType<DataTypeAttribute>().FirstOrDefault();
if (dataTypeAttribute != null) {
result.DataTypeName = dataTypeAttribute.ToDataTypeName();
}
EditableAttribute editable = attributes.OfType<EditableAttribute>().FirstOrDefault();
if (editable != null) {
result.IsReadOnly = !editable.AllowEdit;
}
else {
ReadOnlyAttribute readOnlyAttribute = attributeList.OfType<ReadOnlyAttribute>().FirstOrDefault();
if (readOnlyAttribute != null) {
result.IsReadOnly = readOnlyAttribute.IsReadOnly;
}
}
DisplayFormatAttribute displayFormatAttribute = attributeList.OfType<DisplayFormatAttribute>().FirstOrDefault();
if (displayFormatAttribute == null && dataTypeAttribute != null) {
displayFormatAttribute = dataTypeAttribute.DisplayFormat;
}
if (displayFormatAttribute != null) {
result.NullDisplayText = displayFormatAttribute.NullDisplayText;
result.DisplayFormatString = displayFormatAttribute.DataFormatString;
result.ConvertEmptyStringToNull = displayFormatAttribute.ConvertEmptyStringToNull;
if (displayFormatAttribute.ApplyFormatInEditMode) {
result.EditFormatString = displayFormatAttribute.DataFormatString;
}
if (!displayFormatAttribute.HtmlEncode && String.IsNullOrWhiteSpace(result.DataTypeName)) {
result.DataTypeName = DataTypeUtil.HtmlTypeName;
}
}
ScaffoldColumnAttribute scaffoldColumnAttribute = attributeList.OfType<ScaffoldColumnAttribute>().FirstOrDefault();
if (scaffoldColumnAttribute != null) {
result.ShowForDisplay = result.ShowForEdit = scaffoldColumnAttribute.Scaffold;
}
DisplayAttribute display = attributes.OfType<DisplayAttribute>().FirstOrDefault();
string name = null;
if (display != null) {
result.Description = display.GetDescription();
result.ShortDisplayName = display.GetShortName();
result.Watermark = display.GetPrompt();
result.Order = display.GetOrder() ?? ModelMetadata.DefaultOrder;
name = display.GetName();
}
if (name != null) {
result.DisplayName = name;
}
else {
DisplayNameAttribute displayNameAttribute = attributeList.OfType<DisplayNameAttribute>().FirstOrDefault();
if (displayNameAttribute != null) {
result.DisplayName = displayNameAttribute.DisplayName;
}
}
RequiredAttribute requiredAttribute = attributeList.OfType<RequiredAttribute>().FirstOrDefault();
if (requiredAttribute != null) {
result.IsRequired = true;
}
return result;
}
}
}