网博士cases_list_to_html.asp,aspnetcore/DefaultHtmlGenerator.cs at main · dotnet/aspnetcore · GitHub...

// Copyright (c) .NET Foundation. All rights reserved.

// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;

using System.Collections;

using System.Collections.Generic;

using System.ComponentModel.DataAnnotations;

using System.Diagnostics;

using System.Globalization;

using System.Linq;

using System.Reflection;

using System.Text.Encodings.Web;

using Microsoft.AspNetCore.Antiforgery;

using Microsoft.AspNetCore.Html;

using Microsoft.AspNetCore.Http;

using Microsoft.AspNetCore.Mvc.ModelBinding;

using Microsoft.AspNetCore.Mvc.Rendering;

using Microsoft.AspNetCore.Mvc.Routing;

using Microsoft.Extensions.Options;

namespace Microsoft.AspNetCore.Mvc.ViewFeatures

{

///

/// Default implementation of .

///

public class DefaultHtmlGenerator : IHtmlGenerator

{

private const string HiddenListItem = @"

";

private static readonly MethodInfo ConvertEnumFromStringMethod =

typeof(DefaultHtmlGenerator).GetTypeInfo().GetDeclaredMethod(nameof(ConvertEnumFromString));

// See: (http://www.w3.org/TR/html5/forms.html#the-input-element)

private static readonly string[] _placeholderInputTypes =

new[] { "text", "search", "url", "tel", "email", "password", "number" };

// See: (http://www.w3.org/TR/html5/sec-forms.html#apply)

private static readonly string[] _maxLengthInputTypes =

new[] { "text", "search", "url", "tel", "email", "password" };

private readonly IAntiforgery _antiforgery;

private readonly IModelMetadataProvider _metadataProvider;

private readonly IUrlHelperFactory _urlHelperFactory;

private readonly HtmlEncoder _htmlEncoder;

private readonly ValidationHtmlAttributeProvider _validationAttributeProvider;

///

/// Initializes a new instance of the class.

///

/// The instance which is used to generate antiforgery

/// tokens.

/// The accessor for .

/// The .

/// The .

/// The .

/// The .

public DefaultHtmlGenerator(

IAntiforgery antiforgery,

IOptions optionsAccessor,

IModelMetadataProvider metadataProvider,

IUrlHelperFactory urlHelperFactory,

HtmlEncoder htmlEncoder,

ValidationHtmlAttributeProvider validationAttributeProvider)

{

if (antiforgery == null)

{

throw new ArgumentNullException(nameof(antiforgery));

}

if (optionsAccessor == null)

{

throw new ArgumentNullException(nameof(optionsAccessor));

}

if (metadataProvider == null)

{

throw new ArgumentNullException(nameof(metadataProvider));

}

if (urlHelperFactory == null)

{

throw new ArgumentNullException(nameof(urlHelperFactory));

}

if (htmlEncoder == null)

{

throw new ArgumentNullException(nameof(htmlEncoder));

}

if (validationAttributeProvider == null)

{

throw new ArgumentNullException(nameof(validationAttributeProvider));

}

_antiforgery = antiforgery;

_metadataProvider = metadataProvider;

_urlHelperFactory = urlHelperFactory;

_htmlEncoder = htmlEncoder;

_validationAttributeProvider = validationAttributeProvider;

// Underscores are fine characters in id's.

IdAttributeDotReplacement = optionsAccessor.Value.HtmlHelperOptions.IdAttributeDotReplacement;

}

///

/// Gets or sets a value that indicates whether the maxlength attribute should be rendered for

/// compatible HTML input elements, when they're bound to models marked with either

/// or attributes.

///

/// The default value is .

///

///

/// If both attributes are specified, the one with the smaller value will be used for the rendered

/// maxlength attribute.

///

///

/// This property is currently ignored.

///

///

protected bool AllowRenderingMaxLengthAttribute { get; } = true;

///

public string IdAttributeDotReplacement { get; }

///

public string Encode(string value)

{

return !string.IsNullOrEmpty(value) ? _htmlEncoder.Encode(value) : string.Empty;

}

///

public string Encode(object value)

{

return (value != null) ? _htmlEncoder.Encode(value.ToString()) : string.Empty;

}

///

public string FormatValue(object value, string format)

{

return ViewDataDictionary.FormatValue(value, format);

}

///

public virtual TagBuilder GenerateActionLink(

ViewContext viewContext,

string linkText,

string actionName,

string controllerName,

string protocol,

string hostname,

string fragment,

object routeValues,

object htmlAttributes)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

if (linkText == null)

{

throw new ArgumentNullException(nameof(linkText));

}

var urlHelper = _urlHelperFactory.GetUrlHelper(viewContext);

var url = urlHelper.Action(actionName, controllerName, routeValues, protocol, hostname, fragment);

return GenerateLink(linkText, url, htmlAttributes);

}

///

public virtual TagBuilder GeneratePageLink(

ViewContext viewContext,

string linkText,

string pageName,

string pageHandler,

string protocol,

string hostname,

string fragment,

object routeValues,

object htmlAttributes)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

if (linkText == null)

{

throw new ArgumentNullException(nameof(linkText));

}

var urlHelper = _urlHelperFactory.GetUrlHelper(viewContext);

var url = urlHelper.Page(pageName, pageHandler, routeValues, protocol, hostname, fragment);

return GenerateLink(linkText, url, htmlAttributes);

}

///

public virtual IHtmlContent GenerateAntiforgery(ViewContext viewContext)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

var formContext = viewContext.FormContext;

if (formContext.CanRenderAtEndOfForm)

{

// Inside a BeginForm/BeginRouteForm or a

tag helper. So, the antiforgery token might have

// already been created and appended to the 'end form' content (the AntiForgeryToken HTML helper does

// this) OR the

tag helper might have already generated an antiforgery token.

if (formContext.HasAntiforgeryToken)

{

return HtmlString.Empty;

}

formContext.HasAntiforgeryToken = true;

}

return _antiforgery.GetHtml(viewContext.HttpContext);

}

///

public virtual TagBuilder GenerateCheckBox(

ViewContext viewContext,

ModelExplorer modelExplorer,

string expression,

bool? isChecked,

object htmlAttributes)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

if (modelExplorer != null)

{

// CheckBoxFor() case. That API does not support passing isChecked directly.

Debug.Assert(!isChecked.HasValue);

if (modelExplorer.Model != null)

{

if (bool.TryParse(modelExplorer.Model.ToString(), out var modelChecked))

{

isChecked = modelChecked;

}

}

}

var htmlAttributeDictionary = GetHtmlAttributeDictionaryOrNull(htmlAttributes);

if (isChecked.HasValue && htmlAttributeDictionary != null)

{

// Explicit isChecked value must override "checked" in dictionary.

htmlAttributeDictionary.Remove("checked");

}

// Use ViewData only in CheckBox case (metadata null) and when the user didn't pass an isChecked value.

return GenerateInput(

viewContext,

InputType.CheckBox,

modelExplorer,

expression,

value: "true",

useViewData: (modelExplorer == null && !isChecked.HasValue),

isChecked: isChecked ?? false,

setId: true,

isExplicitValue: false,

format: null,

htmlAttributes: htmlAttributeDictionary);

}

///

public virtual TagBuilder GenerateHiddenForCheckbox(

ViewContext viewContext,

ModelExplorer modelExplorer,

string expression)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

var tagBuilder = new TagBuilder("input");

tagBuilder.MergeAttribute("type", GetInputTypeString(InputType.Hidden));

tagBuilder.MergeAttribute("value", "false");

tagBuilder.TagRenderMode = TagRenderMode.SelfClosing;

var fullName = NameAndIdProvider.GetFullHtmlFieldName(viewContext, expression);

if (!string.IsNullOrEmpty(fullName))

{

tagBuilder.MergeAttribute("name", fullName);

}

return tagBuilder;

}

///

public virtual TagBuilder GenerateForm(

ViewContext viewContext,

string actionName,

string controllerName,

object routeValues,

string method,

object htmlAttributes)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

var defaultMethod = false;

if (string.IsNullOrEmpty(method))

{

defaultMethod = true;

}

else if (HttpMethods.IsPost(method))

{

defaultMethod = true;

}

string action;

if (actionName == null && controllerName == null && routeValues == null && defaultMethod)

{

// Submit to the original URL in the special case that user called the BeginForm() overload without

// parameters (except for the htmlAttributes parameter). Also reachable in the even-more-unusual case

// that user called another BeginForm() overload with default argument values.

var request = viewContext.HttpContext.Request;

action = request.PathBase + request.Path + request.QueryString;

}

else

{

var urlHelper = _urlHelperFactory.GetUrlHelper(viewContext);

action = urlHelper.Action(action: actionName, controller: controllerName, values: routeValues);

}

return GenerateFormCore(viewContext, action, method, htmlAttributes);

}

///

public virtual TagBuilder GeneratePageForm(

ViewContext viewContext,

string pageName,

string pageHandler,

object routeValues,

string fragment,

string method,

object htmlAttributes)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

var urlHelper = _urlHelperFactory.GetUrlHelper(viewContext);

var action = urlHelper.Page(pageName, pageHandler, routeValues, protocol: null, host: null, fragment: fragment);

return GenerateFormCore(viewContext, action, method, htmlAttributes);

}

///

public TagBuilder GenerateRouteForm(

ViewContext viewContext,

string routeName,

object routeValues,

string method,

object htmlAttributes)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

var urlHelper = _urlHelperFactory.GetUrlHelper(viewContext);

var action = urlHelper.RouteUrl(routeName, routeValues);

return GenerateFormCore(viewContext, action, method, htmlAttributes);

}

///

public virtual TagBuilder GenerateHidden(

ViewContext viewContext,

ModelExplorer modelExplorer,

string expression,

object value,

bool useViewData,

object htmlAttributes)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

// Special-case opaque values and arbitrary binary data.

if (value is byte[] byteArrayValue)

{

value = Convert.ToBase64String(byteArrayValue);

}

var htmlAttributeDictionary = GetHtmlAttributeDictionaryOrNull(htmlAttributes);

return GenerateInput(

viewContext,

InputType.Hidden,

modelExplorer,

expression,

value,

useViewData,

isChecked: false,

setId: true,

isExplicitValue: true,

format: null,

htmlAttributes: htmlAttributeDictionary);

}

///

public virtual TagBuilder GenerateLabel(

ViewContext viewContext,

ModelExplorer modelExplorer,

string expression,

string labelText,

object htmlAttributes)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

if (modelExplorer == null)

{

throw new ArgumentNullException(nameof(modelExplorer));

}

var resolvedLabelText = labelText ??

modelExplorer.Metadata.DisplayName ??

modelExplorer.Metadata.PropertyName;

if (resolvedLabelText == null && expression != null)

{

var index = expression.LastIndexOf('.');

if (index == -1)

{

// Expression does not contain a dot separator.

resolvedLabelText = expression;

}

else

{

resolvedLabelText = expression.Substring(index + 1);

}

}

var tagBuilder = new TagBuilder("label");

var fullName = NameAndIdProvider.GetFullHtmlFieldName(viewContext, expression);

var idString = NameAndIdProvider.CreateSanitizedId(viewContext, fullName, IdAttributeDotReplacement);

tagBuilder.Attributes.Add("for", idString);

tagBuilder.InnerHtml.SetContent(resolvedLabelText);

tagBuilder.MergeAttributes(GetHtmlAttributeDictionaryOrNull(htmlAttributes), replaceExisting: true);

return tagBuilder;

}

///

public virtual TagBuilder GeneratePassword(

ViewContext viewContext,

ModelExplorer modelExplorer,

string expression,

object value,

object htmlAttributes)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

var htmlAttributeDictionary = GetHtmlAttributeDictionaryOrNull(htmlAttributes);

return GenerateInput(

viewContext,

InputType.Password,

modelExplorer,

expression,

value,

useViewData: false,

isChecked: false,

setId: true,

isExplicitValue: true,

format: null,

htmlAttributes: htmlAttributeDictionary);

}

///

public virtual TagBuilder GenerateRadioButton(

ViewContext viewContext,

ModelExplorer modelExplorer,

string expression,

object value,

bool? isChecked,

object htmlAttributes)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

var htmlAttributeDictionary = GetHtmlAttributeDictionaryOrNull(htmlAttributes);

if (modelExplorer == null)

{

// RadioButton() case. Do not override checked attribute if isChecked is implicit.

if (!isChecked.HasValue &&

(htmlAttributeDictionary == null || !htmlAttributeDictionary.ContainsKey("checked")))

{

// Note value may be null if isChecked is non-null.

if (value == null)

{

throw new ArgumentNullException(nameof(value));

}

// isChecked not provided nor found in the given attributes; fall back to view data.

var valueString = Convert.ToString(value, CultureInfo.CurrentCulture);

isChecked = string.Equals(

EvalString(viewContext, expression),

valueString,

StringComparison.OrdinalIgnoreCase);

}

}

else

{

// RadioButtonFor() case. That API does not support passing isChecked directly.

Debug.Assert(!isChecked.HasValue);

// Need a value to determine isChecked.

Debug.Assert(value != null);

var model = modelExplorer.Model;

var valueString = Convert.ToString(value, CultureInfo.CurrentCulture);

isChecked = model != null &&

string.Equals(model.ToString(), valueString, StringComparison.OrdinalIgnoreCase);

}

if (isChecked.HasValue && htmlAttributeDictionary != null)

{

// Explicit isChecked value must override "checked" in dictionary.

htmlAttributeDictionary.Remove("checked");

}

return GenerateInput(

viewContext,

InputType.Radio,

modelExplorer,

expression,

value,

useViewData: false,

isChecked: isChecked ?? false,

setId: true,

isExplicitValue: true,

format: null,

htmlAttributes: htmlAttributeDictionary);

}

///

public virtual TagBuilder GenerateRouteLink(

ViewContext viewContext,

string linkText,

string routeName,

string protocol,

string hostName,

string fragment,

object routeValues,

object htmlAttributes)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

if (linkText == null)

{

throw new ArgumentNullException(nameof(linkText));

}

var urlHelper = _urlHelperFactory.GetUrlHelper(viewContext);

var url = urlHelper.RouteUrl(routeName, routeValues, protocol, hostName, fragment);

return GenerateLink(linkText, url, htmlAttributes);

}

///

public TagBuilder GenerateSelect(

ViewContext viewContext,

ModelExplorer modelExplorer,

string optionLabel,

string expression,

IEnumerable selectList,

bool allowMultiple,

object htmlAttributes)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

var currentValues = GetCurrentValues(viewContext, modelExplorer, expression, allowMultiple);

return GenerateSelect(

viewContext,

modelExplorer,

optionLabel,

expression,

selectList,

currentValues,

allowMultiple,

htmlAttributes);

}

///

public virtual TagBuilder GenerateSelect(

ViewContext viewContext,

ModelExplorer modelExplorer,

string optionLabel,

string expression,

IEnumerable selectList,

ICollection currentValues,

bool allowMultiple,

object htmlAttributes)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

var fullName = NameAndIdProvider.GetFullHtmlFieldName(viewContext, expression);

var htmlAttributeDictionary = GetHtmlAttributeDictionaryOrNull(htmlAttributes);

if (!IsFullNameValid(fullName, htmlAttributeDictionary))

{

throw new ArgumentException(

Resources.FormatHtmlGenerator_FieldNameCannotBeNullOrEmpty(

typeof(IHtmlHelper).FullName,

nameof(IHtmlHelper.Editor),

typeof(IHtmlHelper<>).FullName,

nameof(IHtmlHelper.EditorFor),

"htmlFieldName"),

nameof(expression));

}

// If we got a null selectList, try to use ViewData to get the list of items.

if (selectList == null)

{

selectList = GetSelectListItems(viewContext, expression);

}

modelExplorer = modelExplorer ??

ExpressionMetadataProvider.FromStringExpression(expression, viewContext.ViewData, _metadataProvider);

// Convert each ListItem to an tag and wrap them with if requested.

var listItemBuilder = GenerateGroupsAndOptions(optionLabel, selectList, currentValues);

var tagBuilder = new TagBuilder("select");

tagBuilder.InnerHtml.SetHtmlContent(listItemBuilder);

tagBuilder.MergeAttributes(htmlAttributeDictionary);

NameAndIdProvider.GenerateId(viewContext, tagBuilder, fullName, IdAttributeDotReplacement);

if (!string.IsNullOrEmpty(fullName))

{

tagBuilder.MergeAttribute("name", fullName, replaceExisting: true);

}

if (allowMultiple)

{

tagBuilder.MergeAttribute("multiple", "multiple");

}

// If there are any errors for a named field, we add the css attribute.

if (viewContext.ViewData.ModelState.TryGetValue(fullName, out var entry))

{

if (entry.Errors.Count > 0)

{

tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);

}

}

AddValidationAttributes(viewContext, tagBuilder, modelExplorer, expression);

return tagBuilder;

}

///

public virtual TagBuilder GenerateTextArea(

ViewContext viewContext,

ModelExplorer modelExplorer,

string expression,

int rows,

int columns,

object htmlAttributes)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

if (rows < 0)

{

throw new ArgumentOutOfRangeException(nameof(rows), Resources.HtmlHelper_TextAreaParameterOutOfRange);

}

if (columns < 0)

{

throw new ArgumentOutOfRangeException(

nameof(columns),

Resources.HtmlHelper_TextAreaParameterOutOfRange);

}

var fullName = NameAndIdProvider.GetFullHtmlFieldName(viewContext, expression);

var htmlAttributeDictionary = GetHtmlAttributeDictionaryOrNull(htmlAttributes);

if (!IsFullNameValid(fullName, htmlAttributeDictionary))

{

throw new ArgumentException(

Resources.FormatHtmlGenerator_FieldNameCannotBeNullOrEmpty(

typeof(IHtmlHelper).FullName,

nameof(IHtmlHelper.Editor),

typeof(IHtmlHelper<>).FullName,

nameof(IHtmlHelper.EditorFor),

"htmlFieldName"),

nameof(expression));

}

viewContext.ViewData.ModelState.TryGetValue(fullName, out var entry);

var value = string.Empty;

if (entry != null && entry.AttemptedValue != null)

{

value = entry.AttemptedValue;

}

else if (modelExplorer.Model != null)

{

value = modelExplorer.Model.ToString();

}

var tagBuilder = new TagBuilder("textarea");

NameAndIdProvider.GenerateId(viewContext, tagBuilder, fullName, IdAttributeDotReplacement);

tagBuilder.MergeAttributes(htmlAttributeDictionary, replaceExisting: true);

if (rows > 0)

{

tagBuilder.MergeAttribute("rows", rows.ToString(CultureInfo.InvariantCulture), replaceExisting: true);

}

if (columns > 0)

{

tagBuilder.MergeAttribute(

"cols",

columns.ToString(CultureInfo.InvariantCulture),

replaceExisting: true);

}

if (!string.IsNullOrEmpty(fullName))

{

tagBuilder.MergeAttribute("name", fullName, replaceExisting: true);

}

AddPlaceholderAttribute(viewContext.ViewData, tagBuilder, modelExplorer, expression);

AddMaxLengthAttribute(viewContext.ViewData, tagBuilder, modelExplorer, expression);

AddValidationAttributes(viewContext, tagBuilder, modelExplorer, expression);

// If there are any errors for a named field, we add this CSS attribute.

if (entry != null && entry.Errors.Count > 0)

{

tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);

}

// The first newline is always trimmed when a TextArea is rendered, so we add an extra one

// in case the value being rendered is something like "\r\nHello"

tagBuilder.InnerHtml.AppendLine();

tagBuilder.InnerHtml.Append(value);

return tagBuilder;

}

///

public virtual TagBuilder GenerateTextBox(

ViewContext viewContext,

ModelExplorer modelExplorer,

string expression,

object value,

string format,

object htmlAttributes)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

var htmlAttributeDictionary = GetHtmlAttributeDictionaryOrNull(htmlAttributes);

return GenerateInput(

viewContext,

InputType.Text,

modelExplorer,

expression,

value,

useViewData: (modelExplorer == null && value == null),

isChecked: false,

setId: true,

isExplicitValue: true,

format: format,

htmlAttributes: htmlAttributeDictionary);

}

///

public virtual TagBuilder GenerateValidationMessage(

ViewContext viewContext,

ModelExplorer modelExplorer,

string expression,

string message,

string tag,

object htmlAttributes)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

var fullName = NameAndIdProvider.GetFullHtmlFieldName(viewContext, expression);

var htmlAttributeDictionary = GetHtmlAttributeDictionaryOrNull(htmlAttributes);

if (!IsFullNameValid(fullName, htmlAttributeDictionary, fallbackAttributeName: "data-valmsg-for"))

{

throw new ArgumentException(

Resources.FormatHtmlGenerator_FieldNameCannotBeNullOrEmpty(

typeof(IHtmlHelper).FullName,

nameof(IHtmlHelper.Editor),

typeof(IHtmlHelper<>).FullName,

nameof(IHtmlHelper.EditorFor),

"htmlFieldName"),

nameof(expression));

}

var formContext = viewContext.ClientValidationEnabled ? viewContext.FormContext : null;

if (!viewContext.ViewData.ModelState.ContainsKey(fullName) && formContext == null)

{

return null;

}

var tryGetModelStateResult = viewContext.ViewData.ModelState.TryGetValue(fullName, out var entry);

var modelErrors = tryGetModelStateResult ? entry.Errors : null;

ModelError modelError = null;

if (modelErrors != null && modelErrors.Count != 0)

{

modelError = modelErrors.FirstOrDefault(m => !string.IsNullOrEmpty(m.ErrorMessage)) ?? modelErrors[0];

}

if (modelError == null && formContext == null)

{

return null;

}

// Even if there are no model errors, we generate the span and add the validation message

// if formContext is not null.

if (string.IsNullOrEmpty(tag))

{

tag = viewContext.ValidationMessageElement;

}

var tagBuilder = new TagBuilder(tag);

tagBuilder.MergeAttributes(htmlAttributeDictionary);

// Only the style of the span is changed according to the errors if message is null or empty.

// Otherwise the content and style is handled by the client-side validation.

var className = (modelError != null) ?

HtmlHelper.ValidationMessageCssClassName :

HtmlHelper.ValidationMessageValidCssClassName;

tagBuilder.AddCssClass(className);

if (!string.IsNullOrEmpty(message))

{

tagBuilder.InnerHtml.SetContent(message);

}

else if (modelError != null)

{

modelExplorer = modelExplorer ?? ExpressionMetadataProvider.FromStringExpression(

expression,

viewContext.ViewData,

_metadataProvider);

tagBuilder.InnerHtml.SetContent(

ValidationHelpers.GetModelErrorMessageOrDefault(modelError, entry, modelExplorer));

}

if (formContext != null)

{

if (!string.IsNullOrEmpty(fullName))

{

tagBuilder.MergeAttribute("data-valmsg-for", fullName);

}

var replaceValidationMessageContents = string.IsNullOrEmpty(message);

tagBuilder.MergeAttribute("data-valmsg-replace",

replaceValidationMessageContents.ToString().ToLowerInvariant());

}

return tagBuilder;

}

///

public virtual TagBuilder GenerateValidationSummary(

ViewContext viewContext,

bool excludePropertyErrors,

string message,

string headerTag,

object htmlAttributes)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

var viewData = viewContext.ViewData;

if (!viewContext.ClientValidationEnabled && viewData.ModelState.IsValid)

{

// Client-side validation is not enabled to add to the generated element and element will be empty.

return null;

}

if (excludePropertyErrors &&

(!viewData.ModelState.TryGetValue(viewData.TemplateInfo.HtmlFieldPrefix, out var entryForModel) ||

entryForModel.Errors.Count == 0))

{

// Client-side validation (if enabled) will not affect the generated element and element will be empty.

return null;

}

TagBuilder messageTag;

if (string.IsNullOrEmpty(message))

{

messageTag = null;

}

else

{

if (string.IsNullOrEmpty(headerTag))

{

headerTag = viewContext.ValidationSummaryMessageElement;

}

messageTag = new TagBuilder(headerTag);

messageTag.InnerHtml.SetContent(message);

}

// If excludePropertyErrors is true, describe any validation issue with the current model in a single item.

// Otherwise, list individual property errors.

var isHtmlSummaryModified = false;

var modelStates = ValidationHelpers.GetModelStateList(viewData, excludePropertyErrors);

var htmlSummary = new TagBuilder("ul");

foreach (var modelState in modelStates)

{

// Perf: Avoid allocations

for (var i = 0; i < modelState.Errors.Count; i++)

{

var modelError = modelState.Errors[i];

var errorText = ValidationHelpers.GetModelErrorMessageOrDefault(modelError);

if (!string.IsNullOrEmpty(errorText))

{

var listItem = new TagBuilder("li");

listItem.InnerHtml.SetContent(errorText);

htmlSummary.InnerHtml.AppendLine(listItem);

isHtmlSummaryModified = true;

}

}

}

if (!isHtmlSummaryModified)

{

htmlSummary.InnerHtml.AppendHtml(HiddenListItem);

htmlSummary.InnerHtml.AppendLine();

}

var tagBuilder = new TagBuilder("div");

tagBuilder.MergeAttributes(GetHtmlAttributeDictionaryOrNull(htmlAttributes));

if (viewData.ModelState.IsValid)

{

tagBuilder.AddCssClass(HtmlHelper.ValidationSummaryValidCssClassName);

}

else

{

tagBuilder.AddCssClass(HtmlHelper.ValidationSummaryCssClassName);

}

if (messageTag != null)

{

tagBuilder.InnerHtml.AppendLine(messageTag);

}

tagBuilder.InnerHtml.AppendHtml(htmlSummary);

if (viewContext.ClientValidationEnabled && !excludePropertyErrors)

{

// Inform the client where to replace the list of property errors after validation.

tagBuilder.MergeAttribute("data-valmsg-summary", "true");

}

return tagBuilder;

}

///

public virtual ICollection GetCurrentValues(

ViewContext viewContext,

ModelExplorer modelExplorer,

string expression,

bool allowMultiple)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

var fullName = NameAndIdProvider.GetFullHtmlFieldName(viewContext, expression);

var type = allowMultiple ? typeof(string[]) : typeof(string);

var rawValue = GetModelStateValue(viewContext, fullName, type);

// If ModelState did not contain a current value, fall back to ViewData- or ModelExplorer-supplied value.

if (rawValue == null)

{

if (modelExplorer == null)

{

// Html.DropDownList() and Html.ListBox() helper case.

rawValue = viewContext.ViewData.Eval(expression);

if (rawValue is IEnumerable)

{

// This ViewData item contains the fallback selectList collection for GenerateSelect().

// Do not try to use this collection.

rawValue = null;

}

}

else

{

// , Html.DropDownListFor() and Html.ListBoxFor() helper case. Do not use ViewData.

rawValue = modelExplorer.Model;

}

if (rawValue == null)

{

return null;

}

}

// Convert raw value to a collection.

IEnumerable rawValues;

if (allowMultiple)

{

rawValues = rawValue as IEnumerable;

if (rawValues == null || rawValues is string)

{

throw new InvalidOperationException(

Resources.FormatHtmlHelper_SelectExpressionNotEnumerable(nameof(expression)));

}

}

else

{

rawValues = new[] { rawValue };

}

modelExplorer = modelExplorer ??

ExpressionMetadataProvider.FromStringExpression(expression, viewContext.ViewData, _metadataProvider);

var metadata = modelExplorer.Metadata;

if (allowMultiple && metadata.IsEnumerableType)

{

metadata = metadata.ElementMetadata;

}

var enumNames = metadata.EnumNamesAndValues;

var isTargetEnum = metadata.IsEnum;

// Logic below assumes isTargetEnum and enumNames are consistent. Confirm that expectation is met.

Debug.Assert(isTargetEnum ^ enumNames == null);

var innerType = metadata.UnderlyingOrModelType;

// Convert raw value collection to strings.

var currentValues = new HashSet(StringComparer.OrdinalIgnoreCase);

foreach (var value in rawValues)

{

// Add original or converted string.

var stringValue = (value as string) ?? Convert.ToString(value, CultureInfo.CurrentCulture);

// Do not add simple names of enum properties here because whitespace isn't relevant for their binding.

// Will add matching names just below.

if (enumNames == null || !enumNames.ContainsKey(stringValue.Trim()))

{

currentValues.Add(stringValue);

}

// Remainder handles isEnum cases. Convert.ToString() returns field names for enum values but select

// list may (well, should) contain integer values.

var enumValue = value as Enum;

if (isTargetEnum && enumValue == null && value != null)

{

var valueType = value.GetType();

if (typeof(long).IsAssignableFrom(valueType) || typeof(ulong).IsAssignableFrom(valueType))

{

// E.g. user added an int to a ViewData entry and called a string-based HTML helper.

enumValue = ConvertEnumFromInteger(value, innerType);

}

else if (!string.IsNullOrEmpty(stringValue))

{

// E.g. got a string from ModelState.

var methodInfo = ConvertEnumFromStringMethod.MakeGenericMethod(innerType);

enumValue = (Enum)methodInfo.Invoke(obj: null, parameters: new[] { stringValue });

}

}

if (enumValue != null)

{

// Add integer value.

var integerString = enumValue.ToString("d");

currentValues.Add(integerString);

// isTargetEnum may be false when raw value has a different type than the target e.g. ViewData

// contains enum values and property has type int or string.

if (isTargetEnum)

{

// Add all simple names for this value.

var matchingNames = enumNames

.Where(kvp => string.Equals(integerString, kvp.Value, StringComparison.Ordinal))

.Select(kvp => kvp.Key);

foreach (var name in matchingNames)

{

currentValues.Add(name);

}

}

}

}

return currentValues;

}

internal static string EvalString(ViewContext viewContext, string key, string format)

{

return Convert.ToString(viewContext.ViewData.Eval(key, format), CultureInfo.CurrentCulture);

}

///

/// Not used directly in HtmlHelper. Exposed for use in DefaultDisplayTemplates.

///

internal static TagBuilder GenerateOption(SelectListItem item, string text)

{

return GenerateOption(item, text, item.Selected);

}

internal static TagBuilder GenerateOption(SelectListItem item, string text, bool selected)

{

var tagBuilder = new TagBuilder("option");

tagBuilder.InnerHtml.SetContent(text);

if (item.Value != null)

{

tagBuilder.Attributes["value"] = item.Value;

}

if (selected)

{

tagBuilder.Attributes["selected"] = "selected";

}

if (item.Disabled)

{

tagBuilder.Attributes["disabled"] = "disabled";

}

return tagBuilder;

}

internal static object GetModelStateValue(ViewContext viewContext, string key, Type destinationType)

{

if (viewContext.ViewData.ModelState.TryGetValue(key, out var entry) && entry.RawValue != null)

{

return ModelBindingHelper.ConvertTo(entry.RawValue, destinationType, culture: null);

}

return null;

}

///

/// Generate a <form> element.

///

/// A instance for the current scope.

/// The URL where the form-data should be submitted.

/// The HTTP method for processing the form, either GET or POST.

///

/// An that contains the HTML attributes for the element. Alternatively, an

/// instance containing the HTML attributes.

///

///

/// A instance for the </form> element.

///

protected virtual TagBuilder GenerateFormCore(

ViewContext viewContext,

string action,

string method,

object htmlAttributes)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

var tagBuilder = new TagBuilder("form");

tagBuilder.MergeAttributes(GetHtmlAttributeDictionaryOrNull(htmlAttributes));

// action is implicitly generated from other parameters, so htmlAttributes take precedence.

tagBuilder.MergeAttribute("action", action);

if (string.IsNullOrEmpty(method))

{

// Occurs only when called from a tag helper.

method = "post";

}

// For tag helpers, htmlAttributes will be null; replaceExisting value does not matter.

// method is an explicit parameter to HTML helpers, so it takes precedence over the htmlAttributes.

tagBuilder.MergeAttribute("method", method, replaceExisting: true);

return tagBuilder;

}

///

/// Generate an input tag.

///

/// The .

/// The .

/// The .

/// The expression.

/// The value.

/// Whether to use view data.

/// If the input is checked.

/// Whether this should set id.

/// Whether this is an explicit value.

/// The format.

/// The html attributes.

///

protected virtual TagBuilder GenerateInput(

ViewContext viewContext,

InputType inputType,

ModelExplorer modelExplorer,

string expression,

object value,

bool useViewData,

bool isChecked,

bool setId,

bool isExplicitValue,

string format,

IDictionary htmlAttributes)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

// Not valid to use TextBoxForModel() and so on in a top-level view; would end up with an unnamed input

// elements. But we support the *ForModel() methods in any lower-level template, once HtmlFieldPrefix is

// non-empty.

var fullName = NameAndIdProvider.GetFullHtmlFieldName(viewContext, expression);

if (!IsFullNameValid(fullName, htmlAttributes))

{

throw new ArgumentException(

Resources.FormatHtmlGenerator_FieldNameCannotBeNullOrEmpty(

typeof(IHtmlHelper).FullName,

nameof(IHtmlHelper.Editor),

typeof(IHtmlHelper<>).FullName,

nameof(IHtmlHelper.EditorFor),

"htmlFieldName"),

nameof(expression));

}

var inputTypeString = GetInputTypeString(inputType);

var tagBuilder = new TagBuilder("input")

{

TagRenderMode = TagRenderMode.SelfClosing,

};

tagBuilder.MergeAttributes(htmlAttributes);

tagBuilder.MergeAttribute("type", inputTypeString);

if (!string.IsNullOrEmpty(fullName))

{

tagBuilder.MergeAttribute("name", fullName, replaceExisting: true);

}

var suppliedTypeString = tagBuilder.Attributes["type"];

if (_placeholderInputTypes.Contains(suppliedTypeString))

{

AddPlaceholderAttribute(viewContext.ViewData, tagBuilder, modelExplorer, expression);

}

if (_maxLengthInputTypes.Contains(suppliedTypeString))

{

AddMaxLengthAttribute(viewContext.ViewData, tagBuilder, modelExplorer, expression);

}

var valueParameter = FormatValue(value, format);

var usedModelState = false;

switch (inputType)

{

case InputType.CheckBox:

var modelStateWasChecked = GetModelStateValue(viewContext, fullName, typeof(bool)) as bool?;

if (modelStateWasChecked.HasValue)

{

isChecked = modelStateWasChecked.Value;

usedModelState = true;

}

goto case InputType.Radio;

case InputType.Radio:

if (!usedModelState)

{

if (GetModelStateValue(viewContext, fullName, typeof(string)) is string modelStateValue)

{

isChecked = string.Equals(modelStateValue, valueParameter, StringComparison.Ordinal);

usedModelState = true;

}

}

if (!usedModelState && useViewData)

{

isChecked = EvalBoolean(viewContext, expression);

}

if (isChecked)

{

tagBuilder.MergeAttribute("checked", "checked");

}

tagBuilder.MergeAttribute("value", valueParameter, isExplicitValue);

break;

case InputType.Password:

if (value != null)

{

tagBuilder.MergeAttribute("value", valueParameter, isExplicitValue);

}

break;

case InputType.Text:

default:

var attributeValue = (string)GetModelStateValue(viewContext, fullName, typeof(string));

if (attributeValue == null)

{

attributeValue = useViewData ? EvalString(viewContext, expression, format) : valueParameter;

}

var addValue = true;

object typeAttributeValue;

if (htmlAttributes != null && htmlAttributes.TryGetValue("type", out typeAttributeValue))

{

var typeAttributeString = typeAttributeValue.ToString();

if (string.Equals(typeAttributeString, "file", StringComparison.OrdinalIgnoreCase) ||

string.Equals(typeAttributeString, "image", StringComparison.OrdinalIgnoreCase))

{

// 'value' attribute is not needed for 'file' and 'image' input types.

addValue = false;

}

}

if (addValue)

{

tagBuilder.MergeAttribute("value", attributeValue, replaceExisting: isExplicitValue);

}

break;

}

if (setId)

{

NameAndIdProvider.GenerateId(viewContext, tagBuilder, fullName, IdAttributeDotReplacement);

}

// If there are any errors for a named field, we add the CSS attribute.

if (viewContext.ViewData.ModelState.TryGetValue(fullName, out var entry) && entry.Errors.Count > 0)

{

tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);

}

AddValidationAttributes(viewContext, tagBuilder, modelExplorer, expression);

return tagBuilder;

}

///

/// Generate a link.

///

/// The text for the link.

/// The url for the link.

/// The html attributes.

/// The .

protected virtual TagBuilder GenerateLink(

string linkText,

string url,

object htmlAttributes)

{

if (linkText == null)

{

throw new ArgumentNullException(nameof(linkText));

}

var tagBuilder = new TagBuilder("a");

tagBuilder.InnerHtml.SetContent(linkText);

tagBuilder.MergeAttributes(GetHtmlAttributeDictionaryOrNull(htmlAttributes));

tagBuilder.MergeAttribute("href", url);

return tagBuilder;

}

///

/// Adds a placeholder attribute to the .

///

/// A instance for the current scope.

/// A instance.

/// The for the .

/// Expression name, relative to the current model.

protected virtual void AddPlaceholderAttribute(

ViewDataDictionary viewData,

TagBuilder tagBuilder,

ModelExplorer modelExplorer,

string expression)

{

modelExplorer = modelExplorer ?? ExpressionMetadataProvider.FromStringExpression(

expression,

viewData,

_metadataProvider);

var placeholder = modelExplorer.Metadata.Placeholder;

if (!string.IsNullOrEmpty(placeholder))

{

tagBuilder.MergeAttribute("placeholder", placeholder);

}

}

///

/// Adds a maxlength attribute to the .

///

/// A instance for the current scope.

/// A instance.

/// The for the .

/// Expression name, relative to the current model.

protected virtual void AddMaxLengthAttribute(

ViewDataDictionary viewData,

TagBuilder tagBuilder,

ModelExplorer modelExplorer,

string expression)

{

modelExplorer = modelExplorer ?? ExpressionMetadataProvider.FromStringExpression(

expression,

viewData,

_metadataProvider);

int? maxLengthValue = null;

foreach (var attribute in modelExplorer.Metadata.ValidatorMetadata)

{

if (attribute is MaxLengthAttribute maxLengthAttribute && (!maxLengthValue.HasValue || maxLengthValue.Value > maxLengthAttribute.Length))

{

maxLengthValue = maxLengthAttribute.Length;

}

else if (attribute is StringLengthAttribute stringLengthAttribute && (!maxLengthValue.HasValue || maxLengthValue.Value > stringLengthAttribute.MaximumLength))

{

maxLengthValue = stringLengthAttribute.MaximumLength;

}

}

if (maxLengthValue.HasValue)

{

tagBuilder.MergeAttribute("maxlength", maxLengthValue.Value.ToString(CultureInfo.InvariantCulture));

}

}

///

/// Adds validation attributes to the if client validation

/// is enabled.

///

/// A instance for the current scope.

/// A instance.

/// The for the .

/// Expression name, relative to the current model.

protected virtual void AddValidationAttributes(

ViewContext viewContext,

TagBuilder tagBuilder,

ModelExplorer modelExplorer,

string expression)

{

modelExplorer = modelExplorer ?? ExpressionMetadataProvider.FromStringExpression(

expression,

viewContext.ViewData,

_metadataProvider);

_validationAttributeProvider.AddAndTrackValidationAttributes(

viewContext,

modelExplorer,

expression,

tagBuilder.Attributes);

}

private static Enum ConvertEnumFromInteger(object value, Type targetType)

{

try

{

return (Enum)Enum.ToObject(targetType, value);

}

catch (Exception exception)

when (exception is FormatException || exception.InnerException is FormatException)

{

// The integer was too large for this enum type.

return null;

}

}

private static object ConvertEnumFromString(string value) where TEnum : struct

{

if (Enum.TryParse(value, out TEnum enumValue))

{

return enumValue;

}

// Do not return default(TEnum) when parse was unsuccessful.

return null;

}

private static bool EvalBoolean(ViewContext viewContext, string key)

{

return Convert.ToBoolean(viewContext.ViewData.Eval(key), CultureInfo.InvariantCulture);

}

private static string EvalString(ViewContext viewContext, string key)

{

return Convert.ToString(viewContext.ViewData.Eval(key), CultureInfo.CurrentCulture);

}

// Only need a dictionary if htmlAttributes is non-null. TagBuilder.MergeAttributes() is fine with null.

private static IDictionary GetHtmlAttributeDictionaryOrNull(object htmlAttributes)

{

IDictionary htmlAttributeDictionary = null;

if (htmlAttributes != null)

{

htmlAttributeDictionary = htmlAttributes as IDictionary;

if (htmlAttributeDictionary == null)

{

htmlAttributeDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

}

}

return htmlAttributeDictionary;

}

private static string GetInputTypeString(InputType inputType)

{

switch (inputType)

{

case InputType.CheckBox:

return "checkbox";

case InputType.Hidden:

return "hidden";

case InputType.Password:

return "password";

case InputType.Radio:

return "radio";

case InputType.Text:

return "text";

default:

return "text";

}

}

private static IEnumerable GetSelectListItems(

ViewContext viewContext,

string expression)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

// Method is called only if user did not pass a select list in. They must provide select list items in the

// ViewData dictionary and definitely not as the Model. (Even if the Model datatype were correct, a

// element generated for a collection of SelectListItems would be useless.)

var value = viewContext.ViewData.Eval(expression);

// First check whether above evaluation was successful and did not match ViewData.Model.

if (value == null || value == viewContext.ViewData.Model)

{

throw new InvalidOperationException(Resources.FormatHtmlHelper_MissingSelectData(

$"IEnumerable",

expression));

}

// Second check the Eval() call returned a collection of SelectListItems.

if (!(value is IEnumerable selectList))

{

throw new InvalidOperationException(Resources.FormatHtmlHelper_WrongSelectDataType(

expression,

value.GetType().FullName,

$"IEnumerable"));

}

return selectList;

}

private static bool IsFullNameValid(string fullName, IDictionary htmlAttributeDictionary)

{

return IsFullNameValid(fullName, htmlAttributeDictionary, fallbackAttributeName: "name");

}

private static bool IsFullNameValid(

string fullName,

IDictionary htmlAttributeDictionary,

string fallbackAttributeName)

{

if (string.IsNullOrEmpty(fullName))

{

// fullName==null is normally an error because name="" is not valid in HTML 5.

if (htmlAttributeDictionary == null)

{

return false;

}

// Check if user has provided an explicit name attribute.

// Generalized a bit because other attributes e.g. data-valmsg-for refer to element names.

htmlAttributeDictionary.TryGetValue(fallbackAttributeName, out var attributeObject);

var attributeString = Convert.ToString(attributeObject, CultureInfo.InvariantCulture);

if (string.IsNullOrEmpty(attributeString))

{

return false;

}

}

return true;

}

///

public IHtmlContent GenerateGroupsAndOptions(string optionLabel, IEnumerable selectList)

{

return GenerateGroupsAndOptions(optionLabel, selectList, currentValues: null);

}

private IHtmlContent GenerateGroupsAndOptions(

string optionLabel,

IEnumerable selectList,

ICollection currentValues)

{

if (!(selectList is IList itemsList))

{

itemsList = selectList.ToList();

}

var count = itemsList.Count;

if (optionLabel != null)

{

count++;

}

// Short-circuit work below if there's nothing to add.

if (count == 0)

{

return HtmlString.Empty;

}

var listItemBuilder = new HtmlContentBuilder(count);

// Make optionLabel the first item that gets rendered.

if (optionLabel != null)

{

listItemBuilder.AppendLine(GenerateOption(

new SelectListItem()

{

Text = optionLabel,

Value = string.Empty,

Selected = false,

},

currentValues: null));

}

// Group items in the SelectList if requested.

// The worst case complexity of this algorithm is O(number of groups*n).

// If there aren't any groups, it is O(n) where n is number of items in the list.

var optionGenerated = new bool[itemsList.Count];

for (var i = 0; i < itemsList.Count; i++)

{

if (!optionGenerated[i])

{

var item = itemsList[i];

var optGroup = item.Group;

if (optGroup != null)

{

var groupBuilder = new TagBuilder("optgroup");

if (optGroup.Name != null)

{

groupBuilder.MergeAttribute("label", optGroup.Name);

}

if (optGroup.Disabled)

{

groupBuilder.MergeAttribute("disabled", "disabled");

}

groupBuilder.InnerHtml.AppendLine();

for (var j = i; j < itemsList.Count; j++)

{

var groupItem = itemsList[j];

if (!optionGenerated[j] &&

object.ReferenceEquals(optGroup, groupItem.Group))

{

groupBuilder.InnerHtml.AppendLine(GenerateOption(groupItem, currentValues));

optionGenerated[j] = true;

}

}

listItemBuilder.AppendLine(groupBuilder);

}

else

{

listItemBuilder.AppendLine(GenerateOption(item, currentValues));

optionGenerated[i] = true;

}

}

}

return listItemBuilder;

}

private IHtmlContent GenerateOption(SelectListItem item, ICollection currentValues)

{

var selected = item.Selected;

if (currentValues != null)

{

var value = item.Value ?? item.Text;

selected = currentValues.Contains(value);

}

var tagBuilder = GenerateOption(item, item.Text, selected);

return tagBuilder;

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ava实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),可运行高分资源 Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。下面详细介绍C语言的基本概念和语法。 1. 变量和数据类型 在C语言中,变量用于存储数据,数据类型用于定义变量的类型和范围。C语言支持多种数据类型,包括基本数据类型(如int、float、char等)和复合数据类型(如结构体、联合等)。 2. 运算符 C语言中常用的运算符包括算术运算符(如+、、、/等)、关系运算符(如==、!=、、=、<、<=等)、逻辑运算符(如&&、||、!等)。此外,还有位运算符(如&、|、^等)和指针运算符(如、等)。 3. 控制结构 C语言中常用的控制结构包括if语句、循环语句(如for、while等)和switch语句。通过这些控制结构,可以实现程序的分支、循环和多路选择等功能。 4. 函数 函数是C语言中用于封装代码的单元,可以实现代码的复用和模块化。C语言中定义函数使用关键字“void”或返回值类型(如int、float等),并通过“{”和“}”括起来的代码块来实现函数的功能。 5. 指针 指针是C语言中用于存储变量地址的变量。通过指针,可以实现对内存的间接访问和修改。C语言中定义指针使用星号()符号,指向数组、字符串和结构体等数据结构时,还需要注意数组名和字符串常量的特殊性质。 6. 数组和字符串 数组是C语言中用于存储同类型数据的结构,可以通过索引访问和修改数组中的元素。字符串是C语言中用于存储文本数据的特殊类型,通常以字符串常量的形式出现,用双引号("...")括起来,末尾自动添加'\0'字符。 7. 结构体和联合 结构体和联合是C语言中用于存储不同类型数据的复合数据类型。结构体由多个成员组成,每个成员可以是不同的数据类型;联合由多个变量组成,它们共用同一块内存空间。通过结构体和联合,可以实现数据的封装和抽象。 8. 文件操作 C语言中通过文件操作函数(如fopen、fclose、fread、fwrite等)实现对文件的读写操作。文件操作函数通常返回文件指针,用于表示打开的文件。通过文件指针,可以进行文件的定位、读写等操作。 总之,C语言是一种功能强大、灵活高效的编程语言,广泛应用于各种领域。掌握C语言的基本语法和数据结构,可以为编程学习和实践打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值