Newtonsoft.Json C# Json序列化和反序列化工具的使用、类型方法大全 C# 算法题系列(二) 各位相加、整数反转、回文数、罗马数字转整数 C# 算法题系列(一) 两数之和、无重复字符的最长子串 DateTime Tips c#发送邮件,可发送多个附件 MVC图片上传详解
Newtonsoft.Json C# Json序列化和反序列化工具的使用、类型方法大全
Newtonsoft.Json
Newtonsoft.Json 是.Net平台操作Json的工具,他的介绍就不多说了,笔者最近在弄接口,需要操作Json。
以某个云计算平台的Token为例,边操作边讲解。
Json 转为 Model
将 Model 转为 Json
将 LINQ 转为 JSON
Linq 操作
命名空间、类型、方法大全
另外附上 百度AI 文字识别 Json 及其模型类
Newtonsoft.Json 将字符串转为对象,是根据类型对象名称进行的,大小写不分,但是名称要一致要,哪怕你的json只有一个
{ "a":1 }
你的对象
public class Test { public int aa{get;set;} }
也是不能对应的。
有复杂层次的 json,可以使用 “类中类” 来映射,要注意 List<T>/Array/ArrayList的类型的使用。
Json 转为 Model
新建一个 Json 文件,名字随意,例如 json1.json
把以下内容粘贴进去
{ "refresh_token": "25.ea2f85ebd48df85fe5400000.18640.282335-15533349", "expires_in": 2592010, "session_key": "9mzdWr3n8ncMeDgX8zjhkhlW8khb5cdZtPevPbPwQGBg==", "access_token": "24.ac0ca9fakhlkyhl552017858.282335-15533349", "scope": "audio_voice_assistant_get audio_tts_post public vis-ocr_ocr nlp_simnet nlp_wclassify_watermark brain_ocr_scope vis-classify_car brain_gif_antiporn brain_ocr_general brain_ocr_general_basic brain_ocr_generer vis-classify_animal brain_politician brain_unit_utterance brain_imgquality_general brain_nlp_simnet brain_nlp_depparser vis-classify_plant brain_solution brain_ocr_plate_number brain_nlp_wordembedding brain_nlp_dnnlm_cn_legacy brain_nlp_simnet_legacy brain_nlp_commain_animal_classify brain_plant_classify brain_solution_iocr brain_realtime_product brain_nlp_lexer_custom brain_kgbody_analysis brain_body_attr brain_ocr_vat_invoice brain_advanced_general_classify brain_numbers brain_body_number vis-faceverify_FACE_auth_sessionkey smartapp_swanid_verify smartapp_opensource_openapi", "session_secret": "2ca66d464545c77a4767f709873be4" }
定义一个模型,文件名为 AccessTokenModel.cs
public class AccessTokenModel { public string refresh_token { get; set; } public string expires_in { get; set; }//: Access Token的有效期(秒为单位,一般为1个月) public string scope { get; set; } public string session_key { get; set; } public string access_token { get; set; }//: 要获取的Access Token public string session_secret { get; set; } }
打开 Program.cs 文件
public static void Main(string[] args) { FileStream fs = new FileStream(@"请修改成你的文件路径\json1.json", FileMode.Open); StreamReader fileStream = new StreamReader(fs); string str = ""; string line; while ((line = fileStream.ReadLine()) != null) { str += line; }
//上面的代码没有意义,只是将Json文件的内容加载到字符串中
JObject jObject = new JObject(); //新建 操作对象 AccessTokenModel a = JsonConvert.DeserializeObject<AccessTokenModel>(str); Console.WriteLine(a.access_token); //随意输出一个属性 Console.ReadKey(); }
重点方法
JsonConvert.DeserializeObject<要转化的模型类>("字符串对象");
之后可以很方便的把Json文件的内容存放到数据库中。
集合
把Json文件改成以下的样子
[{ "refresh_token": "25.ea2f85ebd48df85fe5400000.18640.282335-15533349", "expires_in": 2592010, "session_key": "9mzdWr3n8ncMeDgX8zjhkhlW8khb5cdZtPevPbPwQGBg==", "access_token": "24.ac0ca9fakhlkyhl552017858.282335-15533349", "scope": "audio_voice_assistant_get audio_tts_post public vis-ocr_ocr nlp_simnet nlp_wclassify_watermark brain_ocr_scope vis-classify_car brain_gif_antiporn brain_ocr_general brain_ocr_general_basic brain_ocr_generer vis-classify_animal brain_politician brain_unit_utterance brain_imgquality_general brain_nlp_simnet brain_nlp_depparser vis-classify_plant brain_solution brain_ocr_plate_number brain_nlp_wordembedding brain_nlp_dnnlm_cn_legacy brain_nlp_simnet_legacy brain_nlp_commain_animal_classify brain_plant_classify brain_solution_iocr brain_realtime_product brain_nlp_lexer_custom brain_kgbody_analysis brain_body_attr brain_ocr_vat_invoice brain_advanced_general_classify brain_numbers brain_body_number vis-faceverify_FACE_auth_sessionkey smartapp_swanid_verify smartapp_opensource_openapi", "session_secret": "2ca66d464545c77a4767f709873be4" }, { "refresh_token": "25.ea2f85ebd48df85fe5400000.18640.282335-15533349", "expires_in": 2592010, "session_key": "9mzdWr3n8ncMeDgX8zjhkhlW8khb5cdZtPevPbPwQGBg==", "access_token": "24.ac0ca9fakhlkyhl552017858.282335-15533349", "scope": "audio_voice_assistant_get audio_tts_post public vis-ocr_ocr nlp_simnet nlp_wclassify_watermark brain_ocr_scope vis-classify_car brain_gif_antiporn brain_ocr_general brain_ocr_general_basic brain_ocr_generer vis-classify_animal brain_politician brain_unit_utterance brain_imgquality_general brain_nlp_simnet brain_nlp_depparser vis-classify_plant brain_solution brain_ocr_plate_number brain_nlp_wordembedding brain_nlp_dnnlm_cn_legacy brain_nlp_simnet_legacy brain_nlp_commain_animal_classify brain_plant_classify brain_solution_iocr brain_realtime_product brain_nlp_lexer_custom brain_kgbody_analysis brain_body_attr brain_ocr_vat_invoice brain_advanced_general_classify brain_numbers brain_body_number vis-faceverify_FACE_auth_sessionkey smartapp_swanid_verify smartapp_opensource_openapi", "session_secret": "2ca66d464545c77a4767f709873be4" } ]
public static void Main(string[] args) { FileStream fs = new FileStream(@"请修改成你的文件路径\json1.json", FileMode.Open); StreamReader fileStream = new StreamReader(fs); string str = ""; string line; while ((line = fileStream.ReadLine()) != null) { str += line; } //上面的代码没有意义,只是将Json文件的内容加载到字符串中 JObject jObject = new JObject(); //新建 操作对象 List<AccessTokenModel> a = JsonConvert.DeserializeObject<List<AccessTokenModel>>(str); foreach (var i in a) { Console.WriteLine(i.access_token); } Console.ReadKey(); }
将Model转为Json
能够将模型对象转为 Json。
继续使用上面的 AccessTokenModel.cs 文件,
public static void Main(string[] args) { AccessTokenModel accessTokenModel = new AccessTokenModel(); accessTokenModel.access_token = "test1"; accessTokenModel.expires_in = "test2"; accessTokenModel.refresh_token = "test3"; accessTokenModel.scope = "test4"; accessTokenModel.session_key = "test5"; accessTokenModel.session_secret = "test6"; JObject jObject = new JObject(); string str = JsonConvert.SerializeObject(accessTokenModel); //转为字符串 Console.WriteLine(str); Console.ReadKey(); }
重点方法
JsonConvert.SerializeObject(a模型对象);
运行后可以看到控制台输出的是Json字符串了,你可以继续把他放到Json文件中,这里不再赘述。
将 LINQ 转为 JSON
下面这个是从官网直接copy的例子,Jarray 是其框架提供的一种类型。
在控制台运行后会发现输出的字符是已经格式化的。
public static void Main(string[] args) { JArray array = new JArray(); array.Add("Manual text"); array.Add(new DateTime(2000, 5, 23)); JObject o = new JObject(); o["MyArray"] = array; string json = o.ToString(); // { // "MyArray": [ // "Manual text", // "2000-05-23T00:00:00" // ] // } Console.WriteLine(json); Console.ReadKey();
Linq 操作
框架提供了对 Jobject 对象的Linq操作支持
using Newtonsoft.Json.Linq;
之后你可以像操作数组、集合或者Context一样方便。
命名空间、类型、方法大全
本来想翻译一下的,英语太差,算了。在常用的类型前面加粗吧
Class | Description | |||
---|---|---|---|---|
DefaultJsonNameTable |
The default JSON name table implementation.
|
|||
JsonArrayAttribute |
Instructs the JsonSerializer how to serialize the collection.
|
|||
JsonConstructorAttribute |
Instructs the JsonSerializer to use the specified constructor when deserializing that object.
|
|||
JsonContainerAttribute |
Instructs the JsonSerializer how to serialize the object.
|
|||
JsonConvert |
提供用于在.NET 和 Json之间互相转等操作的方法
|
|||
JsonConverter |
Converts an object to and from JSON.
|
|||
JsonConverter<T> |
Converts an object to and from JSON.
|
|||
JsonConverterAttribute |
Instructs the JsonSerializer to use the specified JsonConverter when serializing the member or class.
|
|||
JsonConverterCollection |
Represents a collection of JsonConverter.
|
|||
JsonDictionaryAttribute |
Instructs the JsonSerializer how to serialize the collection.
|
|||
JsonException |
JSON序列化或反序列化过程中发生错误时引发的异常类型
|
|||
JsonExtensionDataAttribute |
Instructs the JsonSerializer to deserialize properties with no matching class member into the specified collection and write values during serialization.
|
|||
JsonIgnoreAttribute |
Instructs the JsonSerializer not to serialize the public field or public read/write property value.
|
|||
JsonNameTable |
Base class for a table of atomized string objects.
|
|||
JsonObjectAttribute |
Instructs the JsonSerializer how to serialize the object.
|
|||
JsonPropertyAttribute |
Instructs the JsonSerializer to always serialize the member with the specified name.
|
|||
JsonReader |
Represents a reader that provides fast, non-cached, forward-only access to serialized JSON data.
|
|||
JsonReaderException |
The exception thrown when an error occurs while reading JSON text.
|
|||
JsonRequiredAttribute |
Instructs the JsonSerializer to always serialize the member, and to require that the member has a value.
|
|||
JsonSerializationException |
The exception thrown when an error occurs during JSON serialization or deserialization.
|
|||
JsonSerializer |
Serializes and deserializes objects into and from the JSON format. The JsonSerializer enables you to control how objects are encoded into JSON.
|
|||
JsonSerializerSettings |
Specifies the settings on a JsonSerializer object.
|
|||
JsonTextReader |
Represents a reader that provides fast, non-cached, forward-only access to JSON text data.
|
|||
JsonTextWriter |
Represents a writer that provides a fast, non-cached, forward-only way of generating JSON data.
|
|||
JsonValidatingReader | Obsolete.
Represents a reader that provides JsonSchema validation.
|
|||
JsonWriter |
Represents a writer that provides a fast, non-cached, forward-only way of generating JSON data.
|
|||
JsonWriterException |
The exception thrown when an error occurs while writing JSON text.
|
Interface | Description | |
---|---|---|
IArrayPool<T> |
Provides an interface for using pooled arrays.
|
|
IJsonLineInfo |
Provides an interface to enable a class to return line and position information.
|
Enumeration | Description | |
---|---|---|
ConstructorHandling |
Specifies how constructors are used when initializing objects during deserialization by the JsonSerializer.
|
|
DateFormatHandling |
Specifies how dates are formatted when writing JSON text.
|
|
DateParseHandling |
Specifies how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON text.
|
|
DateTimeZoneHandling |
Specifies how to treat the time value when converting between string and DateTime.
|
|
DefaultValueHandling |
Specifies default value handling options for the JsonSerializer.
|
|
FloatFormatHandling |
Specifies float format handling options when writing special floating point numbers, e.g. NaN,PositiveInfinity and NegativeInfinity with JsonWriter.
|
|
FloatParseHandling |
Specifies how floating point numbers, e.g. 1.0 and 9.9, are parsed when reading JSON text.
|
|
Formatting |
Specifies formatting options for the JsonTextWriter.
|
|
JsonReader.State |
Specifies the state of the reader.
|
|
JsonToken |
Specifies the type of JSON token.
|
|
MemberSerialization |
Specifies the member serialization options for the JsonSerializer.
|
|
MetadataPropertyHandling |
Specifies metadata property handling options for the JsonSerializer.
|
|
MissingMemberHandling |
Specifies missing member handling options for the JsonSerializer.
|
|
NullValueHandling |
Specifies null value handling options for the JsonSerializer.
|
|
ObjectCreationHandling |
Specifies how object creation is handled by the JsonSerializer.
|
|
PreserveReferencesHandling |
Specifies reference handling options for the JsonSerializer. Note that references cannot be preserved when a value is set via a non-default constructor such as types that implement ISerializable.
|
|
ReferenceLoopHandling |
Specifies reference loop handling options for the JsonSerializer.
|
|
Required |
Indicating whether a property is required.
|
|
StringEscapeHandling |
Specifies how strings are escaped when writing JSON text.
|
|
TypeNameAssemblyFormatHandling |
Indicates the method that will be used during deserialization for locating and loading assemblies.
|
|
TypeNameHandling |
Specifies type name handling options for the JsonSerializer.
|
|
WriteState |
Specifies the state of the JsonWriter.
|
图片
百度AI 识别文字,返回Json结果, 名字随意.格式建议为 json,如果使用记事本保存,注意编码格式是 utf-8,因为c# string默认为utf8,不然会乱码。
{ "log_id": 3413661945235258919, "direction": 0, "words_result_num": 2, "words_result": [ { "vertexes_location": [ { "y": 81, "x": 51 }, { "y": 81, "x": 151 }, { "y": 103, "x": 151 }, { "y": 103, "x": 51 } ], "probability": { "variance": 0.0, "average": 0.999861, "min": 0.999627 }, "chars": [ { "char": "今", "location": { "width": 17, "top": 83, "left": 60, "height": 20 } }, { "char": "天", "location": { "width": 17, "top": 83, "left": 78, "height": 20 } }, { "char": "除", "location": { "width": 12, "top": 83, "left": 103, "height": 20 } }, { "char": "了", "location": { "width": 16, "top": 83, "left": 116, "height": 20 } }, { "char": "皮", "location": { "width": 13, "top": 83, "left": 140, "height": 20 } } ], "min_finegrained_vertexes_location": [ { "y": 81, "x": 51 }, { "y": 81, "x": 151 }, { "y": 103, "x": 151 }, { "y": 103, "x": 51 } ], "finegrained_vertexes_location": [ { "y": 81, "x": 51 }, { "y": 81, "x": 71 }, { "y": 81, "x": 90 }, { "y": 81, "x": 110 }, { "y": 81, "x": 129 }, { "y": 81, "x": 149 }, { "y": 81, "x": 151 }, { "y": 91, "x": 151 }, { "y": 100, "x": 151 }, { "y": 103, "x": 151 }, { "y": 103, "x": 132 }, { "y": 103, "x": 112 }, { "y": 103, "x": 93 }, { "y": 103, "x": 73 }, { "y": 103, "x": 54 }, { "y": 103, "x": 51 }, { "y": 93, "x": 51 }, { "y": 84, "x": 51 } ], "location": { "width": 102, "top": 81, "left": 51, "height": 24 }, "words": "今天除了皮" }, { "vertexes_location": [ { "y": 109, "x": 52 }, { "y": 109, "x": 152 }, { "y": 130, "x": 152 }, { "y": 130, "x": 52 } ], "probability": { "variance": 8E-05, "average": 0.9907, "min": 0.973259 }, "chars": [ { "char": "又", "location": { "width": 16, "top": 111, "left": 61, "height": 20 } }, { "char": "啥", "location": { "width": 12, "top": 111, "left": 85, "height": 20 } }, { "char": "也", "location": { "width": 16, "top": 111, "left": 98, "height": 20 } }, { "char": "没", "location": { "width": 15, "top": 111, "left": 123, "height": 20 } }, { "char": "干", "location": { "width": 13, "top": 111, "left": 141, "height": 20 } } ], "min_finegrained_vertexes_location": [ { "y": 109, "x": 52 }, { "y": 109, "x": 152 }, { "y": 130, "x": 152 }, { "y": 130, "x": 52 } ], "finegrained_vertexes_location": [ { "y": 109, "x": 52 }, { "y": 109, "x": 71 }, { "y": 109, "x": 91 }, { "y": 109, "x": 110 }, { "y": 109, "x": 129 }, { "y": 109, "x": 149 }, { "y": 109, "x": 152 }, { "y": 119, "x": 152 }, { "y": 129, "x": 152 }, { "y": 130, "x": 152 }, { "y": 130, "x": 133 }, { "y": 130, "x": 113 }, { "y": 130, "x": 94 }, { "y": 130, "x": 74 }, { "y": 130, "x": 55 }, { "y": 130, "x": 52 }, { "y": 121, "x": 52 }, { "y": 111, "x": 52 } ], "location": { "width": 102, "top": 109, "left": 52, "height": 22 }, "words": "又啥也没干" } ], "language": -1 }
对应的模型 ,将 cs 文件,名字 GeneralModel.cs
/// <summary> /// 通用文字识别(含位置版)返回结果 /// </summary> public class GeneralModel { /// <summary> /// 必选 /// 唯一的log id,用于问题定位 /// </summary> public long log_id { get; set; } /// <summary> /// 图像方向,当detect_direction=true时存在。 /// 非必选 ///- -1:未定义, ///- 0:正向, ///- 1: 逆时针90度, ///- 2:逆时针180度, ///- 3:逆时针270度 /// </summary> public int direction { get; set; } /// <summary> /// 必选 /// 识别结果数,表示words_result的元素个数 /// </summary> public int words_result_num { get; set; } /// <summary> /// 检测语言 默认值会返回 -1 /// </summary> public string language { get; set; } /// <summary> /// 定位和识别文字结果数组 /// </summary> public List<Words_result> words_result { get; set; } public class Words_result { /// <summary> /// 图片中文字段四个顶点位置(矩形范围) /// </summary> public List<XY> vertexes_Location { get; set; } /// <summary> /// 可选 /// 行置信度信息;如果输入参数 probability = true 则输出 /// </summary> public Probability probability { get; set; } /// <summary> /// 每个字 /// </summary> public List<Chars> chars { get; set; } /// <summary> /// 最小细粒度顶点坐标 /// </summary> public List<XY> min_finegrained_vertexes_location { get; set; } /// <summary> /// 细粒度顶点坐标,多边形 /// </summary> public List<XY> finegrained_vertexes_location { get; set; } /// <summary> /// 文字在图片中的相对位置 /// </summary> public Location location { get; set; } /// <summary> /// 识别出的文字 /// </summary> public string words { get; set; } /// <summary> /// 坐标 /// </summary> public class XY { public int x { get; set; } public int y { get; set; } } /// <summary> /// 行置信度 /// </summary> public class Probability { /// <summary> /// 行置信度平均值方差 /// </summary> public double variance { get; set; } /// <summary> /// 行置信度平均值 /// </summary> public double average { get; set; } /// <summary> /// 行置信度最小值 /// </summary> public double min { get; set; } } /// <summary> /// 单个文字 /// </summary> public class Chars { /// <summary> /// 识别的单个文字 /// </summary> public char chaR { get; set; } /// <summary> /// 该文字范围(矩形) /// </summary> public Location location { get; set; } } } public class Location { public int left { get; set; } public int top { get; set; } public int width { get; set; } public int height { get; set; } } } }
可用控制台进行检验
static void Main(string[] args) { StreamReader streamReader = new StreamReader(System.IO.File.OpenRead(@"json文件位置")); string str = ""; string jsonstr; while ((jsonstr = streamReader.ReadLine()) != null) { str += jsonstr; } GeneralModel generalModel = JsonConvert.DeserializeObject<GeneralModel>(str); Console.WriteLine("图片id:" + generalModel.log_id); Console.WriteLine("图像方向:" + generalModel.direction); Console.WriteLine("检测语言为:" + generalModel.language); Console.WriteLine("有几个结果:" + generalModel.words_result_num); foreach (var item in generalModel.words_result) { Console.WriteLine("识别结果:" + Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(item.words))); foreach (var itemi in item.vertexes_Location) { Console.WriteLine("{x:" + itemi.x + ";y:" + itemi.y + "}"); } Console.WriteLine("Probability:可信度:" + "行置信度平均值" + item.probability.average + ";行置信度平均值方差:" + item.probability.variance + ";行置信度平均值最小值:" + item.probability.min); foreach (var itemi in item.chars) { Console.WriteLine(itemi.chaR); Console.WriteLine("位置: left:" + itemi.location.left + "; height: " + itemi.location.height + "top: " + itemi.location.top + "; width: " + itemi.location.width); } } Console.ReadKey();
C# 算法题系列(二) 各位相加、整数反转、回文数、罗马数字转整数
各位相加
给定一个非负整数 num
,反复将各个位上的数字相加,直到结果为一位数。
示例:
输入: 38 输出: 2 解释: 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2。 由于 2 是一位数,所以返回 2。
进阶:
你可以不使用循环或者递归,且在 O(1) 时间复杂度内解决这个问题吗?
题目地址 https://leetcode-cn.com/problems/add-digits/
代码模板
public class Solution { public int AddDigits(int num) { } }
测试数据
输入 1 输出 1 输入 10 输出 1 输入 38 输出 2 输入 199 输出 1 输入 8888 输出 5
笔者的方法:
使用了while循环,除一次计算一次,原始数和各位数和同时变化。时间在70ms内。
public static int Csum(int num) { if (num < 10) //小于10的数直接返回 return num; int shi = 0; //记录个位数相加 while (num > 0) { if (num >= 10) { shi += num % 10; num = num / 10; } else if (num < 10) { shi += num; num = num / 10; } if (shi >= 10) shi = shi % 10 + shi / 10; //超过10的个位数重新变化 } return shi; }
方法二 弃九验算法
同样在 60-70ms
public class Solution { public int AddDigits(int num) { if(num==0) return 0; if(num%9==0) return 9; return num%9; } }
整数反转
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
示例 1:
输入: 123 输出: 321
示例 2:
输入: -123 输出: -321
示例 3:
输入: 120 输出: 21
注意:
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0
题目地址 https://leetcode-cn.com/problems/reverse-integer/
代码模板
1
2
3
4
5
|
public class Solution { public int Reverse( int x) { } } |
笔者方法 68ms左右
public class Solution { public int Reverse(int x) { int num = 0; while (x != 0) { int i = x % 10; x = x / 10; //C# int32 范围 [-2147483647~2147483647] if (num > int.MaxValue / 10 ) return 0; if (num < int.MinValue / 10) return 0; num = num * 10 + i; } return num; } }
回文数
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
题目地址:https://leetcode-cn.com/problems/palindrome-number
示例 1:
输入: 121 输出: true
示例 2:
输入: -121 输出: false 解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:
输入: 10 输出: false 解释: 从右向左读, 为 01 。因此它不是一个回文数。
进阶:
你能不将整数转为字符串来解决这个问题吗?
代码模板
public class Solution { public bool IsPalindrome(int x) { } }
笔者的代码
运行时间在120ms左右,笔者的思路是:如果一个数字的反序还是等于这个数,那么这个数就是回文数。
以下代码无法解决反序后可能溢出,可以利用上一题的代码进行溢出检查。
当然,一个int类型的数,如果是回文,那么他的反序肯定不会溢出,反之其反序发生溢出则肯定不是回文数。
public class Solution { public bool IsPalindrome(int x) { if (x < 0) return false; int xx = x; int num = 0; //x的反序 while (xx != 0) //求反序 { int i = xx % 10; xx = xx / 10; num = num * 10 + i; } if (x == num) //如果x的反序num==x,那么这个数字是回文数 return true; else return false; } }
加try-catch,耗时增加 10~20ms
try { while (xx != 0) { int i = xx % 10; xx = xx / 10; num = num * 10 + i; } } catch { return false; }
官方这道题给出了示例代码,耗时120ms左右,思路是只反序一半,反序后的原始数、反序一半的数进行比较,也就不用检查溢出。
public class Solution { public bool IsPalindrome(int x) { // 特殊情况: // 如上所述,当 x < 0 时,x 不是回文数。 // 同样地,如果数字的最后一位是 0,为了使该数字为回文, // 则其第一位数字也应该是 0 // 只有 0 满足这一属性 if(x < 0 || (x % 10 == 0 && x != 0)) { return false; } int revertedNumber = 0; while(x > revertedNumber) { revertedNumber = revertedNumber * 10 + x % 10; x /= 10; } // 当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。 // 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revertedNumber = 123, // 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。 return x == revertedNumber || x == revertedNumber/10; } }
别人用字符串方式进行判断(虽然题目说不能用string),耗时150-180ms,不太稳定
public class Solution { public bool IsPalindrome(int x) { string str = x.ToString(); for (int i = 0; i < str.Length / 2; ++i) { if (str[i] != str[str.Length - 1 - i]) { return false; } } return true; } }
罗马数字转整数
罗马数字包含以下七种字符: I
, V
, X
, L
,C
,D
和 M
。
题目地址 https://leetcode-cn.com/problems/roman-to-integer/submissions/
字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000
例如, 罗马数字 2 写做 II
,即为两个并列的 1。12 写做 XII
,即为 X
+ II
。 27 写做 XXVII
, 即为 XX
+ V
+ II
。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII
,而是 IV
。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX
。这个特殊的规则只适用于以下六种情况:
I
可以放在V
(5) 和X
(10) 的左边,来表示 4 和 9。X
可以放在L
(50) 和C
(100) 的左边,来表示 40 和 90。C
可以放在D
(500) 和M
(1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。
示例 1:
输入: "III" 输出: 3
示例 2:
输入: "IV" 输出: 4
示例 3:
输入: "IX" 输出: 9
示例 4:
输入: "LVIII" 输出: 58 解释: L = 50, V= 5, III = 3.
示例 5:
输入: "MCMXCIV" 输出: 1994 解释: M = 1000, CM = 900, XC = 90, IV = 4.
笔者的方法:
时间200ms左右,
思路是
- 把所有的情况放到哈希表中
- 每次取一个位
- 把 i 和 i+1 放一起,试试有没有区配的,有的话把 i 和 i+1 放一起
- 没有的话,就是 只是计 i
public class Solution { public int RomanToInt(string s) { char[] c = s.ToCharArray(); //将其转为字符数组 int sum = 0; //值 Hashtable hashtable = new Hashtable(); //7个基本单位 hashtable.Add("I", 1); hashtable.Add("V", 5); hashtable.Add("X", 10); hashtable.Add("L", 50); hashtable.Add("C", 100); hashtable.Add("D", 500); hashtable.Add("M", 1000); //加上6种情况 hashtable.Add("IV", 4); hashtable.Add("IX", 9); hashtable.Add("XL", 40); hashtable.Add("XC", 90); hashtable.Add("CD", 400); hashtable.Add("CM", 900);
/*
* 六种情况
IV 4 IX 9
XL 40 XC 90
CD 400 CM 9000
*/
for (int i = 0; i < c.Length; i++) { if (i + 1 < c.Length && hashtable.ContainsKey(c[i].ToString() + c[i + 1].ToString())) //如果发现两位一起能区配的话 { sum += int.Parse(hashtable[c[i].ToString() + c[i + 1].ToString()].ToString()); //获取值,HashTable的类型都是Object! i++; //跳两位 } else { sum += int.Parse(hashtable[c[i].ToString()].ToString()); } } return sum; } }
换成字典
public class Solution { public int RomanToInt(string s) { char[] c = s.ToCharArray(); //将其转为字符数组 int sum = 0; //值 Dictionary<string, int> dictionary = new Dictionary<string, int>(); //7个基本单位 dictionary.Add("I", 1); dictionary.Add("V", 5); dictionary.Add("X", 10); dictionary.Add("L", 50); dictionary.Add("C", 100); dictionary.Add("D", 500); dictionary.Add("M", 1000); //加上6种情况 dictionary.Add("IV", 4); dictionary.Add("IX", 9); dictionary.Add("XL", 40); dictionary.Add("XC", 90); dictionary.Add("CD", 400); dictionary.Add("CM", 900);
/*
* 六种情况
IV 4 IX 9
XL 40 XC 90
CD 400 CM 9000
*/
for (int i = 0; i < c.Length; i++) { if (i + 1 < c.Length && dictionary.ContainsKey(c[i].ToString() + c[i + 1])) //如果发现两位一起能区配的话 { sum += dictionary[c[i].ToString() + c[i + 1].ToString()]; //获取值,HashTable的类型都是Object! i++; //跳两位 } else { sum += dictionary[c[i].ToString()]; } } return sum; } }
以上两个例子都会进行较多的装箱拆箱,下面主要使用if-else,switch,空间花销较大,但是如果测试例子较多,进行大量计算,时间会相对少一点。
public class Solution { public int RomanToInt(string s) { int sum = 0; //值 for (int i = 0; i < s.Length; i++) { if (i + 1 < s.Length) //如果后面还有别的字符 { if (s[i] == 'I') { int a = 0; switch (s[i + 1]) //"i%" { case 'V': a = 4; i++; break; case 'X': a = 9; i++; break; default: a = 1; break; } sum += a; } else if (s[i] == 'X') { int a = 0; switch (s[i + 1]) //"X%" { case 'L': a = 40; i++; break; case 'C': a = 90; i++; break; default: a = 10; break; } sum += a; } else if (s[i] == 'C') { int a = 0; switch (s[i + 1]) //"X%" { case 'D': a = 400; i++; break; case 'M': a = 900; i++; break; default: a = 100; break; } sum += a; } else { int a = 0; switch (s[i]) {case 'V': a = 5; break;case 'L': a = 50; break;case 'D': a = 500; break; case 'M': a = 1000; break; } sum += a; } } else { int a = 0; switch (s[i]) { case 'I': a = 1; break; case 'V': a = 5; break; case 'X': a = 10; break; case 'L': a = 50; break; case 'C': a = 100; break; case 'D': a = 500; break; case 'M': a = 1000; break; } sum += a; } } return sum; } }
C# 算法题系列(一) 两数之和、无重复字符的最长子串
题目一
原题链接 https://leetcode-cn.com/problems/two-sum/
给定一个整数数组 nums
和一个目标值 target
,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
提示:不能自身相加。
测试用例
[2,7,11,15] 9
[0,1]
格式模板
public class Solution { public int[] TwoSum(int[] nums, int target) { /* 代码 */ } }
笔者的代码,仅供参考
使用暴力方法,运行时间 700ms-1100ms
public class Solution { public int[] TwoSum(int[] nums, int target) { int [] a = new int[2]; for (int i = 0; i < nums.Length - 1; i++) { for (int j = i + 1; j < nums.Length; j++) { if (nums[i] + nums[j] == target) { a[0] = i; a[1] = j; } } } return a; } }
运行时间 400ms-600ms
由于使用的是哈希表,所以缺点是键不能相同。
public class Solution { public int[] TwoSum(int[] nums, int target) { int[] a = new int[2]; System.Collections.Hashtable hashtable = new System.Collections.Hashtable(); for(int i = 0; i < nums.Length; i++) { hashtable.Add(nums[i], i); } for(int i = 0; i < nums.Length; i++) { int complement = target - nums[i]; if (hashtable.ContainsKey(complement) && int.Parse(hashtable[complement].ToString())!=i) { a[0] = i; a[1] = int.Parse(hashtable[complement].ToString()); } } return a; } }
还是哈希表,缺点是哈希表存储的类型是object,获取值时需要进行转换。
public int[] TwoSum(int[] nums, int target) { int[] a = new int[2]; System.Collections.Hashtable h = new System.Collections.Hashtable(); for (int i = 0; i < nums.Length; i++) { int c = target - nums[i]; if (h.ContainsKey(c)) { a[0] = int.Parse(h[c].ToString()) <= nums[i] ? int.Parse(h[c].ToString()) : i; a[1] = int.Parse(h[c].ToString()) > nums[i] ? int.Parse(h[c].ToString()) : i; } else if (!h.ContainsKey(nums[i])) { h.Add(nums[i], i); } } return a; }
抄一下别人的
public class Solution { public int[] TwoSum(int[] nums, int target) { int[] res = {0, 0}; int len = nums.Length; Dictionary<int, int> dict = new Dictionary<int, int>(); for (int i = 0; i < len; i++) { int query = target - nums[i]; if (dict.ContainsKey(query)) { int min = (i <= dict[query]) ? i : dict[query]; int max = (i <= dict[query]) ? dict[query] : i; return new int[] { min, max }; } else if (!dict.ContainsKey(nums[i])) { dict.Add(nums[i], i); } } return res; } } --------------------- 作者:Bruce-Yeung 来源:CSDN 原文:https://blog.csdn.net/lzuacm/article/details/80551669 版权声明:本文为博主原创文章,转载请附上博文链接!
题目二
原题地址 https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
要注意字符串为空、变量为null、字符串长度 Length = 1 等情况。
测试实例
输入 " " "au" "abcabcbb" "bbbbb" "pwwkew" "aab"
预期结果分别是 1,2,3,1,3,2
代码格式模板
1
2
3
4
5
|
public class Solution { public int LengthOfLongestSubstring( string s) { } } |
笔者的代码仅供参考
使用最笨的方式,200ms左右
public class Solution { public int LengthOfLongestSubstring(string s) { if (s == null || s == "") return 0; char[] a = s.ToCharArray(); //字符串转为字符数组 int start = 0; //区间开始位置 int stop = 0; //区间结束位置 int newMax = 1; //当前区间数 int max = 1; //区间最大个数 for (stop = 1; stop < a.Length; stop++) //每次向后移动一位 { bool b = false; //是否存在重复 for (int i = start; i < stop; i++) //检查当前元素在区间是否有相同值 { if (a[stop] == a[i]) //如果stop+1位在区间找到相同的字符 { char ls = a[stop]; if (newMax > max) max = newMax; start = i + 1; //区间开始位置重置 newMax = stop - start + 1; b = true; break; } } if (b == false) newMax += 1; } if (newMax > max) max = newMax; return max; } }
完整测试代码(控制台)
using System; namespace ConsoleApp1 { public class Testa { public int LengthOfLongestSubstring(string s) { if (s == null || s == "") return 0; char[] a = s.ToCharArray(); //字符串转为字符数组 int start = 0; //区间开始位置 int stop = 0; //区间结束位置 int newMax = 1; //当前区间数 int max = 1; //区间最大个数 for (stop = 1; stop < a.Length; stop++) //每次向后移动一位 { bool b = false; //是否存在重复 for (int i = start; i < stop; i++) //检查当前元素在区间是否有相同值 { if (a[stop] == a[i]) //如果stop+1位在区间找到相同的字符 { char ls = a[stop]; if (newMax > max) max = newMax; start = i + 1; //区间开始位置重置 newMax = stop - start + 1; //重新设置区间数 b = true; break; } } if (b == false) ////没有重新设置区间数时加1 newMax += 1; } if (newMax > max) max = newMax; return max; } } class Program { static void Main(string[] args) { Testa t1 = new Testa(); //正确结果 Console.WriteLine(t1.LengthOfLongestSubstring(" ")); //1 Console.WriteLine(t1.LengthOfLongestSubstring("au")); //2 Console.WriteLine(t1.LengthOfLongestSubstring("abcabcbb")); //3 Console.WriteLine(t1.LengthOfLongestSubstring("bbbbb")); //1 Console.WriteLine(t1.LengthOfLongestSubstring("pwwkew")); //3 Console.WriteLine(t1.LengthOfLongestSubstring("aab")); //2 Console.ReadKey(); } } }
使用哈希集合,速度更快,100ms-150ms
public int LengthOfLongestSubstring(string s) { int n = s.Length; HashSet<char> set = new HashSet<char>(); //集合 int ans = 0, start = 0, stop = 0; //ans为字符串长度,starp区间起点,stop区间终点 while (start < n && stop < n) { // try to extend the range [i, j] if (!set.Contains(s[stop])) { set.Add(s[stop++]); ans = Math.Max(ans, stop - start); //或者ans = ans > (stop - start) ? ans : (stop - start) } else { set.Remove(s[start++]); } } return ans; }
完整控制台测试代码
using System; using System.Collections.Generic; using System.Linq; namespace ConsoleApp2 { public class Solution { public int LengthOfLongestSubstring(string s) { int n = s.Length; HashSet<char> set = new HashSet<char>(); //集合 int ans = 0, start = 0, stop = 0; //ans为字符串长度,starp区间起点,stop区间终点 while (start < n && stop < n) { // try to extend the range [i, j] if (!set.Contains(s[stop])) { set.Add(s[stop++]); ans = Math.Max(ans, stop - start); //或者ans = ans > (stop - start) ? ans : (stop - start) } else { set.Remove(s[start++]); } } return ans; } } class Program { static void Main(string[] args) { Solution t1 = new Solution(); //正确结果 Console.WriteLine(t1.LengthOfLongestSubstring(" ")); //1 Console.WriteLine(t1.LengthOfLongestSubstring("au")); //2 Console.WriteLine(t1.LengthOfLongestSubstring("abcabcbb")); //3 Console.WriteLine(t1.LengthOfLongestSubstring("bbbbb")); //1 Console.WriteLine(t1.LengthOfLongestSubstring("pwwkew")); //3 Console.WriteLine(t1.LengthOfLongestSubstring("aab")); //2 Console.ReadKey(); } } }
DateTime Tips
DateTime Tips(System.Runtime Version=4.2.1.0)
抛砖引玉,如有错误或是更好的方式还望不吝赐教
1. 根据某个DateTime对象取其当天的起始时间
例如:
输入是 2019-01-14T01:27:59.260Z
输出为 2019-01-14T00:00:00.000Z
var result = sourceDate.Date; //sourceDate为DateTime类型
另,如果是当日时间可以直接使用 Date.Today
2. AM与PM
12:00AM是午夜
12:00PM是正午
14日 12:00AM 这个时间使用 addHours(-1)得到的是13日11:00PM
14日 12:00AM 这个时间使用 addHours(1) 得到的是14日1:00AM
3. 每周的开始时间
有时候我们需要自定义每周从哪一天开始(例如:国外周六,国内周一。某x石传说周四更新乱斗等等)
先来看看.Net Core 自带的DayOfWeek枚举
// // 摘要: // Specifies the day of the week. public enum DayOfWeek { Sunday = 0, Monday = 1, Tuesday = 2, Wednesday = 3, Thursday = 4, Friday = 5, Saturday = 6 }
// 使用DayOfWeek中的值,这里配置每周从周几开始,如周四weekBeginDay=4 var weekBeginDay = 1; // 确定给定日期在DayOfWeek的order,此处使用系统当日日期 var order = (int)DateTime.Today.DayOfWeek; // 计算修正日期,如果给定日期(以系统今日时间Today为例)order大于等于一周开始时间的order, 则修正值为给定日期order与一周开始时间的order的差。 // 如周一为每周开始时间,则周四时修正值为4-1=3. // 如果给定日期order小于一周开始时间的order,则需额外加7 correctionCount = todayOrder < weekBeginDay ? todayOrder - weekBeginDay + 7 : todayOrder - weekBeginDay // 所以给定日期所在周期的开始结束时间分别为 var weekBegin = DateTime.Today.AddDays(0 - correctionCount); var weekEnd = DateTime.Today.AddDays(7 - correctionCount);
4.园子里Pickuper的C#语言之“string格式的日期时间字符串转为DateTime类型”的方法讲的很好,只是最后部分的格式有点乱了,整理如下
// 日期格式:yyyyMMdd HH:mm:ss(注意此字符串的字母大小写很严格)yyyy代表年份MM代表月份dd代表天HH代表小时(24小时制)mm代表分钟ss代表秒 DateTime.Now.ToShortTimeString(); DateTime dt = DateTime.Now; dt.ToString();//2005-11-5 13:21:25 dt.ToFileTime().ToString();//127756416859912816 dt.ToFileTimeUtc().ToString();//127756704859912816 dt.ToLocalTime().ToString();//2005-11-5 21:21:25 dt.ToLongDateString().ToString();//2005年11月5日 dt.ToLongTimeString().ToString();//13:21:25 dt.ToOADate().ToString();//38661.5565508218 dt.ToShortDateString().ToString();//2005-11-5 dt.ToShortTimeString().ToString();//13:21 dt.ToUniversalTime().ToString();//2005-11-5 5:21:25 dt.Year.ToString();//2005 dt.Date.ToString();//2005-11-5 0:00:00 dt.DayOfWeek.ToString();//Saturday dt.DayOfYear.ToString();//309 dt.Hour.ToString();//13 dt.Millisecond.ToString();//441 dt.Minute.ToString();//30 dt.Month.ToString();//11 dt.Second.ToString();//28 dt.Ticks.ToString();//632667942284412864 dt.TimeOfDay.ToString();//13:30:28.4412864 dt.ToString();//2005-11-5 13:47:04 dt.AddYears(1).ToString();//2006-11-5 13:47:04 dt.AddDays(1.1).ToString();//2005-11-6 16:11:04 dt.AddHours(1.1).ToString();//2005-11-5 14:53:04 多了1小时6分钟 此处是支持Double类型的 dt.AddMilliseconds(1.1).ToString();//2005-11-5 13:47:04 dt.AddMonths(1).ToString();//2005-12-5 13:47:04 dt.AddSeconds(1.1).ToString();//2005-11-5 13:47:05 ,此处直接使用Tostring被精度限制了 dt.AddMinutes(1.1).ToString();//2005-11-5 13:48:10 dt.AddTicks(1000).ToString();//2005-11-5 13:47:04 dt.CompareTo(dt).ToString();//0 dt.Add(?).ToString();//问号为一个时间段 dt.Equals("2005-11-6 16:11:04").ToString();//False dt.Equals(dt).ToString();//True dt.GetHashCode().ToString();//1474088234 dt.GetType().ToString();//System.DateTime dt.GetTypeCode().ToString();//DateTime dt.GetDateTimeFormats('s')[0].ToString();//2005-11-05T14:06:25 dt.GetDateTimeFormats('t')[0].ToString();//14:06 dt.GetDateTimeFormats('y')[0].ToString();//2005年11月 dt.GetDateTimeFormats('D')[0].ToString();//2005年11月5日 dt.GetDateTimeFormats('D')[1].ToString();//2005 11 05 dt.GetDateTimeFormats('D')[2].ToString();//星期六 2005 11 05 dt.GetDateTimeFormats('D')[3].ToString();//星期六 2005年11月5日 dt.GetDateTimeFormats('M')[0].ToString();//11月5日 dt.GetDateTimeFormats('f')[0].ToString();//2005年11月5日 14:06 dt.GetDateTimeFormats('g')[0].ToString();//2005-11-5 14:06 dt.GetDateTimeFormats('r')[0].ToString();//Sat, 05 Nov 2005 14:06:25 GMT string.Format("{0:d}",dt);//2005-11-5 string.Format("{0}",dt);//2005年11月5日 string.Format("{0:f}",dt);//2005年11月5日 14:23 string.Format("{0:F}",dt);//2005年11月5日 14:23:23 string.Format("{0:g}",dt);//2005-11-5 14:23 string.Format("{0:G}",dt);//2005-11-5 14:23:23 string.Format("{0:M}",dt);//11月5日 string.Format("{0:R}",dt);//Sat, 05 Nov 2005 14:23:23 GMT string.Format("{0:s}",dt);//2005-11-05T14:23:23 string.Format("{0:t}",dt);//14:23 string.Format("{0:T}",dt);//14:23:23 string.Format("{0:u}",dt);//2005-11-05 14:23:23Z string.Format("{0:U}",dt);//2005年11月5日 6:23:23 string.Format("{0:Y}",dt);//2005年11月 string.Format("{0}",dt);//2005-11-5 14:23:23 string.Format("{0:yyyyMMddHHmmssffff}",dt); // 计算2个日期之间的天数差 ----------------------------------------------- DateTime dt1 = Convert.DateTime("2007-8-1"); DateTime dt2 = Convert.DateTime("2007-8-15"); TimeSpan span = dt2.Subtract(dt1); int dayDiff = span.Days + 1; // 计算某年某月的天数 ----------------------------------------------- int days = DateTime.DaysInMonth(2007, 8); //days = 31; // 给日期增加一天、减少一天 ----------------------------------------------- DateTime dt =DateTime.Now; dt.AddDays(1);//增加一天 dt.AddDays(-1);//减少一天 其它年份方法类似... // Oracle SQL里转换日期函数 ----------------------------------------------- to_date("2007-6-6",'YYYY-MM-DD"); to_date("2007/6/6",'yyyy/mm/dd");
另:
dt.AddHours(1.1).ToString();//2005-11-5 14:53:04 多了1小时6分钟 此处是支持Double类型的
并非所有Add~系列的方法均支持Double类型的,
具体为:
public DateTime Add(TimeSpan value); public DateTime AddDays(double value); public DateTime AddHours(double value); public DateTime AddMilliseconds(double value); public DateTime AddMinutes(double value); public DateTime AddMonths(int months); public DateTime AddSeconds(double value); public DateTime AddTicks(long value); public DateTime AddYears(int value);
以上。
c#发送邮件,可发送多个附件
1:创建SendMail类
2:调用方法
SendMail send = new SendMail("123456@qq.com", "123456@163.com", "邮件内容测试", "邮件标题测试", "mail20181224");
send.Attachments(@"D:\\工作\\abc.txt");
send.Attachments(@"D:\\工作\\123.txt");
send.Send();
---------------------------------------------------------------------------------------------------下面是类-------------------------------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net.Mail;
using System.Net.Mime;
/// <summary>
/// SendMail 的摘要说明
/// </summary>
public class SendMail
{
private MailMessage mailMessage;
private SmtpClient smtpClient;
private string password;//发件人密码
/// <summary>
/// 处审核后类的实例
/// </summary>
/// <param name="To">收件人地址</param>
/// <param name="From">发件人地址</param>
/// <param name="Body">邮件正文</param>
/// <param name="Title">邮件的主题</param>
/// <param name="Password">发件人密码</param>
public SendMail(string To, string From, string Body, string Title, string Password)
{
mailMessage = new MailMessage();
mailMessage.To.Add(To);
mailMessage.From = new System.Net.Mail.MailAddress(From);
mailMessage.Subject = Title;
mailMessage.Body = Body;
mailMessage.IsBodyHtml = true;
mailMessage.BodyEncoding = System.Text.Encoding.UTF8;
mailMessage.Priority = System.Net.Mail.MailPriority.Normal;
this.password = Password;
}
/// <summary>
/// 添加附件
/// </summary>
public void Attachments(string Path)
{
string[] path = Path.Split(',');
Attachment data;
ContentDisposition disposition;
for (int i = 0; i < path.Length; i++)
{
data = new Attachment(path[i], MediaTypeNames.Application.Octet);//实例化附件
disposition = data.ContentDisposition;
disposition.CreationDate = System.IO.File.GetCreationTime(path[i]);//获取附件的创建日期
disposition.ModificationDate = System.IO.File.GetLastWriteTime(path[i]);//获取附件的修改日期
disposition.ReadDate = System.IO.File.GetLastAccessTime(path[i]);//获取附件的读取日期
mailMessage.Attachments.Add(data);//添加到附件中
}
}
/// <summary>
/// 异步发送邮件
/// </summary>
/// <param name="CompletedMethod"></param>
public void SendAsync(SendCompletedEventHandler CompletedMethod)
{
if (mailMessage != null)
{
smtpClient = new SmtpClient();
smtpClient.Credentials = new System.Net.NetworkCredential(mailMessage.From.Address, password);//设置发件人身份的票据
smtpClient.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
smtpClient.Host = "smtp." + mailMessage.From.Host;
smtpClient.SendCompleted += new SendCompletedEventHandler(CompletedMethod);//注册异步发送邮件完成时的事件
smtpClient.SendAsync(mailMessage, mailMessage.Body);
}
}
/// <summary>
/// 发送邮件
/// </summary>
public void Send()
{
if (mailMessage != null)
{
smtpClient = new SmtpClient();
smtpClient.Credentials = new System.Net.NetworkCredential(mailMessage.From.Address, password);//设置发件人身份的票据
smtpClient.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
smtpClient.Host = "smtp." + mailMessage.From.Host;
smtpClient.Send(mailMessage);
}
}
}
MVC图片上传详解
MVC图片上传--控制器方法
新建一个控制器命名为File,定义一个Img方法
[HttpPost]
public ActionResult Img(HttpPostedFileBase shangchuan)
{
string path = @"\upload\" + DateTime.Now.ToFileTime() + ".jpg";
Session["path"] = path;
string save = Server.MapPath(path);
shangchuan.SaveAs(save);
return Content(path);
}
MVC视图利用Ajax.BeginForm表单提交,
@表单提交到控制器Add添加方法@
@using (Ajax.BeginForm("Add", "Show", null, new AjaxOptions { OnSuccess = "success" }, new { id = "f1", enctype = "multipart/form-data" }))
{
<label for="name">商品图像</label>
<div>
<input type="file" name="shangchuan" />
<input type="button" value="点击上传" onclick="upload()" />
</div>
<div id="img" style="width:100px;height:100px"></div>
<script>
function upload() {
$(f1).ajaxSubmit(
{
url: "/File/Img",
type: 'post',
success: function (a, b, c) {
$("#img").empty();
$("#img").append("<img src='" + a + "' style='width:100px;height:100px;'/>");
$("#ProductImg").val(a);
}
})
}
</script>
}
控制器中添加方法
[HttpPost]
[ValidateInput(false)]
public ActionResult Add(ProductRecordInfo m)
{
//通过Session接收File控制器中Img方法保存的图片上传地址
m.ProductImg = Session["path"].ToString();
int i = new UserBLL().Add(m);
return Content(i.ToString());
}